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) ;
}
}
}
}