jdk/src/share/classes/com/sun/tools/hat/internal/util/ArraySorter.java
author xdono
Wed, 02 Jul 2008 12:55:45 -0700
changeset 715 f16baef3a20e
parent 468 642c8c0be52e
child 5506 202f599c92aa
permissions -rw-r--r--
6719955: Update copyright year Summary: Update copyright year for files that have been modified in 2008 Reviewed-by: ohair, tbell
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
715
f16baef3a20e 6719955: Update copyright year
xdono
parents: 468
diff changeset
     2
 * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
468
642c8c0be52e 6695553: Cleanup GPLv2+SPL legal notices in hat sources
ohair
parents: 2
diff changeset
    27
/*
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 * The Original Code is HAT. The Initial Developer of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 * Original Code is Bill Foote, with contributions from others
468
642c8c0be52e 6695553: Cleanup GPLv2+SPL legal notices in hat sources
ohair
parents: 2
diff changeset
    30
 * at JavaSoft/Sun.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
package com.sun.tools.hat.internal.util;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * A singleton utility class that sorts an array of objects.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * Use:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 *  Stuff[] arr = ...;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 *  ArraySorter.sort(arr, new Comparer() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 *      public int compare(Object lhs, Object rhs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 *          return ((String) lhs).compareTo((String) rhs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 *      }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 *  });
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * @author      Bill Foote
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
public class ArraySorter {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
     * Sort the given array, using c for comparison
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
    static public void sort(Object[] arr, Comparer c)  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
        quickSort(arr, c, 0, arr.length-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
     * Sort an array of strings, using String.compareTo()
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
    static public void sortArrayOfStrings(Object[] arr) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
        sort(arr, new Comparer() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
            public int compare(Object lhs, Object rhs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
                return ((String) lhs).compareTo((String) rhs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
        });
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    static private void swap(Object[] arr, int a, int b) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
        Object tmp = arr[a];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
        arr[a] = arr[b];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
        arr[b] = tmp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    // Sorts arr between from and to, inclusive.  This is a quick, off-the-top-
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    // of-my-head quicksort:  I haven't put any thought into optimizing it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    // I _did_ put thought into making sure it's safe (it will always
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    // terminate).  Worst-case it's O(n^2), but it will usually run in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    // in O(n log n).  It's well-behaved if the list is already sorted,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    // or nearly so.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    static private void quickSort(Object[] arr, Comparer c, int from, int to) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
        if (to <= from)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        int mid = (from + to) / 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        if (mid != from)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
            swap(arr, mid, from);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
        Object pivot = arr[from];   // Simple-minded, but reasonable
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        int highestBelowPivot = from - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
        int low = from+1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
        int high = to;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
            // We now move low and high toward each other, maintaining the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
            // invariants:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
            //      arr[i] <= pivot    for all i < low
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
            //      arr[i] > pivot     for all i > high
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
            // As long as these invariants hold, and every iteration makes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
            // progress, we are safe.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
        while (low <= high) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
            int cmp = c.compare(arr[low], pivot);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
            if (cmp <= 0) {   // arr[low] <= pivot
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
                if (cmp < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
                    highestBelowPivot = low;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
                low++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
                int c2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
                for (;;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
                        // arr[high] > pivot:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
                    c2 = c.compare(arr[high], pivot);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
                    if (c2 > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
                        high--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
                        if (low > high) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
                // At this point, low is never == high, BTW
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
                if (low <= high) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
                    swap(arr, low, high);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
                    if (c2 < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
                        highestBelowPivot = low;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
                    low++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
                    high--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        // At this point, low == high+1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        // Now we just need to sort from from..highestBelowPivot
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        // and from high+1..to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        if (highestBelowPivot > from) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
            // pivot == pivot, so ensure algorithm terminates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
            swap(arr, from, highestBelowPivot);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
            quickSort(arr, c, from, highestBelowPivot-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        quickSort(arr, c, high+1, to);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
}