A quick sort algorithm to sort Vectors or arrays. Provides sort and binary search capabilities.
// HTMLParser Library - A java-based parser for HTML
// http://htmlparser.org
// Copyright (C) 2006 Derrick Oswald
//
// Revision Control Information
//
// $URL: https://svn.sourceforge.net/svnroot/htmlparser/trunk/lexer/src/main/java/org/htmlparser/util/sort/Sort.java $
// $Author: derrickoswald $
// $Date: 2006-09-16 10:44:17 -0400 (Sat, 16 Sep 2006) $
// $Revision: 4 $
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Common Public License; either
// version 1.0 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Common Public License for more details.
//
// You should have received a copy of the Common Public License
// along with this library; if not, the license is available from
// the Open Source Initiative (OSI) website:
// http://opensource.org/licenses/cpl1.0.php
//package org.htmlparser.util.sort;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
/**
* A quick sort algorithm to sort Vectors or arrays. Provides sort and binary
* search capabilities.
* <p>
* This all goes away in JDK 1.2.
* <p>
*
* @author James Gosling
* @author Kevin A. Smith
* @author Derrick Oswald
* @version 1.4, 11 June, 1997
*/
public class Sort {
/**
* No object of this class need ever be instantiated. All methods are
* static.
*/
private Sort() {
}
/**
* This is a generic version of C.A.R Hoare's Quick Sort algorithm. This
* will handle vectors that are already sorted, and vectors with duplicate
* keys. Equivalent to:
*
* <pre>
* QuickSort(v, 0, v.size() - 1);
* </pre>
*
* @param v
* A <code>Vector</code> of <code>Ordered</code> items.
* @exception ClassCastException
* If the vector contains objects that are not
* <code>Ordered</code>.
*/
public static void QuickSort(Vector v) throws ClassCastException {
QuickSort(v, 0, v.size() - 1);
}
/**
* This is a generic version of C.A.R Hoare's Quick Sort algorithm. This
* will handle vectors that are already sorted, and vectors with duplicate
* keys.
* <p>
* If you think of a one dimensional vector as going from the lowest index
* on the left to the highest index on the right then the parameters to this
* function are lowest index or left and highest index or right.
*
* @param v
* A <code>Vector</code> of <code>Ordered</code> items.
* @param lo0
* Left boundary of vector partition.
* @param hi0
* Right boundary of vector partition.
* @exception ClassCastException
* If the vector contains objects that are not
* <code>Ordered</code>.
*/
public static void QuickSort(Vector v, int lo0, int hi0)
throws ClassCastException {
int lo = lo0;
int hi = hi0;
Ordered mid;
if (hi0 > lo0) { // arbitrarily establish partition element as the
// midpoint of the vector
mid = (Ordered) v.elementAt((lo0 + hi0) / 2);
// loop through the vector until indices cross
while (lo <= hi) {
// find the first element that is greater than or equal to
// the partition element starting from the left index
while ((lo < hi0)
&& (0 > ((Ordered) v.elementAt(lo)).compare(mid)))
++lo;
// find an element that is smaller than or equal to
// the partition element starting from the right index
while ((hi > lo0)
&& (0 < ((Ordered) v.elementAt(hi)).compare(mid)))
--hi;
// if the indexes have not crossed, swap
if (lo <= hi)
swap(v, lo++, hi--);
}
// if the right index has not reached the left side of array
// must now sort the left partition
if (lo0 < hi)
QuickSort(v, lo0, hi);
// if the left index has not reached the right side of array
// must now sort the right partition
if (lo < hi0)
QuickSort(v, lo, hi0);
}
}
private static void swap(Vector v, int i, int j) {
Object o;
o = v.elementAt(i);
v.setElementAt(v.elementAt(j), i);
v.setElementAt(o, j);
}
/**
* This is a generic version of C.A.R Hoare's Quick Sort algorithm. This
* will handle arrays that are already sorted, and arrays with duplicate
* keys.
* <p>
* Equivalent to:
*
* <pre>
* QuickSort(a, 0, a.length - 1);
* </pre>
*
* @param a
* An array of <code>Ordered</code> items.
*/
public static void QuickSort(Ordered[] a) {
QuickSort(a, 0, a.length - 1);
}
/**
* This is a generic version of C.A.R Hoare's Quick Sort algorithm. This
* will handle arrays that are already sorted, and arrays with duplicate
* keys.
* <p>
* If you think of a one dimensional array as going from the lowest index on
* the left to the highest index on the right then the parameters to this
* function are lowest index or left and highest index or right.
*
* @param a
* An array of <code>Ordered</code> items.
* @param lo0
* Left boundary of array partition.
* @param hi0
* Right boundary of array partition.
*/
public static void QuickSort(Ordered[] a, int lo0, int hi0) {
int lo = lo0;
int hi = hi0;
Ordered mid;
if (hi0 > lo0) {
// arbitrarily establish partition element as the midpoint of the
// array
mid = a[(lo0 + hi0) / 2];
// loop through the vector until indices cross
while (lo <= hi) {
// find the first element that is greater than or equal to
// the partition element starting from the left index
while ((lo < hi0) && (0 > a[lo].compare(mid)))
++lo;
// find an element that is smaller than or equal to
// the partition element starting from the right Index.
while ((hi > lo0) && (0 < a[hi].compare(mid)))
--hi;
// if the indexes have not crossed, swap
if (lo <= hi)
swap(a, lo++, hi--);
}
// if the right index has not reached the left side of array
// must now sort the left partition
if (lo0 < hi)
QuickSort(a, lo0, hi);
// if the left index has not reached the right side of array
// must now sort the right partition
if (lo < hi0)
QuickSort(a, lo, hi0);
}
}
/**
* Swaps two elements of an array.
*
* @param a
* The array of elements.
* @param i
* The index of one item to swap.
* @param j
* The index of the other item to swap.
*/
private static void swap(Object[] a, int i, int j) {
Object o;
o = a[i];
a[i] = a[j];
a[j] = o;
}
/**
* This is a string version of C.A.R Hoare's Quick Sort algorithm. This will
* handle arrays that are already sorted, and arrays with duplicate keys.
* <p>
* Equivalent to:
*
* <pre>
* QuickSort(a, 0, a.length - 1);
* </pre>
*
* @param a
* An array of <code>String</code> items.
*/
public static void QuickSort(String[] a) {
QuickSort(a, 0, a.length - 1);
}
/**
* This is a string version of C.A.R Hoare's Quick Sort algorithm. This will
* handle arrays that are already sorted, and arrays with duplicate keys.
* <p>
* If you think of a one dimensional array as going from the lowest index on
* the left to the highest index on the right then the parameters to this
* function are lowest index or left and highest index or right.
*
* @param a
* An array of <code>String</code> items.
* @param lo0
* Left boundary of array partition.
* @param hi0
* Right boundary of array partition.
*/
public static void QuickSort(String[] a, int lo0, int hi0) {
int lo = lo0;
int hi = hi0;
String mid;
if (hi0 > lo0) {
// arbitrarily establish partition element as the midpoint of the
// array
mid = a[(lo0 + hi0) / 2];
// loop through the vector until indices cross
while (lo <= hi) {
// find the first element that is greater than or equal to
// the partition element starting from the left index
while ((lo < hi0) && (0 > a[lo].compareTo(mid)))
++lo;
// find an element that is smaller than or equal to
// the partition element starting from the right Index.
while ((hi > lo0) && (0 < a[hi].compareTo(mid)))
--hi;
// if the indexes have not crossed, swap
if (lo <= hi)
swap(a, lo++, hi--);
}
// if the right index has not reached the left side of array
// must now sort the left partition
if (lo0 < hi)
QuickSort(a, lo0, hi);
// if the left index has not reached the right side of array
// must now sort the right partition
if (lo < hi0)
QuickSort(a, lo, hi0);
}
}
/**
* This is a generic version of C.A.R Hoare's Quick Sort algorithm. This
* will handle Sortable objects that are already sorted, and Sortable
* objects with duplicate keys.
* <p>
*
* @param sortable
* A <code>Sortable</code> object.
* @param lo0
* Left boundary of partition.
* @param hi0
* Right boundary of partition.
*/
public static void QuickSort(Sortable sortable, int lo0, int hi0) {
int lo = lo0;
int hi = hi0;
Ordered mid;
Ordered test;
if (hi0 > lo0) { // arbitrarily establish partition element as the
// midpoint of the vector
mid = sortable.fetch((lo0 + hi0) / 2, null);
test = null;
// loop through the vector until indices cross
while (lo <= hi) {
// find the first element that is greater than or equal to
// the partition element starting from the left index
while ((lo < hi0)
&& (0 > (test = sortable.fetch(lo, test)).compare(mid)))
++lo;
// find an element that is smaller than or equal to
// the partition element starting from the right index
while ((hi > lo0)
&& (0 < (test = sortable.fetch(hi, test)).compare(mid)))
--hi;
// if the indexes have not crossed, swap
if (lo <= hi)
sortable.swap(lo++, hi--);
}
// if the right index has not reached the left side of array
// must now sort the left partition
if (lo0 < hi)
QuickSort(sortable, lo0, hi);
// if the left index has not reached the right side of array
// must now sort the right partition
if (lo < hi0)
QuickSort(sortable, lo, hi0);
}
}
/**
* This is a generic version of C.A.R Hoare's Quick Sort algorithm. This
* will handle Sortable objects that are already sorted, and Sortable
* objects with duplicate keys.
* <p>
* Equivalent to:
*
* <pre>
* QuickSort(sortable, sortable.first(), sortable.last());
* </pre>
*
* @param sortable
* A <code>Sortable</code> object.
*/
public static void QuickSort(Sortable sortable) {
QuickSort(sortable, sortable.first(), sortable.last());
}
/**
* Sort a Hashtable.
*
* @param h
* A Hashtable with String or Ordered keys.
* @return A sorted array of the keys.
* @exception ClassCastException
* If the keys of the hashtable are not <code>Ordered</code>.
*/
public static Object[] QuickSort(Hashtable h) throws ClassCastException {
Enumeration e;
boolean are_strings;
Object[] ret;
// make the array
ret = new Ordered[h.size()];
e = h.keys();
are_strings = true; // until proven otherwise
for (int i = 0; i < ret.length; i++) {
ret[i] = e.nextElement();
if (are_strings && !(ret[i] instanceof String))
are_strings = false;
}
// sort it
if (are_strings)
QuickSort((String[]) ret);
else
QuickSort((Ordered[]) ret);
return (ret);
}
/**
* Binary search for an object
*
* @param set
* The collection of <code>Ordered</code> objects.
* @param ref
* The name to search for.
* @param lo
* The lower index within which to look.
* @param hi
* The upper index within which to look.
* @return The index at which reference was found or is to be inserted.
*/
public static int bsearch(Sortable set, Ordered ref, int lo, int hi) {
int num;
int mid;
Ordered ordered;
int half;
int result;
int ret;
ret = -1;
num = (hi - lo) + 1;
ordered = null;
while ((-1 == ret) && (lo <= hi)) {
half = num / 2;
mid = lo + ((0 != (num & 1)) ? half : half - 1);
ordered = set.fetch(mid, ordered);
result = ref.compare(ordered);
if (0 == result)
ret = mid;
else if (0 > result) {
hi = mid - 1;
num = ((0 != (num & 1)) ? half : half - 1);
} else {
lo = mid + 1;
num = half;
}
}
if (-1 == ret)
ret = lo;
return (ret);
}
/**
* Binary search for an object
*
* @param set
* The collection of <code>Ordered</code> objects.
* @param ref
* The name to search for.
* @return The index at which reference was found or is to be inserted.
*/
public static int bsearch(Sortable set, Ordered ref) {
return (bsearch(set, ref, set.first(), set.last()));
}
/**
* Binary search for an object
*
* @param vector
* The vector of <code>Ordered</code> objects.
* @param ref
* The name to search for.
* @param lo
* The lower index within which to look.
* @param hi
* The upper index within which to look.
* @return The index at which reference was found or is to be inserted.
*/
public static int bsearch(Vector vector, Ordered ref, int lo, int hi) {
int num;
int mid;
int half;
int result;
int ret;
ret = -1;
num = (hi - lo) + 1;
while ((-1 == ret) && (lo <= hi)) {
half = num / 2;
mid = lo + ((0 != (num & 1)) ? half : half - 1);
result = ref.compare(vector.elementAt(mid));
if (0 == result)
ret = mid;
else if (0 > result) {
hi = mid - 1;
num = ((0 != (num & 1)) ? half : half - 1);
} else {
lo = mid + 1;
num = half;
}
}
if (-1 == ret)
ret = lo;
return (ret);
}
/**
* Binary search for an object
*
* @param vector
* The vector of <code>Ordered</code> objects.
* @param ref
* The name to search for.
* @return The index at which reference was found or is to be inserted.
*/
public static int bsearch(Vector vector, Ordered ref) {
return (bsearch(vector, ref, 0, vector.size() - 1));
}
/**
* Binary search for an object
*
* @param array
* The array of <code>Ordered</code> objects.
* @param ref
* The name to search for.
* @param lo
* The lower index within which to look.
* @param hi
* The upper index within which to look.
* @return The index at which reference was found or is to be inserted.
*/
public static int bsearch(Ordered[] array, Ordered ref, int lo, int hi) {
int num;
int mid;
int half;
int result;
int ret;
ret = -1;
num = (hi - lo) + 1;
while ((-1 == ret) && (lo <= hi)) {
half = num / 2;
mid = lo + ((0 != (num & 1)) ? half : half - 1);
result = ref.compare(array[mid]);
if (0 == result)
ret = mid;
else if (0 > result) {
hi = mid - 1;
num = ((0 != (num & 1)) ? half : half - 1);
} else {
lo = mid + 1;
num = half;
}
}
if (-1 == ret)
ret = lo;
return (ret);
}
/**
* Binary search for an object
*
* @param array
* The array of <code>Ordered</code> objects.
* @param ref
* The name to search for.
* @return The index at which reference was found or is to be inserted.
*/
public static int bsearch(Ordered[] array, Ordered ref) {
return (bsearch(array, ref, 0, array.length - 1));
}
}
// HTMLParser Library - A java-based parser for HTML
// http://htmlparser.org
// Copyright (C) 2006 Derrick Oswald
//
// Revision Control Information
//
// $URL:
// https://svn.sourceforge.net/svnroot/htmlparser/trunk/lexer/src/main/java/org/htmlparser/util/sort/Ordered.java
// $
// $Author: derrickoswald $
// $Date: 2006-09-16 10:44:17 -0400 (Sat, 16 Sep 2006) $
// $Revision: 4 $
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Common Public License; either
// version 1.0 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Common Public License for more details.
//
// You should have received a copy of the Common Public License
// along with this library; if not, the license is available from
// the Open Source Initiative (OSI) website:
// http://opensource.org/licenses/cpl1.0.php
/**
* Describes an object that knows about ordering. Implementors must have a
* comparison function, which imposes a partial ordering on some collection of
* objects. Ordered objects can be passed to a sort method (such as
* org.htmlparser.util.sort.Sort) to allow precise control over the sort order.
* <p>
* An set of elements S is partially ordered if and only if
* <code>e1.compare(e2)==0</code> implies that <code>e1.equals(e2)</code> for
* every e1 and e2 in S.
* <p>
* This all goes away in JDK 1.2.
* <p>
* For use with java.lang.Comparable from JDK 1.2:
*
* <pre>
* public int compare(Object o1, Object o2) {
* return (((Ordered) o1).compare(o2));
* }
* </pre>
*
* @see Sort
*/
interface Ordered {
/**
* Compares this object with another for order. Returns a negative integer,
* zero, or a positive integer as this object is less than, equal to, or
* greater than the second.
* <p>
* The implementor must ensure that
* <code>sgn(x.compare(y)) == -sgn(y.compare(x))</code> for all x and y.
* (This implies that <code>x.compare(y)</code> must throw an exception if
* and only if <code>y.compare(x)</code> throws an exception.)
* <p>
* The implementor must also ensure that the relation is transitive:
* <code>((x.compare(y)>0) && (y.compare(z)>0))</code> implies
* <code>x.compare(z)>0</code>.
* <p>
* Finally, the implementer must ensure that <code>x.compare(y)==0</code>
* implies that <code>sgn(x.compare(z))==sgn(y.compare(z))</code> for all z.
*
* @param that
* The object to compare this object against.
* @return A negative integer, zero, or a positive integer as this object is
* less than, equal to, or greater than the second.
* @exception ClassCastException
* The arguments type prevents it from being compared by this
* Ordered.
*/
public int compare(Object that);
}
// HTMLParser Library - A java-based parser for HTML
// http://htmlparser.org
// Copyright (C) 2006 Derrick Oswald
//
// Revision Control Information
//
// $URL:
// https://svn.sourceforge.net/svnroot/htmlparser/trunk/lexer/src/main/java/org/htmlparser/util/sort/Sortable.java
// $
// $Author: derrickoswald $
// $Date: 2006-09-16 10:44:17 -0400 (Sat, 16 Sep 2006) $
// $Revision: 4 $
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Common Public License; either
// version 1.0 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Common Public License for more details.
//
// You should have received a copy of the Common Public License
// along with this library; if not, the license is available from
// the Open Source Initiative (OSI) website:
// http://opensource.org/licenses/cpl1.0.php
/**
* Provides a mechanism to abstract the sort process. Classes implementing this
* interface are collections of Ordered objects that are to be sorted by the
* Sort class and are not necessarily Vectors or Arrays of Ordered objects.
*
* @see Sort
*/
interface Sortable {
/**
* Returns the first index of the Sortable.
*
* @return The index of the first element.
*/
public int first();
/**
* Returns the last index of the Sortable.
*
* @return The index of the last element. If this were an array object this
* would be (object.length - 1).
*/
public int last();
/**
* Fetch the object at the given index.
*
* @param index
* The item number to get.
* @param reuse
* If this argument is not null, it is an object acquired from a
* previous fetch that is no longer needed and may be returned as
* the result if it makes mores sense to alter and return it than
* to fetch or create a new element. That is, the reuse object is
* garbage and may be used to avoid allocating a new object if
* that would normally be the strategy.
* @return The Ordered object at that index.
*/
public Ordered fetch(int index, Ordered reuse);
/**
* Swaps the elements at the given indicies.
*
* @param i
* One index.
* @param j
* The other index.
*/
public void swap(int i, int j);
}
Related examples in the same category