/** * Sorts by first splitting the array into two subarrays: one is less or equal to the * first element of the original array, the other is greater or equal to the same * first element. Then recursively sorts the subarrays to make the original array sorted. * This algorithm is due to Tony Hoare. In Merritt's sorting taxonomy, this algorithm * belongs to the family of sorting where the splitting is hard and the joining is easy. * @author Dung X. Nguyen - Copyright 1999 - All rights reserved. * @since 11/28/99 */ public class CQuickSorter extends ACompareSorter { public static final CQuickSorter Singleton = new CQuickSorter(); private CQuickSorter() { } /** * Splits A[lo:hi] in such a way that A[lo:s-1] <= A[s:hi] for some s. * @param A * @param lo < hi. * @param hi > lo. * @return s such that A[lo:s-1] <= A[s:hi] */ protected int split(IOrdered[] A, int lo, int hi) { IOrdered key = A[lo]; int lx = lo; // left index. int rx = hi; // right index. // Invariant 1: key <= A[rx+1:hi]. // Invariant 2: A[lo:lx-1] <= key. // Invariant 3: there exists ix in [lo:rx] such that A[ix] <= key. // Invariant 4: there exists jx in [lx:hi] such that key <= A[jx]. while (lx <= rx) { while (key.compare (A[rx]) == IOrdered.LESS) { // will terminate due to invariant 3. rx--; // Invariant 1 is maintained. } // A[rx] <= key <= A[rx+1:hi]; also invariant 0, lx <= rx. while (A[lx].compare (key) == IOrdered.LESS) { // will terminate due to invariant 4. lx++; // Invariant 2 is maintained. } // A[lo:lx-1] <= key <= A[lx] if (lx <= rx) { // swap A[lx] with A[rx]: IOrdered temp = A[lx]; A[lx] = A[rx]; // invariant 3 is maintained. A[rx] = temp; // invariant 4 is maintained. rx--; // invariant 1 is maintained. lx++; // invariant 2 is maintained. } } // rx < lx, A[lo:lx-1] <= key <= A[rx+1:hi], and key = A[lx]. return lx; } /** * @param A A[lo:s-1] and A[s:hi] are sorted, and A[lo:s-1] <= A[s:hi]. * @param lo * @param s in [lo:hi]. * @param hi */ protected void join(IOrdered[] A, int lo, int s, int hi) { } }