blob: cb963d6de43e1657340425a7d3259003e8b4e986 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26
27/* The contents of this file are subject to the Sun Public License
28 * Version 1.0 (the "License"); you may not use this file except in
29 * compliance with the License. A copy of the License is available at
30 * http://www.sun.com/, and in the file LICENSE.html in the
31 * doc directory.
32 *
33 * The Original Code is HAT. The Initial Developer of the
34 * Original Code is Bill Foote, with contributions from others
35 * at JavaSoft/Sun. Portions created by Bill Foote and others
36 * at Javasoft/Sun are Copyright (C) 1997-2004. All Rights Reserved.
37 *
38 * In addition to the formal license, I ask that you don't
39 * change the history or donations files without permission.
40 */
41
42package com.sun.tools.hat.internal.util;
43import java.util.*;
44
45/**
46 * A singleton utility class that sorts a vector.
47 * <p>
48 * Use:
49 * <pre>
50 *
51 * Vector v = <a vector of, say, String objects>;
52 * VectorSorter.sort(v, new Comparer() {
53 * public int compare(Object lhs, Object rhs) {
54 * return ((String) lhs).compareTo((String) rhs);
55 * }
56 * });
57 * </pre>
58 *
59 * @author Bill Foote
60 */
61
62
63public class VectorSorter {
64
65 /**
66 * Sort the given vector, using c for comparison
67 **/
68 static public void sort(Vector<Object> v, Comparer c) {
69 quickSort(v, c, 0, v.size()-1);
70 }
71
72
73 /**
74 * Sort a vector of strings, using String.compareTo()
75 **/
76 static public void sortVectorOfStrings(Vector<Object> v) {
77 sort(v, new Comparer() {
78 public int compare(Object lhs, Object rhs) {
79 return ((String) lhs).compareTo((String) rhs);
80 }
81 });
82 }
83
84
85 static private void swap(Vector<Object> v, int a, int b) {
86 Object tmp = v.elementAt(a);
87 v.setElementAt(v.elementAt(b), a);
88 v.setElementAt(tmp, b);
89 }
90
91 //
92 // Sorts v between from and to, inclusive. This is a quick, off-the-top-
93 // of-my-head quicksort: I haven't put any thought into optimizing it.
94 // I _did_ put thought into making sure it's safe (it will always
95 // terminate). Worst-case it's O(n^2), but it will usually run in
96 // in O(n log n). It's well-behaved if the list is already sorted,
97 // or nearly so.
98 //
99 static private void quickSort(Vector<Object> v, Comparer c, int from, int to) {
100 if (to <= from)
101 return;
102 int mid = (from + to) / 2;
103 if (mid != from)
104 swap(v, mid, from);
105 Object pivot = v.elementAt(from);
106 // Simple-minded, but reasonable
107 int highestBelowPivot = from - 1;
108 int low = from+1;
109 int high = to;
110 // We now move low and high toward eachother, maintaining the
111 // invariants:
112 // v[i] <= pivot for all i < low
113 // v[i] > pivot for all i > high
114 // As long as these invariants hold, and every iteration makes
115 // progress, we are safe.
116 while (low <= high) {
117 int cmp = c.compare(v.elementAt(low), pivot);
118 if (cmp <= 0) { // v[low] <= pivot
119 if (cmp < 0) {
120 highestBelowPivot = low;
121 }
122 low++;
123 } else {
124 int c2;
125 for (;;) {
126 c2 = c.compare(v.elementAt(high), pivot);
127 // v[high] > pivot:
128 if (c2 > 0) {
129 high--;
130 if (low > high) {
131 break;
132 }
133 } else {
134 break;
135 }
136 }
137 // At this point, low is never == high
138 if (low <= high) {
139 swap(v, low, high);
140 if (c2 < 0) {
141 highestBelowPivot = low;
142 }
143 low++;
144 high--;
145 }
146 }
147 }
148 // Now we just need to sort from from..highestBelowPivot
149 // and from high+1..to
150 if (highestBelowPivot > from) {
151 // pivot == pivot, so ensure algorithm terminates
152 swap(v, from, highestBelowPivot);
153 quickSort(v, c, from, highestBelowPivot-1);
154 }
155 quickSort(v, c, high+1, to);
156 }
157}