Java Array Sort sortRetain(long[] a)

Here you can find the source of sortRetain(long[] a)

Description

Sorts the specified array of longs into ascending numerical order.

License

Open Source License

Parameter

Parameter Description
a the array to be sorted.

Declaration

public static int[] sortRetain(long[] a) 

Method Source Code

//package com.java2s;
/**/*from w  w  w.  j ava  2 s .  c  o  m*/
 * <PRE>
 * Name   : com.solidmatrix.regxmaker.util.shared.SortUtils
 * Project: RegXmaker Library
 * Version: 1.1
 * Tier   : N/A (Function Class)
 * Author : Gennadiy Shafranovich
 * Purpose: To provide custom features when sortings
 * Summary: Provides the ability to sort arrays of primitives 
 *          and return an array of ints in which each subset
 *          of the array contains the original position of the value
 *          that resides in the sorted array. Methods are copied from
 *          java.util.Arrays class and then modified to provide this
 *          functionality.
 *
 * Copyright (C) 2001, 2004 SolidMatrix Technologies, Inc.
 * This file is part of RegXmaker Library.
 *
 * RegXmaker Library is is free software; you can redistribute it and/or modify
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * RegXmaker 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 GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Comments: Full, with javadoc.
 *
 * Modification History
 *
 * 01-23-2001  GS Class created and ready for testing
 *
 * 07-05-2004  YS Added licensing information
 * </PRE>
 */

public class Main {
    /**
     * Sorts the specified array of longs into ascending numerical order.
     * The sorting algorithm is a tuned quicksort, adapted from Jon
     * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
     * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
     * 1993).  This algorithm offers n*log(n) performance on many data sets
     * that cause other quicksorts to degrade to quadratic performance.
     *
     * @param a the array to be sorted.
     */
    public static int[] sortRetain(long[] a) {
        int[] pos = getPosArray(a.length);
        sort1(a, pos, 0, a.length);
        return pos;
    }

    /**
     * Sorts the specified range of the specified array of longs into
     * ascending numerical order.  The range to be sorted extends from index
     * <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive.
     * (If <tt>fromIndex==toIndex</tt>, the range to be sorted is empty.)
     *
     * <p>The sorting algorithm is a tuned quicksort, adapted from Jon
     * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
     * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
     * 1993).  This algorithm offers n*log(n) performance on many data sets
     * that cause other quicksorts to degrade to quadratic performance.
     *
     * @param a the array to be sorted.
     * @param fromIndex the index of the first element (inclusive) to be
     *        sorted.
     * @param toIndex the index of the last element (exclusive) to be sorted.
     * @throws IllegalArgumentException if <tt>fromIndex &gt; toIndex</tt>
     * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or
     * <tt>toIndex &gt; a.length</tt>
     */
    public static int[] sortRetain(long[] a, int fromIndex, int toIndex) {
        rangeCheck(a.length, fromIndex, toIndex);
        int[] pos = getPosArray(a.length, fromIndex);
        sort1(a, pos, fromIndex, toIndex - fromIndex);
        return pos;
    }

    /**
     * Sorts the specified array of ints into ascending numerical order.
     * The sorting algorithm is a tuned quicksort, adapted from Jon
     * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
     * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
     * 1993).  This algorithm offers n*log(n) performance on many data sets
     * that cause other quicksorts to degrade to quadratic performance.
     *
     * @param a the array to be sorted.
     */
    public static int[] sortRetain(int[] a) {
        int[] pos = getPosArray(a.length);
        sort1(a, pos, 0, a.length);
        return pos;
    }

    /**
     * Sorts the specified range of the specified array of ints into
     * ascending numerical order.  The range to be sorted extends from index
     * <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive.
     * (If <tt>fromIndex==toIndex</tt>, the range to be sorted is empty.)<p>
     *
     * The sorting algorithm is a tuned quicksort, adapted from Jon
     * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
     * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
     * 1993).  This algorithm offers n*log(n) performance on many data sets
     * that cause other quicksorts to degrade to quadratic performance.
     *
     * @param a the array to be sorted.
     * @param fromIndex the index of the first element (inclusive) to be
     *        sorted.
     * @param toIndex the index of the last element (exclusive) to be sorted.
     * @throws IllegalArgumentException if <tt>fromIndex &gt; toIndex</tt>
     * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or
     *          <tt>toIndex &gt; a.length</tt>
     */
    public static int[] sortRetain(int[] a, int fromIndex, int toIndex) {
        rangeCheck(a.length, fromIndex, toIndex);
        int[] pos = getPosArray(a.length, fromIndex);
        sort1(a, pos, fromIndex, toIndex - fromIndex);
        return pos;
    }

