package jds.sort; import java.util.Enumeration; import jds.FindNth; import jds.SortAlgorithm; import java.util.Comparator; import jds.Indexed; /** * Partition - algorithms involving partitioning a vector into groups; * for use with book * Classic Data Structures * in Java * by Timothy A Budd, * published by Addison-Wesley, 2001. * * @author Timothy A. Budd * @version 1.1 September 1999 */ public class Partition implements FindNth, SortAlgorithm { /** * the collection that will hold the data values */ protected Indexed elementData; /** * the Comparator object used to place elements in order */ protected Comparator test; /** * initialize a new Parition object * * @param c the Comparator used to place values in order */ public Partition (Comparator c) { test =c ; } /** * initialize a new Parition object * * @param v an Indexed object of initial values * @param c the Comparator used to place values in order */ public Partition (Indexed v, Comparator c) { test = c; elementData = v; } // the FindNth interface /** * find nth smallest value in collection * * @param index of value, from 0 to (size-1) * @return value of element * @exception java.util.NoSuchElementException index is illegal */ public Object findNth (int n) { return findNth (n, 0, elementData.size()); } private Object findNth (int n, int low, int high) { int pivotIndex = pivot(low, high, (high + low)/2); if (pivotIndex == n) return elementData.elementAt(n); if (n < pivotIndex) return findNth(n, low, pivotIndex); return findNth(n, pivotIndex+1, high); } // the QuickSort algorithm /** * rearrange collection into asending order * * @param data the values to be ordered */ public void sort (Indexed data) { elementData = data; quickSort(0, data.size()); } private void quickSort(int low, int high) { if (low >= high) return; int pivotIndex = (low + high) / 2; pivotIndex = pivot(low, high, pivotIndex); quickSort(low, pivotIndex); quickSort(pivotIndex + 1, high); } // the pivot algorithm private void swap (int i, int j) { if (i == j) return; Object temp = elementData.elementAt(i); elementData.setElementAt(elementData.elementAt(j), i); elementData.setElementAt(temp, j); } private int pivot (int start, int stop, int position) { // swap pivot into start position swap(start, position); // partition index values int low = start + 1; int high = stop; while (low < high) { if (test.compare(elementData.elementAt(low), elementData.elementAt(start)) < 0) low++; else if (test.compare(elementData.elementAt(--high), elementData.elementAt(start)) < 0) swap(low, high); } // swap pivot back into place swap(start, --low); return low; } }