/* file BinaryHeap.h */ // code by bds, 4/10 #ifndef __BINARY_HEAP_H #define __BINARY_HEAP_H #include using namespace std; template< typename Key > class Heap { /* These public Priority Queue member functions are defined at the bottom: * (constructor) Heap ( vector& ) * Node extractMin(); // return node v with least key(v). * void insert( Node v ); // application will have set key(v). * void decreaseKey( Node v); // app will have decreased key(v). * bool isEmpty(); // true when heap is empty. */ // reverse this comparison to make a max-heap. bool isLess(const Key& a, const Key& b){ return a < b; } typedef int Node; // an index valid in the keys and locations vectors. typedef int Location; // an index valid for theHeap itself int n; // the current size of the heap; vector theHeap; // indexed by Location vector& priorities; // indexed by Node vector locations; // indexed by Node. gives location in theHeap. // These functions simply allow use of parentheses instead of square brackets. Key& key(Node v) { return priorities[v]; } Location& location (Node v) { return locations[v]; } Node& heap(Location v) { return theHeap[v]; } // invariants: For all nodes v, heap(location(v)) == v. // for all locations k, location(heap(k)) == k. /* Heap invariants: * 1. the node with minimal key is at heap(0). * 2. The heap property is maintained: * for all locations k in 0..n-1, * not isLess ( key(heap(k)), key(heap(parent(k))) ). */ // These functions give adjacent nodes in the heap // from the complete tree perspective. Node parent(Node v) { return heap( (location(v) - 1)/2 ); } Node leftChild(Node v) { return heap( 2*location(v) + 1 ); } Node rightChild(Node v) { return heap( 2*location(v) + 2 ); } void bubbleup( Node v ) { // aka "upheap" /* Input: A node v in the heap, the only node at which the heap * property may be violated. * Result: Some node locations may change. Heap property is restored. * Cost: O(log(n)), where n is the heap's current size. */ while (location(v) != 0 and isLess( key(v), key(parent(v))) ) { Node p = parent(v); swap( heap(location(v)), heap(location(p)) ); swap( location(v), location(p) ); } } void siftdown( Node v ) { // aka "downheap" /* Input: A node v in the heap. the children of v are the only nodes * at which the heap property may be violated. * Result: Some node locations may change. Heap property is restored. * Cost: O(log(n)), where n is the heap's current size. */ while ( location(leftChild(v)) < n ) { Node c = leftChild(v); if ( location(rightChild(v)) < n and isLess( key(rightChild(v)), key(c)) ) c = rightChild(v); // now c is the child with minimal key. if ( isLess(key(c), key(v)) ) { swap(heap(location(v)), heap(location(c))); swap(location(v), location(c)); } else break; } } public: // Heap constructor Heap ( vector& vec ) : n(0), theHeap(vec.size()), priorities(vec), locations(vec.size()) {} Node extractMin() { /* Condition: heap must be non-empty. * Result: heap size is decreased by 1. Locations of some * nodes within the heap are changed. * Output: the removed node having minimal key. * Cost: O(log(n)), where n is the heap's current size. */ Node minNode = heap(0); // swap first (min) and last nodes in heap. swap( heap(0), heap(n-1) ); swap( location(heap(0)), location(heap(n-1)) ); --n; // effectively removes back node from heap. siftdown( heap(0) ); // restore heap property return minNode; } void insert( Node v ) { // Input: A node to be inserted in the heap. // Application has already set key(v). // Result: node v is inserted. Heap size grows by one. // Locations of v and some other nodes may be changed to maintain heap property. // Cost: O(log(n)), where n is the heap's current size. location( v ) = n; heap( n++ ) = v; bubbleup( v ); } void decreaseKey( Node v ) { // Input: Node v in the heap. Application has decreased key(v). // Result: Locations of v and some other nodes may be changed // to re-establish the heap property. // Cost: O(log(n)), where n is the heap's current size. bubbleup( v ); } bool isEmpty() { // Output: true if and only if there are no nodes in the heap currently. // Cost: O(1). return n == 0; } }; #endif // __BINARY_HEAP_H