    /**
     * Sorts the specified array of shorts into ascending numerical order.
     * The sorting algorithm is a tuned quicksort, adapted from Jon
     * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
     * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
     * 1993).  This algorithm offers n*log(n) performance on many data sets
     * that cause other quicksorts to degrade to quadratic performance.
     *
     * @param a the array to be sorted.
     */
    public static int[] sortRetain(short[] a) {
        int[] pos = getPosArray(a.length);
        sort1(a, pos, 0, a.length);
        return pos;
    }

    /**
     * Sorts the specified range of the specified array of shorts into
     * ascending numerical order.  The range to be sorted extends from index
     * <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive.
     * (If <tt>fromIndex==toIndex</tt>, the range to be sorted is empty.)<p>
     *
     * The sorting algorithm is a tuned quicksort, adapted from Jon
     * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
     * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
     * 1993).  This algorithm offers n*log(n) performance on many data sets
     * that cause other quicksorts to degrade to quadratic performance.
     *
     * @param a the array to be sorted.
     * @param fromIndex the index of the first element (inclusive) to be
     *        sorted.
     * @param toIndex the index of the last element (exclusive) to be sorted.
     * @throws IllegalArgumentException if <tt>fromIndex &gt; toIndex</tt>
     * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or
     *          <tt>toIndex &gt; a.length</tt>
     */
    public static int[] sortRetain(short[] a, int fromIndex, int toIndex) {
        rangeCheck(a.length, fromIndex, toIndex);
        int[] pos = getPosArray(a.length, fromIndex);
        sort1(a, pos, fromIndex, toIndex - fromIndex);
        return pos;
    }

    /**
     * Sorts the specified array of chars into ascending numerical order.
     * The sorting algorithm is a tuned quicksort, adapted from Jon
     * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
     * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
     * 1993).  This algorithm offers n*log(n) performance on many data sets
     * that cause other quicksorts to degrade to quadratic performance.
     *
     * @param a the array to be sorted.
     */
    public static int[] sortRetain(char[] a) {
        int[] pos = getPosArray(a.length);
        sort1(a, pos, 0, a.length);
        return pos;
    }

    /**
     * Sorts the specified range of the specified array of chars into
     * ascending numerical order.  The range to be sorted extends from index
     * <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive.
     * (If <tt>fromIndex==toIndex</tt>, the range to be sorted is empty.)<p>
     *
     * The sorting algorithm is a tuned quicksort, adapted from Jon
     * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
     * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
     * 1993).  This algorithm offers n*log(n) performance on many data sets
     * that cause other quicksorts to degrade to quadratic performance.
     *
     * @param a the array to be sorted.
     * @param fromIndex the index of the first element (inclusive) to be
     *        sorted.
     * @param toIndex the index of the last element (exclusive) to be sorted.
     * @throws IllegalArgumentException if <tt>fromIndex &gt; toIndex</tt>
     * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or
     *          <tt>toIndex &gt; a.length</tt>
     */
    public static int[] sortRetain(char[] a, int fromIndex, int toIndex) {
        rangeCheck(a.length, fromIndex, toIndex);
        int[] pos = getPosArray(a.length, fromIndex);
        sort1(a, pos, fromIndex, toIndex - fromIndex);
        return pos;
    }

    /**
     * Sorts the specified array of bytes into ascending numerical order.
     * The sorting algorithm is a tuned quicksort, adapted from Jon
     * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
     * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
     * 1993).  This algorithm offers n*log(n) performance on many data sets
     * that cause other quicksorts to degrade to quadratic performance.
     *
     * @param a the array to be sorted.
     */
    public static int[] sortRetain(byte[] a) {
        int[] pos = getPosArray(a.length);
        sort1(a, pos, 0, a.length);
        return pos;
    }

    /**
     * Sorts the specified range of the specified array of bytes into
     * ascending numerical order.  The range to be sorted extends from index
     * <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive.
     * (If <tt>fromIndex==toIndex</tt>, the range to be sorted is empty.)<p>
     *
     * The sorting algorithm is a tuned quicksort, adapted from Jon
     * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
     * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
     * 1993).  This algorithm offers n*log(n) performance on many data sets
     * that cause other quicksorts to degrade to quadratic performance.
     *
     * @param a the array to be sorted.
     * @param fromIndex the index of the first element (inclusive) to be
     *        sorted.
     * @param toIndex the index of the last element (exclusive) to be sorted.
     * @throws IllegalArgumentException if <tt>fromIndex &gt; toIndex</tt>
     * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or
     *          <tt>toIndex &gt; a.length</tt>
     */
    public static int[] sortRetain(byte[] a, int fromIndex, int toIndex) {
        rangeCheck(a.length, fromIndex, toIndex);
        int[] pos = getPosArray(a.length, fromIndex);
        sort1(a, pos, fromIndex, toIndex - fromIndex);
        return pos;
    }

