Homework: Quicksort
This homework is necessary preparation for the lab. Make sure you type your answers in a file you bring to the lab so that you will be able to quickly copy and paste them into the file provided in the lab.
-
Implement the static method
partitiondeclared below that partitions a given queue,q, into two other queues,frontandback. Entries fromqno larger than the given partitioning entry,partitioner, are put infront, and entries fromqlarger thanpartitionerare put inback. Use theint order.compare(T, T)method to compare entries topartitionerand decide in which queue to put them. Pay attention to the parameter modes: clears forqand replaces forfrontandback./** * Partitions {@code q} into two parts: entries no larger than * {@code partitioner} are put in {@code front}, and the rest are put in * {@code back}. * * @param <T> * type of {@code Queue} entries * @param q * the {@code Queue} to be partitioned * @param partitioner * the partitioning value * @param front * upon return, the entries no larger than {@code partitioner} * @param back * upon return, the entries larger than {@code partitioner} * @param order * ordering by which to separate entries * @clears q * @replaces front, back * @requires IS_TOTAL_PREORDER([relation computed by order.compare method]) * @ensures <pre> * perms(#q, front * back) and * for all x: T where (<x> is substring of front) * ([relation computed by order.compare method](x, partitioner)) and * for all x: T where (<x> is substring of back) * (not [relation computed by order.compare method](x, partitioner)) * </pre> */ private static <T> void partition(Queue<T> q, T partitioner, Queue<T> front, Queue<T> back, Comparator<T> order) {...} -
Implement the instance method
sortdeclared below that sorts aQueue<T> (this)using the quicksort algorithm according to the givenorder. Quicksort is a recursive, divide and conquer algorithm. Basically it breaks the queue into two (smaller) queues, sorts the two smaller queues recursively, and finally assembles the sorted queue. Of course, if the original queue is either empty or it contains only one entry, it is already sorted and there is nothing to do. What specifically characterizes the quicksort algorithm is how the original queue is broken into two smaller queues: an entry of the original queue is used to partition the remaining entries between those no larger than the partitioning entry and those larger than the partitioning entry. After recursively sorting the two smaller queues, all that is left is to assemble the queue with the smaller entries, the partitioning entry, and the queue with the larger entries in this order back into the original queue (this). Follow the comments below to complete the quicksort implementation ofsort./** * Sorts {@code this} according to the ordering provided by the * {@code compare} method from {@code order}. * * @param order * ordering by which to sort * @updates this * @requires IS_TOTAL_PREORDER([relation computed by order.compare method]) * @ensures <pre> * perms(this, #this) and * IS_SORTED(this, [relation computed by order.compare method]) * </pre> */ public void sort(Comparator<T> order) { if (this.length() > 1) { /* * Dequeue the partitioning entry from this */ /* * Partition this into two queues as discussed above * (you will need to declare and initialize two new queues) */ /* * Recursively sort the two queues */ /* * Reconstruct this by combining the two sorted queues and the * partitioning entry in the proper order */ } }
For completeness, here are the math definitions used in the contracts above.
/**
* @mathdefinitions <pre>
* IS_TOTAL_PREORDER (
* r: binary relation on T
* ) : boolean is
* for all x, y, z: T
* ((r(x, y) or r(y, x)) and
* (if (r(x, y) and r(y, z)) then r(x, z)))
*
* IS_SORTED (
* s: string of T,
* r: binary relation on T
* ) : boolean is
* for all x, y: T where (<x, y> is substring of s) (r(x, y))
* </pre>
*/