/* * QuickSort.java * @author Simon Thiel <simon.thiel at gmx.de> * Created on 25. Januar 2005, 11:11 * * integration of: * * QuickSort.java by Henk Jan Nootenboom, 9 Sep 2002 * Copyright 2002-2005 SUMit. All Rights Reserved. * * Algorithm designed by prof C. A. R. Hoare, 1962 * See http://www.sum-it.nl/en200236.html * for algorithm improvement by Henk Jan Nootenboom, 2002. * * Recursive Quicksort, sorts (part of) a Vector by * 1. Choose a pivot, an element used for comparison * 2. dividing into two parts: * - less than-equal pivot * - and greater than-equal to pivot. * A element that is equal to the pivot may end up in any part. * See www.sum-it.nl/en200236.html for the theory behind this. * 3. Sort the parts recursively until there is only one element left. * * www.sum-it.nl/QuickSort.java this source code * www.sum-it.nl/quicksort.php3 demo of this quicksort in a java applet * * Permission to use, copy, modify, and distribute this java source code * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and * without fee is hereby granted. * See http://www.sum-it.nl/security/index.html for copyright laws. */ package sit.tools; import java.util.Vector; /** * * @author Simon Thiel */ public class QuickSort { /** * Creates a new instance of QuickSort */ public QuickSort() { } /** * Sort the entire vector, if it is not empty * * @param elements */ public void quickSort(Vector elements) { if (!elements.isEmpty()) { this.quickSort(elements, 0, elements.size() - 1); } } /** * QuickSort.java by Henk Jan Nootenboom, 9 Sep 2002 Copyright 2002-2005 * SUMit. All Rights Reserved. * * Algorithm designed by prof C. A. R. Hoare, 1962 See * http://www.sum-it.nl/en200236.html for algorithm improvement by Henk Jan * Nootenboom, 2002. * * Recursive Quicksort, sorts (part of) a Vector by 1. Choose a pivot, an * element used for comparison 2. dividing into two parts: - less than-equal * pivot - and greater than-equal to pivot. A element that is equal to the * pivot may end up in any part. See www.sum-it.nl/en200236.html for the * theory behind this. 3. Sort the parts recursively until there is only one * element left. * * www.sum-it.nl/QuickSort.java this source code * www.sum-it.nl/quicksort.php3 demo of this quicksort in a java applet * * Permission to use, copy, modify, and distribute this java source code and * its documentation for NON-COMMERCIAL or COMMERCIAL purposes and without * fee is hereby granted. See http://www.sum-it.nl/security/index.html for * copyright laws. * * @param elements * @param lowIndex * @param highIndex */ private void quickSort(Vector elements, int lowIndex, int highIndex) { int lowToHighIndex; int highToLowIndex; int pivotIndex; Comparable pivotValue; // values Comparable lowToHighValue; Comparable highToLowValue; Comparable parking; //values end int newLowIndex; int newHighIndex; int compareResult; lowToHighIndex = lowIndex; highToLowIndex = highIndex; /** * Choose a pivot, remember it's value No special action for the pivot * element itself. It will be treated just like any other element. */ pivotIndex = (lowToHighIndex + highToLowIndex) / 2; pivotValue = getValue(elements.elementAt(pivotIndex)); /** * Split the Vector in two parts. * * The lower part will be lowIndex - newHighIndex, containing elements * <= pivot Value * * The higher part will be newLowIndex - highIndex, containting elements * >= pivot Value */ newLowIndex = highIndex + 1; newHighIndex = lowIndex - 1; // loop until low meets high while ((newHighIndex + 1) < newLowIndex) // loop until partition complete { // loop from low to high to find a candidate for swapping lowToHighValue = getValue(elements.elementAt(lowToHighIndex)); while (lowToHighIndex < newLowIndex & lowToHighValue.compareTo(pivotValue) < 0) { newHighIndex = lowToHighIndex; // add element to lower part lowToHighIndex++; lowToHighValue = getValue(elements.elementAt(lowToHighIndex)); } // loop from high to low find other candidate for swapping highToLowValue = getValue(elements.elementAt(highToLowIndex)); while (newHighIndex <= highToLowIndex & (highToLowValue.compareTo(pivotValue) > 0)) { newLowIndex = highToLowIndex; // add element to higher part highToLowIndex--; highToLowValue = getValue(elements.elementAt(highToLowIndex)); } // swap if needed if (lowToHighIndex == highToLowIndex) // one last element, may go in either part { newHighIndex = lowToHighIndex; // move element arbitrary to lower part } else if (lowToHighIndex < highToLowIndex) // not last element yet { compareResult = lowToHighValue.compareTo(highToLowValue); if (compareResult >= 0) // low >= high, swap, even if equal { parking = lowToHighValue; elements.setElementAt(highToLowValue, lowToHighIndex); elements.setElementAt(parking, highToLowIndex); newLowIndex = highToLowIndex; newHighIndex = lowToHighIndex; lowToHighIndex++; highToLowIndex--; } } } // Continue recursion for parts that have more than one element if (lowIndex < newHighIndex) { this.quickSort(elements, lowIndex, newHighIndex); // sort lower subpart } if (newLowIndex < highIndex) { this.quickSort(elements, newLowIndex, highIndex); // sort higher subpart } } /** * * @param o * @return */ private Comparable getValue(Object o) { if (o == null) { return null; } return (Comparable) o; } }