    /**
     * Sorts the specified array of doubles into ascending numerical order.
     * The sorting algorithm is a tuned quicksort, adapted from Jon
     * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
     * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
     * 1993).  This algorithm offers n*log(n) performance on many data sets
     * that cause other quicksorts to degrade to quadratic performance.
     *
     * @param a the array to be sorted.
     */
    public static int[] sortRetain(double[] a) {
        int[] pos = getPosArray(a.length);
        sort2(a, pos, 0, a.length);
        return pos;
    }

    /**
     * Sorts the specified range of the specified array of doubles into
     * ascending numerical order.  The range to be sorted extends from index
     * <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive.
     * (If <tt>fromIndex==toIndex</tt>, the range to be sorted is empty.)<p>
     *
     * The sorting algorithm is a tuned quicksort, adapted from Jon
     * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
     * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
     * 1993).  This algorithm offers n*log(n) performance on many data sets
     * that cause other quicksorts to degrade to quadratic performance.
     *
     * @param a the array to be sorted.
     * @param fromIndex the index of the first element (inclusive) to be
     *        sorted.
     * @param toIndex the index of the last element (exclusive) to be sorted.
     * @throws IllegalArgumentException if <tt>fromIndex &gt; toIndex</tt>
     * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or
     *          <tt>toIndex &gt; a.length</tt>
     */
    public static int[] sortRetain(double[] a, int fromIndex, int toIndex) {
        rangeCheck(a.length, fromIndex, toIndex);
        int[] pos = getPosArray(a.length, fromIndex);
        sort2(a, pos, fromIndex, toIndex - fromIndex);
        return pos;
    }

    /**
     * Sorts the specified array of floats into ascending numerical order.
     * The sorting algorithm is a tuned quicksort, adapted from Jon
     * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
     * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
     * 1993).  This algorithm offers n*log(n) performance on many data sets
     * that cause other quicksorts to degrade to quadratic performance.
     *
     * @param a the array to be sorted.
     */
    public static int[] sortRetain(float[] a) {
        int[] pos = getPosArray(a.length);
        sort2(a, pos, 0, a.length);
        return pos;
    }

    /**
     * Sorts the specified range of the specified array of floats into
     * ascending numerical order.  The range to be sorted extends from index
     * <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive.
     * (If <tt>fromIndex==toIndex</tt>, the range to be sorted is empty.)<p>
     *
     * The sorting algorithm is a tuned quicksort, adapted from Jon
     * L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
     * Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
     * 1993).  This algorithm offers n*log(n) performance on many data sets
     * that cause other quicksorts to degrade to quadratic performance.
     *
     * @param a the array to be sorted.
     * @param fromIndex the index of the first element (inclusive) to be
     *        sorted.
     * @param toIndex the index of the last element (exclusive) to be sorted.
     * @throws IllegalArgumentException if <tt>fromIndex &gt; toIndex</tt>
     * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or
     *          <tt>toIndex &gt; a.length</tt>
     */
    public static int[] sortRetain(float[] a, int fromIndex, int toIndex) {
        rangeCheck(a.length, fromIndex, toIndex);
        int[] pos = getPosArray(a.length, fromIndex);
        sort2(a, pos, fromIndex, toIndex - fromIndex);
        return pos;
    }

    /**
     * Creates a new int array with values from 0 to array size - 1
     */
    private static int[] getPosArray(int size) {
        int[] pos = new int[size];
        for (int i = 0; i < size; i++)
            pos[i] = i;

        return pos;
    }

    /**
     * Creates a new int array of a certain size and fills it with 
     * values from start to start + size - 1
     */
    private static int[] getPosArray(int size, int start) {
        int[] pos = new int[size];
        for (int i = 0; i < size; i++)
            pos[i] = start + i;

        return pos;
    }

    /**
     * Sorts the specified sub-array of longs into ascending order.
     */
    private static void sort1(long x[], int[] y, int off, int len) {
        // Insertion sort on smallest arrays
        if (len < 7) {
            for (int i = off; i < len + off; i++)
                for (int j = i; j > off && x[j - 1] > x[j]; j--)
                    swap(x, y, j, j - 1);
            return;
        }

        // Choose a partition element, v
        int m = off + len / 2; // Small arrays, middle element
        if (len > 7) {
            int l = off;
            int n = off + len - 1;
            if (len > 40) { // Big arrays, pseudomedian of 9
                int s = len / 8;
                l = med3(x, l, l + s, l + 2 * s);
                m = med3(x, m - s, m, m + s);
                n = med3(x, n - 2 * s, n - s, n);
            }
            m = med3(x, l, m, n); // Mid-size, med of 3
        }
        long v = x[m];

        // Establish Invariant: v* (<v)* (>v)* v*
        int a = off, b = a, c = off + len - 1, d = c;
        while (true) {
            while (b <= c && x[b] <= v) {
                if (x[b] == v)
                    swap(x, y, a++, b);
                b++;
            }
            while (c >= b && x[c] >= v) {
                if (x[c] == v)
                    swap(x, y, c, d--);
                c--;
            }
            if (b > c)
                break;
            swap(x, y, b++, c--);
        }

        // Swap partition elements back to middle
        int s, n = off + len;
        s = Math.min(a - off, b - a);
        vecswap(x, y, off, b - s, s);
        s = Math.min(d - c, n - d - 1);
        vecswap(x, y, b, n - s, s);

        // Recursively sort non-partition-elements
        if ((s = b - a) > 1)
            sort1(x, y, off, s);
        if ((s = d - c) > 1)
            sort1(x, y, n - s, s);
    }

