190 likes | 284 Views
Trees IV:. The Heap. Heap. Like a binary search tree, a heap is a binary tree in which the data entries can be compared using total order semantics Defining qualities of a heap: the data entry contained in any node is greater than or equal to the data entry contained in either of its children
E N D
Trees IV: The Heap heaps
Heap • Like a binary search tree, a heap is a binary tree in which the data entries can be compared using total order semantics • Defining qualities of a heap: • the data entry contained in any node is greater than or equal to the data entry contained in either of its children • the tree is always complete heaps
Heap Example 45 32 41 19 7 28 40 10 12 heaps
Heap Applications • Heap can be used to implement a sorting algorithm called heapsort • Heap is also a handy way to implement a priority queue -- we’ll use this application to illustrate how heaps work heaps
Heap Implementation • Because a heap is by definition a complete tree, it is easy to use an array-based implementation • Heap operations reHeapUp and reHeapDown are used to maintain the other defining quality of a heap -- each node’s data entry >= data entries of its children heaps
ReHeapUp operation 45 When a new node is added to the tree, it is always added at the leftmost open position in the bottom row 32 41 19 7 28 40 This maintains completeness of tree, but can violate the other defining characteristic of a heap 10 12 35 heaps
ReHeapUp operation Parent/child data swapping continues until the heap condition is restored ReHeapUp restores the second heap condition: a parent node’s data is always greater than or equal to the data in either of its child nodes 45 35 32 41 19 35 32 7 28 40 The operation is accomplished by swapping the new node’s data entry with that of its parent 10 12 7 35 heaps
ReHeapDown operation In a priority queue, the highest-priority item is always dequeued first -- this item would be the top item of the heap Since this is going to be an array implementation, we’ll perform the usual trick of swapping the last array entry with the first, so we can minimize the amount of copying to be done 45 7 32 35 41 19 35 32 7 28 40 10 12 7 45 35 7 heaps
ReHeapDown operation Now we can effectively remove the item by simply diminishing the “used” portion of our array by 1 (already done here) We are once again faced with the same problem -- the heap is the right shape, but the data values are in the wrong positions 41 45 7 32 35 7 40 41 19 7 35 32 28 7 40 We solve this problem, as before, by swapping data between nodes. In this case, we swap the parent node’s data with the largest data entry of the two children, continuing until the heap is restored. 10 12 heaps
Example: Priority Queue with heap implementation • Priority queue has all operations associated with a queue: enqueue, dequeue and helper functions (e.g. size( ), is_empty( ), etc.) • Heap is a good fit for priority queue because highest-priority item should always be dequeued first, and this item would always be found at the top of a heap heaps
Code for Priority Queue template <class thing> class PQheap { public: PQheap( ); enum {SIZE=30}; void enqueue (const thing& entry); thing dequeue( ); size_t size( )const {return numItems;} ... heaps
Code for Priority Queue private: thing data[SIZE]; size_t numItems; void reHeapUp(size_t n); void reHeapDown(size_t n); size_t parent(size_t n) const {return (n-1)/2;} size_t left_child(size_t n) const {return (2*n)+1;} size_t right_child(size_t n) const {return (2*n)+2;} void Swap (thing& x, thing& y); }; heaps
Code for Priority Queue template <class thing> PQheap<thing>::PQheap() { numItems=0; } heaps
Code for Priority Queue template <class thing> void PQheap<thing>::enqueue (const thing& entry) { assert (size( ) < SIZE); data[numItems] = entry; reHeapUp(numItems); numItems++; } heaps
Code for Priority Queue template<class thing> void PQheap<thing>::reHeapUp(size_t n) { size_t x = n; while (x>0 && data[x] > data[parent(x)]) { Swap(data[x], data[parent(x)]); x=parent(x); } } heaps
Code for Priority Queue template <class thing> void PQheap<thing>::Swap (thing& x, thing& y) { thing temp = x; x = y; y = temp; } heaps
Code for Priority Queue template <class thing> thing PQheap<thing>::dequeue() { thing value=data[0]; // save return value numItems--; data[0]=data[numItems]; // swap top & bottom reHeapDown(numItems); // restore heap return value; } heaps
Code for Priority Queue template <class thing> void PQheap<thing>::reHeapDown(size_t n) { size_t current = 0, big_child, heap_ok = 0; while ((!heap_ok) && (left_child(current) < n)) { if (right_child(current) >= n) big_child = left_child(current); else if (data[left_child(current)] > data[right_child(current)]) big_child = left_child(current); else big_child = right_child(current); ... heaps
Code for Priority Queue if (data[current] < data[big_child]) { Swap(data[current], data[big_child]); current = big_child; } else heap_ok = 1; } // end of while loop } // end of function heaps