/*
* This code is from the book:
*
* Winder, R and Roberts, G (2000) Developing Java
* Software, second edition, John Wiley & Sons.
*
* It is copyright (c) 2000 Russel Winder and Graham Roberts.
*/
package ADS ;
/**
* Sort an array of Objects using Quicksort. This is an
* O(n.log(n)) sort except when the data is almost sorted in which
* case it O(n^2).
*
* @version 1.1 1999.11.27
* @author Russel Winder
*/
public class Quicksort {
/**
* The sort operation.
*
* @param a the array to be sorted.
* @param c the Comparator used to compare the
* Objects during the sort process.
*/
public static void sort(final Object[] a, final Comparator c) {
quicksort(a, 0, a.length-1, c) ;
}
/**
* Given the array and two indices, swap the two items in the
* array.
*/
private static void swap(final Object[] a,
final int x,
final int y) {
Object temp = a[x] ;
a[x] = a[y] ;
a[y] = temp ;
}
/**
* Partition an array in two using the pivot value that is at the
* centre of the array being partitioned.
*
*
This partition implementation based on that in Winder, R
* (1993) "Developing C++ Software", Wiley, p.395. NB. This
* implementation (unlike most others) does not guarantee that
* the split point contains the pivot value. Unlike other
* implementations, it requires only < (or >) relation and not
* both < and <= (or > and >=). Also, it seems easier to program
* and to comprehend.
*
* @param a the array out of which to take a slice.
* @param lower the lower bound of this slice.
* @param upper the upper bound of this slice.
* @param c the Comparator to be used to define the
* order.
*/
private static int partition(final Object[] a,
int lower,
int upper,
final Comparator c) {
Object pivotValue = a[(upper+lower+1)/2] ;
while (lower <= upper) {
while (c.relation(a[lower], pivotValue)) {
lower++ ;
}
while (c.relation(pivotValue, a[upper])) {
upper-- ;
}
if (lower <= upper) {
if (lower < upper) {
swap(a, lower, upper) ;
}
lower++ ;
upper-- ;
}
}
return upper ;
}
/**
* The recursive Quicksort function.
*
* @param a the array out of which to take a slice.
* @param lower the lower bound of this slice.
* @param upper the upper bound of this slice.
* @param c the Comparator to be used to define the
* order.
*/
private static void quicksort(final Object[] a,
final int lower,
final int upper,
final Comparator c) {
int sliceLength = upper-lower+1 ;
if (sliceLength > 1) {
if (sliceLength == 2) {
if (c.relation(a[upper], a[lower])) {
swap (a, lower, upper) ;
}
} else {
// This partition implementation does not guarantee that the
// split point contains the pivot value so we cannot assume
// that the pivot is between the two slices.
int pivotIndex = partition(a, lower, upper, c) ;
quicksort(a, lower, pivotIndex, c) ;
quicksort(a, pivotIndex+1, upper, c) ;
}
}
}
}