    /**
     * Sorts the specified sub-array of integers into ascending order.
     */
    private static void sort1(int x[], int[] y, int off, int len) {
        // Insertion sort on smallest arrays
        if (len < 7) {
            for (int i = off; i < len + off; i++)
                for (int j = i; j > off && x[j - 1] > x[j]; j--)
                    swap(x, y, j, j - 1);
            return;
        }

        // Choose a partition element, v
        int m = off + len / 2; // Small arrays, middle element
        if (len > 7) {
            int l = off;
            int n = off + len - 1;
            if (len > 40) { // Big arrays, pseudomedian of 9
                int s = len / 8;
                l = med3(x, l, l + s, l + 2 * s);
                m = med3(x, m - s, m, m + s);
                n = med3(x, n - 2 * s, n - s, n);
            }
            m = med3(x, l, m, n); // Mid-size, med of 3
        }
        int v = x[m];

        // Establish Invariant: v* (<v)* (>v)* v*
        int a = off, b = a, c = off + len - 1, d = c;
        while (true) {
            while (b <= c && x[b] <= v) {
                if (x[b] == v)
                    swap(x, y, a++, b);
                b++;
            }
            while (c >= b && x[c] >= v) {
                if (x[c] == v)
                    swap(x, y, c, d--);
                c--;
            }
            if (b > c)
                break;
            swap(x, y, b++, c--);
        }

        // Swap partition elements back to middle
        int s, n = off + len;
        s = Math.min(a - off, b - a);
        vecswap(x, y, off, b - s, s);
        s = Math.min(d - c, n - d - 1);
        vecswap(x, y, b, n - s, s);

        // Recursively sort non-partition-elements
        if ((s = b - a) > 1)
            sort1(x, y, off, s);
        if ((s = d - c) > 1)
            sort1(x, y, n - s, s);
    }

    /**
     * Sorts the specified sub-array of shorts into ascending order.
     */
    private static void sort1(short x[], int[] y, int off, int len) {
        // Insertion sort on smallest arrays
        if (len < 7) {
            for (int i = off; i < len + off; i++)
                for (int j = i; j > off && x[j - 1] > x[j]; j--)
                    swap(x, y, j, j - 1);
            return;
        }

        // Choose a partition element, v
        int m = off + len / 2; // Small arrays, middle element
        if (len > 7) {
            int l = off;
            int n = off + len - 1;
            if (len > 40) { // Big arrays, pseudomedian of 9
                int s = len / 8;
                l = med3(x, l, l + s, l + 2 * s);
                m = med3(x, m - s, m, m + s);
                n = med3(x, n - 2 * s, n - s, n);
            }
            m = med3(x, l, m, n); // Mid-size, med of 3
        }
        short v = x[m];

        // Establish Invariant: v* (<v)* (>v)* v*
        int a = off, b = a, c = off + len - 1, d = c;
        while (true) {
            while (b <= c && x[b] <= v) {
                if (x[b] == v)
                    swap(x, y, a++, b);
                b++;
            }
            while (c >= b && x[c] >= v) {
                if (x[c] == v)
                    swap(x, y, c, d--);
                c--;
            }
            if (b > c)
                break;
            swap(x, y, b++, c--);
        }

        // Swap partition elements back to middle
        int s, n = off + len;
        s = Math.min(a - off, b - a);
        vecswap(x, y, off, b - s, s);
        s = Math.min(d - c, n - d - 1);
        vecswap(x, y, b, n - s, s);

        // Recursively sort non-partition-elements
        if ((s = b - a) > 1)
            sort1(x, y, off, s);
        if ((s = d - c) > 1)
            sort1(x, y, n - s, s);
    }

