import java.util.Comparator;
import java.util.ArrayList;
/** This implementation is designed to be very easy to read. However, it is very space inefficient
because it allocates many working arrays. See Quick2 for a more efficient implementation.
Morgan McGuire
morgan@cs.williams.edu */
public class Quick1 implements Sort {
/** Sorts array c in place. */
public void quickSort(ArrayList c, Comparator comparator) {
// Arrays of length 1 are sorted already
if (c.size() > 1) {
// Separate into two sub-arrays
ArrayList less = new ArrayList();
ArrayList equal = new ArrayList();
ArrayList greater = new ArrayList();
// Choose the first value as the pivot
Value pivot = c.get(0);
partition(c, pivot, less, equal, greater, comparator);
quickSort(less, comparator);
quickSort(greater, comparator);
join(c, less, equal, greater);
}
}
/** Splits the elements of source across arrays less, equal, and greater
depending on whether each element is <, ==, or > the pivot according
to the comparator. */
private void partition(ArrayList source, Value pivot,
ArrayList less, ArrayList equal,
ArrayList greater, Comparator comparator) {
int n = source.size();
for (int i = 0; i < n; ++i) {
Value temp = source.get(i);
int comp = comparator.compare(temp, pivot);
if (comp < 0) { // temp < pivot
less.add(temp);
} else if (comp == 0) { // temp == pivot
equal.add(temp);
} else { // temp > pivot
greater.add(temp);
}
}
}
/** Concatenates the elements of less, equal, and greater into dest in that order. */
private void join(ArrayList dest, ArrayList less,
ArrayList equal, ArrayList greater) {
dest.clear();
dest.addAll(less);
dest.addAll(equal);
dest.addAll(greater);
}
/** Wrapper for quickSort1 so that we can call it on Java arrays. */
public void sort(Value[] c, Comparator comparator) {
// Convert the Java array to an ArrayList
ArrayList array = new ArrayList(java.util.Arrays.asList(c));
// Sort the ArrayList
quickSort(array, comparator);
// Copy the elements back
array.toArray(c);
}
}