CS 211 — Homework Six

Keep your priorities straight

Due: 27 March 2013, 11:59p

Worth: 40 points

Implementing the PriorityQueue

For this assignment, you will implementing a PriorityQueue<E>. The interface should be essentially as I described it in class:

PriorityQueue(Comparator<E> comparator, int initialCapacity)
This is the constructor. It should do all of the normal constructory things. As we talked about in class, the Comparator should be used to make all comparisons between items in the queue. Since we are using an array-based heap to store the actual data, we add an initialCapacity parameter to determine the initial size of the array (yes, this implies you will need to resize the array as the demand requires).
PriorityQueue(Comparator<E> comparator)
As we did with ArrayList, we have a second version of the constructor that sets the initial capacity to some "reasonable" value.
void add(E item)
Insert the item into the queue. If the item is null, this should throw a NullPointerException.
void clear()
This completely clears the contents of the queue.
boolean isEmpty()
This is a simple test to indicate if the queue is empty.
E peek()
This returns the highest priority object in the queue. If the queue is empty, this should return null.
E poll()
This removes the highest priority object in the queue and returns it. If the queue is empty, this should return null.
int size()
This method returns the current number of elements stored in the queue.

Implementation details

The implementation of this is pretty straightforward. As implied above, you will be implementing the storage side of this data structure as a heap stored in an array. As such, you will need siftUp() and siftDown() methods to handle insertions and deletions.

Command line interaction

For this assignment, we are going to return to text-based interaction like we did in assignment two. You are going to write a simple application that organizes Strings based on their length. Your tool should understand a couple of basic commands that essentially mirror the underlying methods on the PriorityQueue:

add String
This will add whatever the user typed after add (and one space) to the queue. This should output add: String, where String is the String that was added.
peek
This should return peek: String, where String is the longest String in the queue. If the queue is empty, you should output Queue is empty.
poll
This should return poll: String, where String is the longest String in the queue, and remove it from the queue. If the queue is empty, you should output Queue is empty.
size
This should return size: size, where size is the size of the queue.
clear
This should empty the queue and output Queue cleared.
quit
This should end the program and output Goodbye.

If the user types anything else, this should output Invalid command. Also, to reduce confusion, none of the outputs actually include periods — that is just an artifact of ending sentences with them.

This application should be written in a class called AssignmentSix. As we did for assignment two, all of the above functionality should be in a method with this signature: public static void cliHandler(Scanner in, PrintWriter out), and you should have a short main method that calls this, hooking up System.in and System.out appropriately.

You will need to write a custom Comparator to prioritize longer Strings. The Comparator should also impose a second level of prioritization and order Strings of the same length alphabetically. This Comparator should be included as a private inner class of AssignmentSix.

Bonus round

I've been asked for some additional opportunities for extra credit. Read on if you suspect that midsemester break will drag on interminably and you wish you had more CS to do... Please be sure to indicate when you have done one of these so that I know to test them.

[5 points] Add an import command
This should read in a file and add every word to the queue. This should output imported num words from filename, where num is the number of words read, and filename is (obviously) the name of the file. Rather than having the user enter in a filename directly, use a FileChooser to bring up a dialog box. If you don't know about the FileChooser, you can learn more about it here: http://docs.oracle.com/javase/tutorial/uiswing/components/filechooser.html. The only "trick" is that you need to pass null to the show methods since there is not a parent window. If the user cancels the operation, you should output "Operation canceled".
[5 points] Add an export command
This is the compliment to the import. This should output all of the words from the queue to a file, in order, one word per line. When it is done, this should output exported num words to filename. This should not clear the queue (you may need to make a copy). Again, use the FileChooser (being careful to use the right version for saving), and output "Operation canceled", if the user cancels.
[5 points] Implement natural ordering for the PriorityQueue
Add another constructor that does not take a comparator. When this constructor is used, use natural ordering to order the elements. Of course, this means that you will have a problem if the objects you are trying to store are not Comparable. Unfortunately, this is very difficult to figure out in the constructor because of the way Java handles generics. As such, you should also modify the add() method (where we actually have an instance of the type of data we are trying to store) to throw a ClassCastException if the type of data stored in the queue is not Comparable.
[5 points] Implement a "copy constructor" for PriorityQueue
Copying the contents from one PriorityQueue to another is not a particularly straightforward task. Since we can't get at anything but the first value, we have to remove all of the items from the original queue just to read them all. So, a seemingly straightforward approach of polling the first queue and adding them to the second will result in the queue being moved, rather than copied. Instead, we would have to make two copies and then throw away the original queue when we are done. This is also something of an expensive operation. Clearly, it would be better if we could just copy the internal array. A fairly common design pattern in Java is the "copy constructor". Take a look at how it works and provide an implementation.
[10 points] Implement heap sort
This bonus question is a little bit different. Instead of modifying any parts of assignment six, I want you to go back to assignment four and modify Sorter. I would like you to add a new method: public static <T extends Comparable<? super T>> void heapSort(List<T> list). This should implement the heap sort algorithm we discussed in class (heapify the list, then deconstruct it into a sorted list).

Grading

PointsItemComments
Correctness
20 ptsPriorityQueue
10 ptsmain
Misc
10 ptsCommentsAll methods and classes should have Javadoc style comments and non-trivial code should have explanations.

Book keeping

I would like you to continue to book keep your time. So please log the amount of time that you spend on:

Try to be as accurate as possible (it would be great if you didn't just get to the end and go "oh right, I need to keep track of my time & well it seemed like five hours..."). I am using this to (a) figure out if you (as a class, and also on a personal level) need more direction on how to direct your energies, and (b) inform the shape of future assignments. The more accurate this information is, the better I can do those two things, so please do not exaggerate in an attempt to get me to trim the assignments down or underestimate because you feel like your classmates didn't need as much time as you. Please include these in a comment at the top of the AssignmentSix class.


Last modified: Sat Mar 16 15:14:12 EDT 2013