    /**
     * Sorts the specified sub-array of chars into ascending order.
     */
    private static void sort1(char x[], int[] y, int off, int len) {
        // Insertion sort on smallest arrays
        if (len < 7) {
            for (int i = off; i < len + off; i++)
                for (int j = i; j > off && x[j - 1] > x[j]; j--)
                    swap(x, y, j, j - 1);
            return;
        }

        // Choose a partition element, v
        int m = off + len / 2; // Small arrays, middle element
        if (len > 7) {
            int l = off;
            int n = off + len - 1;
            if (len > 40) { // Big arrays, pseudomedian of 9
                int s = len / 8;
                l = med3(x, l, l + s, l + 2 * s);
                m = med3(x, m - s, m, m + s);
                n = med3(x, n - 2 * s, n - s, n);
            }
            m = med3(x, l, m, n); // Mid-size, med of 3
        }
        char v = x[m];

        // Establish Invariant: v* (<v)* (>v)* v*
        int a = off, b = a, c = off + len - 1, d = c;
        while (true) {
            while (b <= c && x[b] <= v) {
                if (x[b] == v)
                    swap(x, y, a++, b);
                b++;
            }
            while (c >= b && x[c] >= v) {
                if (x[c] == v)
                    swap(x, y, c, d--);
                c--;
            }
            if (b > c)
                break;
            swap(x, y, b++, c--);
        }

        // Swap partition elements back to middle
        int s, n = off + len;
        s = Math.min(a - off, b - a);
        vecswap(x, y, off, b - s, s);
        s = Math.min(d - c, n - d - 1);
        vecswap(x, y, b, n - s, s);

        // Recursively sort non-partition-elements
        if ((s = b - a) > 1)
            sort1(x, y, off, s);
        if ((s = d - c) > 1)
            sort1(x, y, n - s, s);
    }

    /**
     * Sorts the specified sub-array of bytes into ascending order.
     */
    private static void sort1(byte x[], int[] y, int off, int len) {
        // Insertion sort on smallest arrays
        if (len < 7) {
            for (int i = off; i < len + off; i++)
                for (int j = i; j > off && x[j - 1] > x[j]; j--)
                    swap(x, y, j, j - 1);
            return;
        }

        // Choose a partition element, v
        int m = off + len / 2; // Small arrays, middle element
        if (len > 7) {
            int l = off;
            int n = off + len - 1;
            if (len > 40) { // Big arrays, pseudomedian of 9
                int s = len / 8;
                l = med3(x, l, l + s, l + 2 * s);
                m = med3(x, m - s, m, m + s);
                n = med3(x, n - 2 * s, n - s, n);
            }
            m = med3(x, l, m, n); // Mid-size, med of 3
        }
        byte v = x[m];

        // Establish Invariant: v* (<v)* (>v)* v*
        int a = off, b = a, c = off + len - 1, d = c;
        while (true) {
            while (b <= c && x[b] <= v) {
                if (x[b] == v)
                    swap(x, y, a++, b);
                b++;
            }
            while (c >= b && x[c] >= v) {
                if (x[c] == v)
                    swap(x, y, c, d--);
                c--;
            }
            if (b > c)
                break;
            swap(x, y, b++, c--);
        }

        // Swap partition elements back to middle
        int s, n = off + len;
        s = Math.min(a - off, b - a);
        vecswap(x, y, off, b - s, s);
        s = Math.min(d - c, n - d - 1);
        vecswap(x, y, b, n - s, s);

        // Recursively sort non-partition-elements
        if ((s = b - a) > 1)
            sort1(x, y, off, s);
        if ((s = d - c) > 1)
            sort1(x, y, n - s, s);
    }

    /**
     * Sorts the specified sub-array of doubles into ascending order.
     */
    private static void sort1(double x[], int[] y, int off, int len) {
        // Insertion sort on smallest arrays
        if (len < 7) {
            for (int i = off; i < len + off; i++)
                for (int j = i; j > off && x[j - 1] > x[j]; j--)
                    swap(x, y, j, j - 1);
            return;
        }

        // Choose a partition element, v
        int m = off + len / 2; // Small arrays, middle element
        if (len > 7) {
            int l = off;
            int n = off + len - 1;
            if (len > 40) { // Big arrays, pseudomedian of 9
                int s = len / 8;
                l = med3(x, l, l + s, l + 2 * s);
                m = med3(x, m - s, m, m + s);
                n = med3(x, n - 2 * s, n - s, n);
            }
            m = med3(x, l, m, n); // Mid-size, med of 3
        }
        double v = x[m];

        // Establish Invariant: v* (<v)* (>v)* v*
        int a = off, b = a, c = off + len - 1, d = c;
        while (true) {
            while (b <= c && x[b] <= v) {
                if (x[b] == v)
                    swap(x, y, a++, b);
                b++;
            }
            while (c >= b && x[c] >= v) {
                if (x[c] == v)
                    swap(x, y, c, d--);
                c--;
            }
            if (b > c)
                break;
            swap(x, y, b++, c--);
        }

        // Swap partition elements back to middle
        int s, n = off + len;
        s = Math.min(a - off, b - a);
        vecswap(x, y, off, b - s, s);
        s = Math.min(d - c, n - d - 1);
        vecswap(x, y, b, n - s, s);

        // Recursively sort non-partition-elements
        if ((s = b - a) > 1)
            sort1(x, y, off, s);
        if ((s = d - c) > 1)
            sort1(x, y, n - s, s);
    }

