Podcast Ch22c Title: Deleting from a Heap Description: Conceptual overview; adjustHeap method; popHeap method; program 22.1 Participants: Barry Kurtz (instructor); John Helfert and Tobie Williams (students) Textbook: Data Structures for Java; William H. Ford and William R. Topp
Deleting from a Heap Deletion from a heap is normally restricted to the root only. Hence, the operation removes the maximum (or minimum) element. To erase the root of an n‑element heap, exchange the element at index n‑1 and the root and filter the root down into its correct position in the tree.
Deleting from a Heap (continued) // filter the array element arr[first] down the // heap with index range [first, last) private static <T> void adjustHeap(T[] arr, int first, int last, Comparator<? super T> comp)
Deleting from a Heap (cont)
Start with the minumum heap shown below Start with the minumum heap shown below. Draw the heap after deleting the root 15.
adjustHeap() The implementation of adjustHeap() uses the integer variables currPos and childPos to scan the path of children. Let currPos = first and target = arr[first]. The iterative scan proceeds until we reach a leaf node or target is ≥ to the values of the children at the current position. Move currPos and childPos down the path of children in tandem. Set childPos = index of the largest (smallest) of arr[2*currPos + 1] and arr[2*currPos + 2].
adjustHeap() (continued) // filter the array element arr[first] down // the heap with index range (first, last) public static <T> void adjustHeap(T[] arr, int first, int last, Comparator<? super T> comp) { int currentPos, childPos; T target; // start at first and filter target down the heap currentPos = first; target = arr[first]; // compute the left child index and begin // a scan down path of children, stopping // at end of list (last) or when we find a // place for target childPos = 2 * currentPos + 1;
adjustHeap() (continued) while (childPos < last) { // index of right child is childPos+1; // compare the two children; change // childPos if comp.compare(arr[childPos+1], // arr[childPos]) < 0 if ((childPos+1 < last) && comp.compare(arr[childPos+1], arr[childPos]) < 0) childPos = childPos + 1; // compare selected child to target if (comp.compare(arr[childPos],target) < 0) { // comp.compare(selected child, target) < 0; // move selected child to the parent; // position of selected child is now vacated arr[currentPos] = arr[childPos];
adjustHeap() (concluded) // update indices to continue the scan currentPos = childPos; childPos = 2 * currentPos + 1; } else // target belongs at currentPos break; arr[currentPos] = target;
Implementing popHeap() // delete the maximum (minimum) element in the heap // and return its value public static <T> T popHeap(T[] arr, int last, Comparator<? super T> comp) The implementation first captures the root and then exchanges it with the last value in the heap (arr[last-1]). A call to adjustHeap() reestablishes heap order in a heap which now has index range [0, last-1). Method popHeap() concludes by returning the original root value.
Implementing popHeap() (concluded) // the array elements in the range (0, last) // are a heap; swap the first and last elements // of the heap and then make the elements in the // index range (0, last-1) a heap; use the // Comparator comp to perform comparisons public static <T> T popHeap(T[] arr, int last, Comparator<? super T> comp) { // element that is popped from the heap T temp = arr[0]; // exchange last element in the heap with // the deleted (root) element arr[0] = arr[last-1]; arr[last-1] = temp; // filter down the root over the range (0,last-1) adjustHeap(arr, 0, last-1, comp); return temp; }
Program 22.1 import ds.util.Heaps; import ds.util.Greater; import ds.util.Less; public class Program22_1 { public static void main(String[] args){ // integer array used to create heaps // arrA and arrB Integer[] intArr = {15, 29, 52, 17, 21, 39, 8}, heapArrA = new Integer[intArr.length], heapArrB = new Integer[intArr.length]; int i; // comparators to specify maximum or minimum heap Greater<Integer> greater = new Greater<Integer>(); Less<Integer> less = new Less<Integer>();
Program 22.1 (cont) // load elements from intArr into // heapArrA to form a maximum heap and into // heapArrB to form a minimum heap for (i = 0; i < intArr.length; i++) { Heaps.pushHeap(heapArrA, i, intArr[i], greater); Heaps.pushHeap(heapArrB, i, intArr[i], less); } // display the heapArrA System.out.println("Display maximum heap:"); System.out.println(Heaps.displayHeap(heapArrA, heapArrA.length, 2)); // graphically display heapArrB before and // after popHeap() Heaps.drawHeaps(heapArrB, heapArrB.length, 2);
Program 22.1 (concluded) Integer minObj = Heaps.popHeap(heapArrB, heapArrB.length, less); System.out.println("\nMinimum value is " + minObj); // the index range is 0 to heapArrB.length-1 Heaps.drawHeap(heapArrB, heapArrB.length-1, 2); }
Run of Program 22.1 Run: Display maximum heap: 52 21 39 15 17 29 8 21 39 15 17 29 8 Minimum value is 8
Start with the following maximum heap and list the elements after each operation. Execute the operations sequentially, using the result of the previous operation. The initial array is {30, 25, 20, 10, 5}. First, insert (push) 40: The array is Answer [ 40, 25, 30, 10, 5, 20 ] (b) Then, delete (pop) an element from the heap: The array is Answer [ 30, 25, 20, 10, 5 ]
Complexity of Heap Operations A heap stores elements in an array-based tree that is a complete tree. The pushHeap() and adjustHeap() operations reorder elements in the tree by move up the path of parents for push() and down the path of largest (smallest) children for pop(). Assuming the heap has n elements, the maximum length for a path between a leaf node and the root is log2n, so the runtime efficiency of the algorithms is O(log2 n)