package weka.classifiers.rules.sortinghandler; /** * This code is from the book: * * Winder, R and Roberts, G (1998) <em>Developing Java * Software</em>, John Wiley & Sons. * * It is copyright (c) 1997 Russel Winder and Graham Roberts. */ import java.util.Vector ; /** * Sort an array of <code>Object</code>s 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.0 19.5.97 * @author Russel Winder */ public class QuicksortVector implements VectorSort { /** * The per object sort operation. * * @param v the <code>Vector</code> of <code>Object</code>s to be * sorted. * * @param c the <code>Comparator</code> used to compare the * <code>Object</code> during the sort process. */ public final void sort(final Vector v, final Comparator c) { execute(v, c) ; } /** * The statically accessible sort operation. * * @param v the <code>Vector</code> of <code>Object</code>s to be * sorted. * * @param c the <code>Comparator</code> used to compare the * <code>Object</code> during the sort process. */ public static void execute(final Vector v, final Comparator c) { quicksort(v, 0, v.size()-1, c) ; } /** * Given the array and two indices, swap the two items in the * array. */ private static void swap(final Vector v, final int a, final int b) { Object temp = v.elementAt(a) ; v.setElementAt(v.elementAt(b), a) ; v.setElementAt(temp, b) ; } /** * Partition an array in two using the pivot value that is at the * centre of the array being partitioned. * * <p>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 v 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 <code>Comparator</code> to be used to define the * order. */ private static int partition(final Vector v, int lower, int upper, final Comparator c) { Object pivotValue = v.elementAt((upper+lower+1)/2) ; while (lower <= upper) { while (c.relation(v.elementAt(lower), pivotValue)) { lower++ ; } while (c.relation(pivotValue, v.elementAt(upper))) { //System.out.println("Lower: "+lower +" "+"upper: "+upper+"\n"); upper-- ; } if (lower <= upper) { if (lower < upper) { swap(v, lower, upper) ; } lower++ ; upper-- ; } } return upper ; } /** * The recursive Quicksort function. * * @param v 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 <code>Comparator</code> to be used to define the * order. */ private static void quicksort(final Vector v, final int lower, final int upper, final Comparator c) { //System.out.println("Lower: "+lower +" "+"upper: "+upper+"\n"); int sliceLength = upper-lower+1 ; if (sliceLength > 1) { if (sliceLength == 2) { if (c.relation(v.elementAt(upper),v.elementAt(lower))) { swap (v, lower, upper) ; } } else { // // This pivot 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(v, lower, upper, c) ; quicksort(v, lower, pivotIndex, c) ; quicksort(v, pivotIndex+1, upper, c) ; } } } }