    /**
     * Sorts the specified sub-array of floats into ascending order.
     */
    private static void sort1(float x[], int[] y, int off, int len) {
        // Insertion sort on smallest arrays
        if (len < 7) {
            for (int i = off; i < len + off; i++)
                for (int j = i; j > off && x[j - 1] > x[j]; j--)
                    swap(x, y, j, j - 1);
            return;
        }

        // Choose a partition element, v
        int m = off + len / 2; // Small arrays, middle element
        if (len > 7) {
            int l = off;
            int n = off + len - 1;
            if (len > 40) { // Big arrays, pseudomedian of 9
                int s = len / 8;
                l = med3(x, l, l + s, l + 2 * s);
                m = med3(x, m - s, m, m + s);
                n = med3(x, n - 2 * s, n - s, n);
            }
            m = med3(x, l, m, n); // Mid-size, med of 3
        }
        float v = x[m];

        // Establish Invariant: v* (<v)* (>v)* v*
        int a = off, b = a, c = off + len - 1, d = c;
        while (true) {
            while (b <= c && x[b] <= v) {
                if (x[b] == v)
                    swap(x, y, a++, b);
                b++;
            }
            while (c >= b && x[c] >= v) {
                if (x[c] == v)
                    swap(x, y, c, d--);
                c--;
            }
            if (b > c)
                break;
            swap(x, y, b++, c--);
        }

        // Swap partition elements back to middle
        int s, n = off + len;
        s = Math.min(a - off, b - a);
        vecswap(x, y, off, b - s, s);
        s = Math.min(d - c, n - d - 1);
        vecswap(x, y, b, n - s, s);

        // Recursively sort non-partition-elements
        if ((s = b - a) > 1)
            sort1(x, y, off, s);
        if ((s = d - c) > 1)
            sort1(x, y, n - s, s);
    }

    /**
     * Check that fromIndex and toIndex are in range, and throw an
     * appropriate exception if they aren't.
     */
    private static void rangeCheck(int arrayLen, int fromIndex, int toIndex) {
        if (fromIndex > toIndex)
            throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
        if (fromIndex < 0)
            throw new ArrayIndexOutOfBoundsException(fromIndex);
        if (toIndex > arrayLen)
            throw new ArrayIndexOutOfBoundsException(toIndex);
    }

    private static void sort2(double a[], int[] y, int fromIndex, int toIndex) {
        final long NEG_ZERO_BITS = Double.doubleToLongBits(-0.0d);
        /*
         * The sort is done in three phases to avoid the expense of using
         * NaN and -0.0 aware comparisons during the main sort.
         */

        /*
         * Preprocessing phase:  Move any NaN's to end of array, count the
         * number of -0.0's, and turn them into 0.0's. 
         */
        int numNegZeros = 0;
        int i = fromIndex, n = toIndex;
        while (i < n) {
            if (a[i] != a[i]) {
                a[i] = a[--n];
                a[n] = Double.NaN;

                int o = y[i];
                y[i] = y[n];
                y[n] = o;
            } else {
                if (a[i] == 0 && Double.doubleToLongBits(a[i]) == NEG_ZERO_BITS) {
                    a[i] = 0.0d;
                    numNegZeros++;
                }
                i++;
            }
        }

        // Main sort phase: quicksort everything but the NaN's
        sort1(a, y, fromIndex, n - fromIndex);

        // Postprocessing phase: change 0.0's to -0.0's as required
        if (numNegZeros != 0) {
            int j = binarySearch(a, 0.0d, fromIndex, n - 1); // posn of ANY zero
            do {
                j--;
            } while (j >= 0 && a[j] == 0.0d);

            // j is now one less than the index of the FIRST zero
            for (int k = 0; k < numNegZeros; k++)
                a[++j] = -0.0d;
        }
    }

    private static void sort2(float a[], int[] y, int fromIndex, int toIndex) {
        final int NEG_ZERO_BITS = Float.floatToIntBits(-0.0f);
        /*
         * The sort is done in three phases to avoid the expense of using
         * NaN and -0.0 aware comparisons during the main sort.
         */

        /*
         * Preprocessing phase:  Move any NaN's to end of array, count the
         * number of -0.0's, and turn them into 0.0's. 
         */
        int numNegZeros = 0;
        int i = fromIndex, n = toIndex;
        while (i < n) {
            if (a[i] != a[i]) {
                a[i] = a[--n];
                a[n] = Float.NaN;

                int o = y[i];
                y[i] = y[n];
                y[n] = o;
            } else {
                if (a[i] == 0 && Float.floatToIntBits(a[i]) == NEG_ZERO_BITS) {
                    a[i] = 0.0f;
                    numNegZeros++;
                }
                i++;
            }
        }

        // Main sort phase: quicksort everything but the NaN's
        sort1(a, y, fromIndex, n - fromIndex);

        // Postprocessing phase: change 0.0's to -0.0's as required
        if (numNegZeros != 0) {
            int j = binarySearch(a, 0.0f, fromIndex, n - 1); // posn of ANY zero
            do {
                j--;
            } while (j >= 0 && a[j] == 0.0f);

            // j is now one less than the index of the FIRST zero
            for (int k = 0; k < numNegZeros; k++)
                a[++j] = -0.0f;
        }
    }

