The Heap Data Structure Mugurel Ionuț Andreica Spring 2012
Properties of the Heap Data Structure A heap has the structure of a balanced binary tree Every node of the heap has an associated numeric value The value of a node is smaller than or equal to the values associated to each of its descendants consequence: the root stores the minimum value in the heap
Operations insertElement(x) extractMin() peek() Inserts the element x into the heap Number of steps proportional to log(N) extractMin() Returns and removes the minimum element from the heap Returns an error if the heap is empty peek() Returns (but does not remove) the minimum element from the heap Only 1 step N=the (current) number of elements in the heap
How the operations work insertElement(x) Add a leaf node l on the last level, which will store the value x pushUp(l) Set node=l While (node≠root) and (node.parent.value<node.value) do Swap node.parent.value and node.value Set node=node.parent
How the operations work (cont.) extractMin() Set x=root.value Choose the rightmost leaf l on the last level Set root.value=l.value Remove l from the heap pushDown(root) Set node=root While (1) do If (node.left_son.value<=node.value) and (node.left_son.value<=node.right_son.value) then Swap node.left_son.value and node.value Set node=node.left_son Else if (node.right_son.value<=node.value) and (node.right_son.value<=node.left_son.value) then Swap node.right_son.value and node.value Set node=node.right_son Else break the while loop Return x Observations: If node.left_son does not exist then we consider node.left_son.value=+∞ If node.right_son does not exist then we consider node.right_son.value=+∞ peek() Return root.value
Implementation Details A heap can be implemented as a binary tree (every node has a value, a parent, a left son and a right son) The most common method is to use an array The elements of the heap are stored on the positions 1,...,N of the array Each position of the array => a node in the tree (position i => node i) Position 1 => the root of the tree The parent of the node i is node i/2 The left son of the node i is node 2*i (if 2*i<=n) The right son of the node i is node 2*i+1 (if 2*i+1<=n)
Array-based Heap Implementation (heap.h) #include <stdio.h> template<typename T> class Heap { public: T *H; int currentDim, maxDim; Heap(int maxDim) { this->maxDim = maxDim; H = new T[this->maxDim + 1]; currentDim = 0; } void insertElement(T x) { if (currentDim == maxDim) { fprintf(stderr, "Error!\n"); return; currentDim++; H[currentDim] = x; pushUp(currentDim); T peek() { if (currentDim == 0) { fprintf(stderr, "Error!\n"); T x; return x; } return H[1]; T extractMin() { T minValue = H[1]; H[1] = H[currentDim]; currentDim--;
Array-based Heap Implementation (cont.) void pushDown() { int l = 1; T vaux; while (1) { if (2 * l + 1 > currentDim) { if (2 * l > currentDim) break; else if (H[2 * l] < H[l]) { vaux = H[2 * l]; H[2 * l] = H[l]; H[l] = vaux; l = 2 * l; } else else { if (H[2 * l] <= H[2 * l + 1] && H[2 * l] < H[l]) { if (currentDim > 0) pushDown(); return minValue; } void pushUp(int l) { int parent; T vaux; parent = l / 2; while (l > 1 && H[parent] > H[l]) { vaux = H[parent]; H[parent] = H[l]; H[l] = vaux; l = parent;
Array-based Heap Implementation (cont.) heap.insertElement(17); heap.insertElement(6); heap.insertElement(9); heap.insertElement(7); heap.insertElement(13); printf("%d\n", heap.peek()); printf("%d\n", heap.extractMin()); } int main() { testHeap(); return 0; H[l] = vaux; l = 2 * l; } else if (H[2 * l + 1] <= H[2 * l] && H[2 * l + 1] < H[l]) { vaux = H[2 * l + 1]; H[2 * l + 1] = H[l]; l = 2 * l + 1; break; }; void testHeap() { Heap<int> heap(1000); heap.insertElement(10); heap.insertElement(100); heap.insertElement(21); heap.insertElement(4);