/home/umdweb/cs4521/programming/pa1/Quicksort/src/sorts/Partitioner.java |
package sorts; import arraymodel.ArrayIndex; import arraymodel.ArrayModel; import arraymodel.IndexRange; import display.Operation; import java.awt.Color; /** * A Partitioner is an array model operation that choses a pivot entry from the * array and partitions the array around the pivot. * This operation is used in a quicksort algorithm. * The quicksort algorithm sets the hi and lo indices of a partitioner by * invoking its setBounds() method before invoking its operate() method. * After invoking operate() the quicksort algorithm can determine the split * index for the partition by invoking the getSplitIndex() method. */ public class Partitioner implements Operation<ArrayModel> { int lo; int hi; int splitIndex; /** * p.setBounds(lo, hi) sets the endpoints of the segment that will be * partitioned by the p's operate() method. * @param lo the index of the first entry in the partitioned segment * @param hi the index of the entry just beyond the end of the partitioned * segment */ public void setBounds(int lo, int hi) { this.lo = lo; this.hi = hi; } /** * p.operate(array) partitions array between the current bounds of p. * These bounds are set prior to invoking p.operate() by invoking * p.setBounds(). * @param array the array to be partitioned */ public void operate(ArrayModel array) { // The index range is used to control the coloring of the segments in the // array. The portions of the array outside the range are colored gray. // The portion inside the range is colored orange. However, when an // ArrayIndex is created it will cause a portion of the range to be colored // differently. IndexRange range = array.createIndexRange(lo, hi, Color.orange, Color.gray); // This causes the portion of the array from lo up to but not including the // value of geq to be colored yellow. This ArrayIndex is initialized to lo, // so initially the yellow segment (entries less than the pivot) is empty. // You can send an ArrayIndex an increment() or decrement() message to // change its value. ArrayIndex geq = range.createIndex(lo, Color.yellow); // This causes the portion of the array from geq up to but not including unk // to be colored green. This ArrayIndex is also initialized to lo, so // initially the green segment (entries greater than or equal to the pivot) // is empty. ArrayIndex unk = range.createIndex(lo, Color.green); // This causes the portion of the array from unk up to but not including end // to be colored light gray. This ArrayIndex is initialized to hi - 1, so // initially the gray segment (unknown entries) covers all but the last // entry. ArrayIndex end = range.createIndex(hi - 1, Color.lightGray); // Use this to force display of the changes to the ArrayIndex objects. // These changes are not automatically displayed because it can make the // display confusing depending on the order of your ArrayIndex increments. array.showChanges(); // Now set up for the partition loop. int pivotIndex = (lo + hi) / 2; Character pivotValue = array.get(pivotIndex); // This is how you swap two entries. Note that for an ArrayIndex you get // its current value by sending it a get() message. // The array object will automatically display all swaps. array.swap(pivotIndex, end.get()); while (unk.get() < end.get()) { Character unknownValue = array.get(unk.get()); // FIXME - you fill in the rest of the code for the loop here. // Use unknownValue.compareTo(pivotValue) for comparison. // Use this to force display of the changes to the ArrayIndex objects. // These changes are not automatically displayed because it can make the // display confusing depending on the order of your ArrayIndex increments. array.showChanges(); } array.swap(geq.get(), end.get()); // The following lines are not essential to the algorithm. They just make // the display at the end better. end.increment(); unk.increment(); array.showChanges(); splitIndex = geq.get(); } /** * p.getSplitIndex() returns the split index for the previous invokation of * p.operate(). * The pivot should be located at this index. * All entries before the split index are less than the pivot. * All entries after the split index are greater than or equal to the pivot. * @return the split index */ public int getSplitIndex() { // This is used by the quicksort operation. It should be set at the end of // a partition. return splitIndex; } @Override public String toString() { // This is used for creating a menu item label for the operation. return "Partition(" + lo + ", " + hi + ")"; } }