Lab 10 -- Top of the Heap
Thursday, March 10, 2011

Objectives

Background

Recall that a heap (specifically, a maxheap) is a complete binary tree such that every node has a value greater than or equal to its children's values. Because heaps are complete trees, we can efficiently represent them using arrays. In this lab, you'll complete some of the code for the heap ADT and then use it to write an efficient priority queue.

Setup

After starting a new project in Eclipse, download the four classes you'll need:

You should first study these classes to understand what's going on. Heap uses an array-based implementation of a complete binary tree where:

Step 1: Making a Tree into a Heap

As was discussed in class, any complete binary tree can be made into a heap by doing the following:
  1. Let node X be the first non-leaf node that is found by traversing the tree in reverse level-by-level order.
  2. Heapify the subtree rooted at node X.
  3. Let X be the next node found in reverse level-by-level order. Repeat Step 2. Continue in this way until you have processed all non-leaf nodes. The root will be the last one processed.

This is exactly what the buildAHeap method does in the Heap class. It invokes the heapify method in order to do Step 2. But heapify isn't written yet. That's your job. Write the method heapify (see the file for prototype and documentation).

PITFALL ALERT: When testing to see which child is the bigger child of node i (that is, which child holds the bigger value), be careful of the case where there is only one child. This will happen at the bottom of the tree if the last internal node has a left child but no right child. For that case, trying to access the right child will probably result in an ArrayIndexOutOfBounds exception. You can be certain that node i has a right child if 2i+1 <= the number of nodes in the tree. I highly recommend that you make helper methods to clarify your heapify method. Your heapify method should not need to do the actual calculations to get the left and right children of the node (or to determine if the node has a right child at all).

PITFALL ALERT 2: The values in your tree are ints, but so are the indexes, so you'll have to be careful to compare the values when that's what you want.

Debug your code until it works. The testHeap() method in the Client class gives one sample binary tree to test. Be sure to conduct your own tests. When you look at the output of your tests, remember that a heap is not a sorted list!

Step 2: A heap-based PQ

The PriorityQueue class is a scaled-down version of a regular PQ. The sole non-default constructor in this class takes an array as a parameter, which is then immediately turned into a heap. There is also a size method and a remove method that returns the highest priority item. For this PQ, "highest priority" means the largest int, so remove simply calls the deleteRoot method in the Heap class. Heap's deleteRoot hasn't been implemented, so that's your next task. Again, see the file for prototype and documentation.

deleteRoot should rely heavily on heapify, so once you are certain that heapify has been tested thoroughly, deleteRoot shouldn't give you too much trouble.

Remember that priority queues give us an easy way of sorting items. Once all of the items are in the PQ, we can simply remove them one at a time, and they should come out in reverse sorted order. This is one way to test that your deleteRoot method is working properly. Once it is written, run the testSorter method in Client (by uncommenting the line that calls it). That code creates a Sorter object and sorts the ints in your heap. Study the priorityQueueSort method in Sorter to understand what's going on. Then create your own tests.

Step 3: Analysis

Finally, how long does this sort take? That is, what is the worst-case running time of the priorityQueueSort method? Answer using Big-O notation in a separate text file and explain your answer. How does your answer compare to the worst-case running time of a similar priorityQueueSort in which the Priority Queue is implemented as an unsorted linked list? Answer using Big-O notation again (and explain it too).

How to turn in this lab

As always, just because it works doesn't mean it's good. There's a lot of good opportunities for modularity in this lab. Think about what tasks you could delegate. Don't forget to comment, use good variable names, and write code that you can easily explain in English.

E-copy in e-mail to me by 4PM Tomorrow.