    /**
     * Swaps x[a] with x[b].
     */
    private static void swap(long x[], int[] y, int a, int b) {
        long t = x[a];
        x[a] = x[b];
        x[b] = t;

        int o = y[a];
        y[a] = y[b];
        y[b] = o;
    }

    /**
     * Swaps x[a] with x[b].
     */
    private static void swap(int x[], int[] y, int a, int b) {
        int t = x[a];
        x[a] = x[b];
        x[b] = t;

        int o = y[a];
        y[a] = y[b];
        y[b] = o;
    }

    /**
     * Swaps x[a] with x[b].
     */
    private static void swap(short x[], int[] y, int a, int b) {
        short t = x[a];
        x[a] = x[b];
        x[b] = t;

        int o = y[a];
        y[a] = y[b];
        y[b] = o;
    }

    /**
     * Swaps x[a] with x[b].
     */
    private static void swap(char x[], int[] y, int a, int b) {
        char t = x[a];
        x[a] = x[b];
        x[b] = t;

        int o = y[a];
        y[a] = y[b];
        y[b] = o;
    }

    /**
     * Swaps x[a] with x[b].
     */
    private static void swap(byte x[], int[] y, int a, int b) {
        byte t = x[a];
        x[a] = x[b];
        x[b] = t;

        int o = y[a];
        y[a] = y[b];
        y[b] = o;
    }

    /**
     * Swaps x[a] with x[b].
     */
    private static void swap(double x[], int[] y, int a, int b) {
        double t = x[a];
        x[a] = x[b];
        x[b] = t;

        int o = y[a];
        y[a] = y[b];
        y[b] = o;
    }

    /**
     * Swaps x[a] with x[b].
     */
    private static void swap(float x[], int[] y, int a, int b) {
        float t = x[a];
        x[a] = x[b];
        x[b] = t;

        int o = y[a];
        y[a] = y[b];
        y[b] = o;
    }

