Trees and Priority Queues (Heaps) This will be our first introduction to Trees. Over the next few weeks, we will discuss several different kinds of trees. We'll start with a heap, also known as a priority queue. What distinguishes a priority queue from a regular queue is that items are assigned and ordered by priority. This could be implemented easily enough using either an array or a linked list, and simply insert each new item in the appropriate spot. The next available item would be at the top of the queue. Instead, we are going to implement this with a variant of a binary tree. A heap as a binary tree has the following characteristics: 1. It is complete, meaning that each row (except perhaps the last) is filled 2. Each node satisfies the heap condition, which states that a node's key is greater than or equal to both of its children 3. It is weakly ordered, meaning that there is no easy way to search the tree for a specific value Inserting into a heap uses a process known as trickle-up. The process works as follows: 1. Insert the new node in the first available position in the heap, which is always in the last row. 2. Compare the new node with its parent. If the new node is larger, then swap the new node with its current parent (trickle up) 3. Repeat step #2 until the new node is smaller than or equal to its parent Removing from a heap uses a process know as trickle-down. The process works as follows: 1. Swap the last node with the first node. 2. Remove the last node (which now contains the value of from the first node) 3. Compare the node with each of its children. Swap it with whichever child is larger. 4. Repeat step #3 until both of its children are smaller. Heaps are often implemented as an array. In order to do this successfully, there are a few variables to calculate and track. Note that all calculation should use integer division, which is the forward slash. current size- this will also assist in finding the position in which to insert new nodes parent- for a node at position x in the array, its parent is located at position (x-1)/2 left child- for a node at position x in the array, its left child is located at 2*x+1, or the right child minus 1 right child- for a node at position x in the array, its right child is located at 2*x+2, or the left child plus 1 Inserting into a heap array takes the following steps: bool insertNode(int i) { if ( current size != array size ) { store i in the next available position in the array trickle up i increment the array size return true; } return false; } void trickleUp(int index) { calculate parent position store the value at index in a temp variable while (index > 0 && value of parent < temp variable ) { swap the value at index with the value at parent set index equal to parent calculate new parent position } store the value in the temp variable at the current index position } Removing from a heap array takes the following steps: int deleteNode() { if ( current size != 0 ) { store the value at the top of the heap in a temp variable decrement the current size place the value at current size into the first position trickle down the value in the first position return the temp variable } return NULL; } void trickleDown(int index) { store the value in the first position in a temp variable while ( index < half the current size ) { calculate the position of the left child calculate the position of the right child if ( right child < current size && value stored in left child is less than value stored in right child ) larger child is the right child else larger child is the left child if ( value in the temp variable >= value at the larger child position ) exit the while loop, we're finished store the value at the larger child position into the index position set the index to the larger child } }