Binary Heaps What is a Binary Heap Array
Binary Heaps • What is a Binary Heap? • Array representation of a Binary Heap • Min. Heap implementation • Operations on Binary Heaps: • enqueue • deleting an arbitrary key • changing the priority of a key • Building a binary heap • top down approach • bottom up approach • Heap Applications: • Heap Sort • Heap as a priority queue
What is a Binary Heap? • • • A binary heap is a complete binary tree with one (or both) of the following heap order properties: • Min. Heap property: Each node must have a key that is less or equal to the key of each of its children. • Max. Heap property: Each node must have a key that is greater or equal to the key of each of its children. A binary heap satisfying the Min. Heap property is called a Min. Heap. A binary heap satisfying the Max. Heap property is called a Max. Heap. A binary heap with all keys equal is both a Min. Heap and a Max. Heap. Recall: A complete binary tree may have missing nodes only on the right side of the lowest level. All levels except the bottom one must be fully populated with nodes All missing nodes, if any, must be on the right side of the lowest level
Min. Heap and non-Min. Heap examples 13 13 21 24 65 26 21 16 31 19 6 68 65 32 16 31 26 13 21 65 26 19 32 16 21 16 31 68 32 13 24 19 68 24 65 26 31 32 19
Min. Heap and non-Min. Heap examples Violates Min. Heap property 21>6 13 21 24 65 26 19 26 6 65 31 26 32 19 19 Not a Heap 21 68 32 Violates heap structural property 24 65 26 68 Not a Heap 13 16 31 16 Not a Heap 21 65 68 A Min. Heap 32 13 24 21 16 31 13 16 31 19 32 Violates heap structural property
Max. Heap and non-Max. Heap examples 68 68 65 24 15 20 65 46 32 23 67 25 15 31 46 32 20 30 50 15 20 40 31 19 25 25 31 70 24 23 16 21 38 19 2 18 5 15 10
Max. Heap and non-Max. Heap examples Violates Max. Heap property 65 < 67 68 65 24 15 20 23 Not a Heap 50 15 20 25 A Max. Heap 31 70 24 65 46 32 19 46 67 15 32 20 31 23 Not a Heap 21 38 25 Violates heap structural property 19 2 16 18 5 25 30 Not a Heap 40 31 68 10 15 Violates heap structural property
Array Representation of a Binary Heap • A heap is a dynamic data structure that is represented and manipulated more efficiently using an array. • Since a heap is a complete binary tree, its node values can be stored in an array, without any gaps, in a breadth-first order, where: Value(node i+1) array[ i ], for i > 0 13 21 24 65 • • 26 16 31 32 19 68 13 21 16 24 31 19 68 65 26 32 0 1 2 3 4 The root is array[0] The parent of array[i] is array[(i – 1)/2], where i > 0 The left child, if any, of array[i] is array[2 i+1]. The right child, if any, of array[i] is array[2 i+2]. 5 6 7 8 9
Array Representation of a Binary Heap (contd. ) • We shall use an implementation in which the heap elements are stored in an array starting at index 1. Value(node i ) array[i] , for i > 1 13 21 24 65 26 • • 16 31 32 19 68 13 21 16 24 31 19 68 65 26 32 0 1 2 3 4 The root is array[1]. The parent of array[i] is array[i/2], where i > 1 The left child, if any, of array[i] is array[2 i]. The right child, if any, of array[i] is array[2 i+1]. 5 6 7 8 9 10
Min. Heap Implementation • A binary heap can serve as a priority queue • Our Min. Heap class will implement the following Priority. Queue interface public interface Priority. Queue extends Container{ public abstract void enqueue(Comparable comparable); public abstract Comparable find. Min(); public abstract Comparable dequeue. Min(); }
Min. Heap Implementation (contd. ) public class Binary. Heap extends Abstract. Container implements Priority. Queue { protected Comparable array[]; public Binary. Heap(int i){ array = new Comparable[i + 1]; } public Binary. Heap(Comparable[] comparable) { this(comparable. length); for(int i = 0; i < comparable. length; i++) array[i + 1] = comparable[i]; count = comparable. length; build. Heap. Bottom. Up(); }
Sift Up • In a Min. Heap, if the key at a node, other than the root, becomes less than its parent, the heap property can be restored by swapping the current node and its parent, repeating this process for the parent if necessary, until – the key at the node is greater than or equal to that of the parent. – we reach the root. Procedure Sift. Up Input: H[1. . n], i where 1 i n. Output: H, where no node is less than its parent on the path from node i to the root. done = false; while (!done && (i != 1)) { if H[i]. key < H[i/2]. key swap(H[i], H[i/2]); else What is the complexity of done = true; Sift Up? i : = i/2; }
Sift Down • In a Min. Heap, if the value at a node becomes greater than the key of any of its children, the heap property can be restored by swapping the current node and the child with minimum key value, repeating this process if necessary until – the key at the node is less than or equal to the keys of both children. – we reach a leaf. Procedure Sift. Down Input: H[1. . n], i where 1 i n. Output: H[i] is percolated down, if needed, so that it’s not greater than its children. done = false; while ( (2*i <= n) && !done) { i = 2*i; if ((i+1 n) and (H[i+1]. key < H[i]. key)) i = i+1; if (H[i/2]. key > H[i]. key) swap(H[i], H[i/2]); What is the complexity of else Sift Down? done : = true; }
Min. Heap enqueue • The pseudo code algorithm for enqueing a key in a Min. Heap is: Algorithm enqueue Input: A heap H[1. . n] & a heap element x. Output: A new heap H[1. . n+1] with x being one of its elements. 1. if (Heap is full) throw an exception; 2. n = n + 1; 3. H[n] = x; 4. Sift. Up(H, n); • Thus, the steps for enqueue are: 1. Enqueue the key at the end of the heap. 2. As long as the heap order property is violated, percolate up. What is the complexity of enqueue method?
Min. Heap Insertion Example 13 13 21 24 65 26 Insert 18 16 31 19 21 68 24 65 32 26 16 31 32 19 68 18 Percolate up 13 13 18 24 65 26 16 21 32 19 31 21 Percolate up 68 24 65 26 16 18 32 19 31 68
Min. Heap enqueue implementation • To have better efficiency, we avoid repeated swapping • We find a place (hole) for the new key, move the hole upward when needed, and at the end, put the key into the hole public void enqueue(Comparable comparable){ if(is. Full()) throw new Container. Full. Exception(); int hole = ++count; // percolate up via a hole while(hole > 1 && array[hole / 2]. compare. To(comparable)>0){ array[hole] = array[hole / 2]; hole = hole / 2 ; } array[hole] = comparable; } public boolean is. Full(){ return count == array. length - 1; }
Deleting an Arbitrary Key Algorithm Delete Input: A nonempty heap H[1. . n] and i where 1 i n. Output: H[1. . n-1] after H[i] is removed. 1. 2. 3. 4. 5. 6. 7. 8. • if (Heap is empty) throw an exception x = H[i]; y = H[n]; n : = n – 1; if i == n+1 then return; // Heap consists of 1 node H[i] = y; if y. key <= x. key then Sift. Up(H, i); else Sift. Down(H, i); What about dequeue. Min()? What is the complexity of Delete method?
Example 13 21 24 65 • Delete 68 • Delete 13 26 60 31 32 62 68
Min. Heap dequeue Implementation public Comparable dequeue. Min(){ if(is. Empty()) throw new Container. Empty. Exception(); Comparable min. Item = array[1]; array[1] = array[count]; count--; percolate. Down(1); return min. Item; } private void percolate. Down(int hole){ int min. Child. Index; Comparable temp = array[hole]; while(hole * 2 <= count){ min. Child. Index = hole * 2; if(min. Child. Index + 1 <= count && array[min. Child. Index + 1]. compare. To(array[min. Child. Index])<0) min. Child. Index++; if(array[min. Child. Index]. compare. To(temp)<0){ array[hole] = array[min. Child. Index]; hole = min. Child. Index; } else break; } array[hole] = temp; }
Changing the priority of a key There are three possibilities when the priority of a key x is changed: 1. The heap property is not violated. 2. The heap property is violated and x has to be percolated up to restore the heap property. 3. The heap property is violated and x has to be percolated down to restore the heap property. Example:
Building a heap (top down) • • A heap is built top-down by inserting one key at a time in an initially empty heap. After each key insertion, if the heap property is violated, it is restored by percolating the inserted key upward. The algorithm is: for(int i=1; i <= heap. Size; i++){ What is the complexity of read key; Build. Heap top-down? binary. Heap. enqueue(key); } Example: Insert the keys 4, 6, 10, 20, and 8 in this order in an originally empty max-heap
Converting an array into a Binary heap (Building a heap bottom-up) • The algorithm to convert an array into a binary heap is: 1. Start at the level containing the last non-leaf node (i. e. , array[n/2], where n is the array size). 2. Make the subtree rooted at the last non-leaf node into a heap by invoking percolate. Down. 3. Move in the current level from right to left, making each subtree, rooted at each encountered node, into a heap by invoking percolate. Down. 4. If the levels are not finished, move to a lower level then go to step 3. • The above algorithm can be refined to the following method of the Binary. Heap class: private void build. Heap. Bottom. Up() { for(int i = count / 2; i >= 1; i--) percolate. Down(i); } • Build. Heap. Bottom. Up runs in O(n) time.
Converting an array into a Min. Heap (Example) 70 29 68 65 32 19 16 13 26 31 70 29 65 68 32 13 26 31 19 16
Heap Application: Heap Sort • A Min. Heap or a Max. Heap can be used to implement an efficient sorting algorithm called Heap Sort. • The following algorithm uses a Min. Heap: public static Binary. Heap for(int i = array[i] } void heap. Sort(Comparable[] array){ heap = new Binary. Heap(array) ; 0; i < array. length; i++) = heap. dequeue. Min() ; • Because the dequeue. Min algorithm is O(log n), heap. Sort is an O(n log n) algorithm. • Apart from needing the extra storage for the heap, heap. Sort is among efficient sorting algorithms.
Heap Applications: Priority Queue • A heap can be used as the underlying implementation of a priority queue. • A priority queue is a data structure in which the items to be inserted have associated priorities. • Items are withdrawn from a priority queue in order of their priorities, starting with the highest priority item first. • Priority queues are often used in resource management, simulations, and in the implementation of some algorithms (e. g. , some graph algorithms, some backtracking algorithms). • Several data structures can be used to implement priority queues. Below is a comparison of some: Data structure Enqueue Find Max Dequeue Max Unsorted List O(1) O(n) Sorted List O(n) O(1) AVL Tree O(log n) Max. Heap O(log n) O(1) O(log n)
- Slides: 24