Here is the same barebones Heap
class we’ve seen already, with method specs and headers but no implementation.
public class Heap {
int[] A;
int size;
/** Add the value v to the heap. */
public void add(int v);
/** Return the smallest value in the heap without modifying the heap.
* Precondition: size >= 1 */
public int peek();
/** Remove and return the minimum value in the heap.
* Precondition: size >= 1 */
public int poll();
}
The kind of heap we’ve been talking about are formally called “min-heaps”, because the minimum value is always at the root. It is also possible to create a “max-heap”, where the maximum value is at the root. How do we need to change the definition (properties) of a heap to switch it from a min-heap to a max-heap?
There is a sorting algorithm called HeapSort. How do you think this might work? Write some pseudocode for a method heapSort(int[] a)
that uses a Heap
like the one above to sort an array of integers. What is the runtime of your algorithm? Is it in-place? Stable?
It turns out to be possible to write an in-place version of HeapSort
using a max-heap. To get you started, here’s a max-heap version of the Heap
class above with a couple extra methods added. The first is a constructor that takes an array of unsorted values and sets that to be the Heap’s internal storage array:
public class Heap {
int[] A;
int size;
/** Constructor: initialize a heap with an unsorted array of values
* as the backing storage. Although A has values, size is 0 so the
* heap starts out empty. */
public Heap(int[] unsorted_array) {
A = unsorted_array;
size = 0;
}
/** Add the value v to the heap. */
public void add(int v);
/** Return the largest value in the heap without modifying the heap.
* Precondition: size >= 1 */
public int peek();
/** Remove and return the largest value in the heap.
* Precondition: size >= 1 */
public int poll();
/** Sort the values in A in-place using heapsort.
* Precondition: the heap is empty and A contains all values to be sorted.
* Postcondition: the heap is empty and A's values are in sorted order. */
public void heapSort() {
// your code here
}
}
The second method is the heapSort()
method, which sorts the values in A
in-place. Implement the heapSort
method.
The most straightforward way to insert elements into a heap is to call add
times, which is . However, it turns out to be possible to build a heap of relements in ) time. There are two tricky parts to this: the algorithm to build the heap, and the analysis to show that it’s . In short, the approach is to build the heap “bottom-up” instead of “top-down”.
Write pseudocode to implement the following method, which could be a member of the Heap
class above:
/** Swap i down to its appropriate position in the bottom-up collection
* of heaps thus far constructed.
* Preconditions:
* - i's left subtree is nonempty
* - i's left subtree and right subtree (if it exists) are max-heaps
* Postcondition: the subtree rooted at i is a max-heap
*/
private void maxHeapify(int i) {
// your code here
}
Noticing that a single value is always a valid heap, write pseudocode for the following, making use of the maxHeapify
method above:
For a given call to maxHeapify(i)
, the runtime is where is the number of nodes in the tree rooted at i
. Although maxHeapify()
makes calls to the private helper, it’s possible to show that it only does a total of work. Prove this. Hint: the analysis is similar to the analysis of the recursive height
calculation in AVL trees that we saw in Lecture 11 Problem 3.