    /**
     * Returns the index of the median of the three indexed longs.
     */
    private static int med3(long x[], int a, int b, int c) {
        return (x[a] < x[b] ? (x[b] < x[c] ? b : x[a] < x[c] ? c : a) : (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
    }

    /**
     * Returns the index of the median of the three indexed integers.
     */
    private static int med3(int x[], int a, int b, int c) {
        return (x[a] < x[b] ? (x[b] < x[c] ? b : x[a] < x[c] ? c : a) : (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
    }

    /**
     * Returns the index of the median of the three indexed shorts.
     */
    private static int med3(short x[], int a, int b, int c) {
        return (x[a] < x[b] ? (x[b] < x[c] ? b : x[a] < x[c] ? c : a) : (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
    }

    /**
     * Returns the index of the median of the three indexed chars.
     */
    private static int med3(char x[], int a, int b, int c) {
        return (x[a] < x[b] ? (x[b] < x[c] ? b : x[a] < x[c] ? c : a) : (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
    }

    /**
     * Returns the index of the median of the three indexed bytes.
     */
    private static int med3(byte x[], int a, int b, int c) {
        return (x[a] < x[b] ? (x[b] < x[c] ? b : x[a] < x[c] ? c : a) : (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
    }

    /**
     * Returns the index of the median of the three indexed doubles.
     */
    private static int med3(double x[], int a, int b, int c) {
        return (x[a] < x[b] ? (x[b] < x[c] ? b : x[a] < x[c] ? c : a) : (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
    }

    /**
     * Returns the index of the median of the three indexed floats.
     */
    private static int med3(float x[], int a, int b, int c) {
        return (x[a] < x[b] ? (x[b] < x[c] ? b : x[a] < x[c] ? c : a) : (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
    }

    /**
     * Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
     */
    private static void vecswap(long x[], int[] y, int a, int b, int n) {
        for (int i = 0; i < n; i++, a++, b++)
            swap(x, y, a, b);
    }

    /**
     * Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
     */
    private static void vecswap(int x[], int[] y, int a, int b, int n) {
        for (int i = 0; i < n; i++, a++, b++)
            swap(x, y, a, b);
    }

    /**
     * Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
     */
    private static void vecswap(short x[], int[] y, int a, int b, int n) {
        for (int i = 0; i < n; i++, a++, b++)
            swap(x, y, a, b);
    }

    /**
     * Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
     */
    private static void vecswap(char x[], int[] y, int a, int b, int n) {
        for (int i = 0; i < n; i++, a++, b++)
            swap(x, y, a, b);
    }

    /**
     * Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
     */
    private static void vecswap(byte x[], int[] y, int a, int b, int n) {
        for (int i = 0; i < n; i++, a++, b++)
            swap(x, y, a, b);
    }

    /**
     * Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
     */
    private static void vecswap(double x[], int[] y, int a, int b, int n) {
        for (int i = 0; i < n; i++, a++, b++)
            swap(x, y, a, b);
    }

    /**
     * Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
     */
    private static void vecswap(float x[], int[] y, int a, int b, int n) {
        for (int i = 0; i < n; i++, a++, b++)
            swap(x, y, a, b);
    }

    /**
     * Searches the specified array of doubles for the specified value using
     * the binary search algorithm.  The array <strong>must</strong> be sorted
     * (as by the <tt>sort</tt> method, above) prior to making this call.  If
     * it is not sorted, the results are undefined.  If the array contains
     * multiple elements with the specified value, there is no guarantee which
     * one will be found.
     *
     * @param a the array to be searched.
     * @param key the value to be searched for.
     * @return index of the search key, if it is contained in the list;
     *          otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>.  The
     *          <i>insertion point</i> is defined as the point at which the
     *          key would be inserted into the list: the index of the first
     *          element greater than the key, or <tt>list.size()</tt>, if all
     *          elements in the list are less than the specified key.  Note
     *          that this guarantees that the return value will be &gt;= 0 if
     *          and only if the key is found.
     * @see #sort(double[])
     */
    public static int binarySearch(double[] a, double key) {
        return binarySearch(a, key, 0, a.length - 1);
    }

    private static int binarySearch(double[] a, double key, int low, int high) {
        while (low <= high) {
            int mid = (low + high) / 2;
            double midVal = a[mid];

            int cmp;
            if (midVal < key) {
                cmp = -1; // Neither val is NaN, thisVal is smaller
            } else if (midVal > key) {
                cmp = 1; // Neither val is NaN, thisVal is larger
            } else {
                long midBits = Double.doubleToLongBits(midVal);
                long keyBits = Double.doubleToLongBits(key);
                cmp = (midBits == keyBits ? 0 : // Values are equal
                        (midBits < keyBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
                                1)); // (0.0, -0.0) or (NaN, !NaN)
            }

            if (cmp < 0)
                low = mid + 1;
            else if (cmp > 0)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1); // key not found.
    }

    /**
     * Searches the specified array of floats for the specified value using
     * the binary search algorithm.  The array <strong>must</strong> be sorted
     * (as by the <tt>sort</tt> method, above) prior to making this call.  If
     * it is not sorted, the results are undefined.  If the array contains
     * multiple elements with the specified value, there is no guarantee which
     * one will be found.
     *
     * @param a the array to be searched.
     * @param key the value to be searched for.
     * @return index of the search key, if it is contained in the list;
     *          otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>.  The
     *          <i>insertion point</i> is defined as the point at which the
     *          key would be inserted into the list: the index of the first
     *          element greater than the key, or <tt>list.size()</tt>, if all
     *          elements in the list are less than the specified key.  Note
     *          that this guarantees that the return value will be &gt;= 0 if
     *          and only if the key is found.
     * @see #sort(float[])
     */
    public static int binarySearch(float[] a, float key) {
        return binarySearch(a, key, 0, a.length - 1);
    }

    private static int binarySearch(float[] a, float key, int low, int high) {
        while (low <= high) {
            int mid = (low + high) / 2;
            float midVal = a[mid];

            int cmp;
            if (midVal < key) {
                cmp = -1; // Neither val is NaN, thisVal is smaller
            } else if (midVal > key) {
                cmp = 1; // Neither val is NaN, thisVal is larger
            } else {
                int midBits = Float.floatToIntBits(midVal);
                int keyBits = Float.floatToIntBits(key);
                cmp = (midBits == keyBits ? 0 : // Values are equal
                        (midBits < keyBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
                                1)); // (0.0, -0.0) or (NaN, !NaN)
            }

            if (cmp < 0)
                low = mid + 1;
            else if (cmp > 0)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1); // key not found.
    }
}

Related

  1. sortNullElements(Object[] array)
  2. sortPerm(final int[] w)
  3. sortPermutation(final int[] A)
  4. sortPixels(double[] data, int numPixel)
  5. sortPopup(Integer[] integers)
  6. sortReverseOrder(String[] strings)
  7. sortStringArray(String array[], boolean inplace)
  8. sortStringArray(String[] array)
  9. sortStringArray(String[] array)