Java Quick Sort quickSort(int[] target, int[] coSort)

Here you can find the source of quickSort(int[] target, int[] coSort)

Description

Sorts the specified target array of ints into ascending numerical order and simultaneously permutes the coSort ints array in the same way then specified target array.

License

Open Source License

Parameter

Parameter Description
target the array to be sorted
coSort the array, which will be permuted in the same way, then the specified target array, during sorting procedure

Exception

Parameter Description
IllegalArgumentException if target == coSort (as references).

Declaration

public static void quickSort(int[] target, int[] coSort) 

Method Source Code

//package com.java2s;
/*//  w  w  w  .  j a  va  2  s.c  o m
 * Redberry: symbolic tensor computations.
 *
 * Copyright (c) 2010-2013:
 *   Stanislav Poslavsky   <stvlpos@mail.ru>
 *   Bolotin Dmitriy       <bolotin.dmitriy@gmail.com>
 *
 * This file is part of Redberry.
 *
 * Redberry is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Redberry 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Redberry. If not, see <http://www.gnu.org/licenses/>.
 */

public class Main {
    /**
     * Sorts the specified target array of ints into ascending numerical order and simultaneously permutes the {@code
     * coSort} ints array in the same way then specified target array. <p/> The code was taken from the jdk6 Arrays
     * class. <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. <p/> <p><b>NOTE: remember this is unstable sort algorithm, so additional combinatorics of the {@code
     * coSort} array can be perfomed. Use this method only if you are sure, in what you are doing. If not - use stable
     * sort methods like an insertion sort or Tim sort.</b> <p/> <p><b>NOTE:</b> The method throws {@code
     * IllegalArgumentException} if {@code target == coSort}, because in this case no sorting will be perfomed.
     *
     * @param target the array to be sorted
     * @param coSort the array, which will be permuted in the same way, then the specified target array, during sorting
     *               procedure
     * @throws IllegalArgumentException if coSort length less then target length.
     * @throws IllegalArgumentException if target == coSort (as references).
     */
    public static void quickSort(int[] target, int[] coSort) {
        quickSort(target, 0, target.length, coSort);
    }

    /**
     * Sorts the specified range of the specified target array of ints into ascending numerical order and simultaneously
     * permutes the {@code coSort} ints array in the same way then specified target array. 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> <p/> The code was taken from the jdk6 Arrays
     * class. <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. <p/> <p><b>NOTE: remember this is unstable sort algorithm, so additional combinatorics of the {@code
     * coSort} array can be perfomed. Use this method only if you are sure, in what you are doing. If not - use stable
     * sort methods like an insertion sort or Tim sort.</b> <p/> <p><b>NOTE:</b> The method throws {@code
     * IllegalArgumentException} if {@code target == coSort}, because in this case no sorting will be perfomed.
     *
     * @param target    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
     * @param coSort    the array, which will be permuted in the same way, then the specified target array, during
     *                  sorting procedure
     * @throws IllegalArgumentException       if <tt>fromIndex &gt; toIndex</tt>
     * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or <tt>toIndex &gt; target.length</tt> or
     *                                        <tt>toIndex &gt; coSort.length</tt>
     * @throws IllegalArgumentException       if target == coSort (as references).
     */
    public static void quickSort(int[] target, int fromIndex, int toIndex, int[] coSort) {
        rangeCheck(target.length, fromIndex, toIndex);
        rangeCheck(coSort.length, fromIndex, toIndex);
        quickSort1(target, fromIndex, toIndex - fromIndex, coSort);
    }

    /**
     * Sorts the specified target array of ints into ascending numerical order and simultaneously permutes the {@code
     * coSort} longs array in the same way then specified target array. <p/> The code was taken from the jdk6 Arrays
     * class. <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. <p/> <p/> <p><b>NOTE: this is unstable sort algorithm, so additional combinatorics of the {@code
     * coSort} array can be perfomed. Use this method only if you are sure, in what you are doing. If not - use stable
     * sort methods like an insertion sort or Tim sort.</b>
     *
     * @param target the array to be sorted
     * @param coSort the array, which will be permuted in the same way, then the specified target array, during sorting
     *               procedure
     * @throws IllegalArgumentException if coSort length less then target length.
     */
    public static void quickSort(int[] target, long[] coSort) {
        quickSort1(target, 0, target.length, coSort);
    }

    /**
     * Sorts the specified range of the specified target array of ints into ascending numerical order and simultaneously
     * permutes the {@code coSort} longs array in the same way then specified target array. 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> <p/> The code was taken from the jdk6 Arrays
     * class. <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. <p/> <p/> <p><b>NOTE: this is unstable sort algorithm, so additional combinatorics of the {@code
     * coSort} array can be performed. Use this method only if you are sure, in what you are doing. If not - use stable
     * sort methods like an insertion sort or Tim sort.</b>
     *
     * @param target    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
     * @param coSort    the array, which will be permuted in the same way, then the specified target array, during
     *                  sorting procedure
     * @throws IllegalArgumentException       if <tt>fromIndex &gt; toIndex</tt>
     * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or <tt>toIndex &gt; target.length</tt> or
     *                                        <tt>toIndex &gt; coSort.length</tt>
     */
    public static void quickSort(int[] target, int fromIndex, int toIndex, long[] coSort) {
        rangeCheck(target.length, fromIndex, toIndex);
        rangeCheck(coSort.length, fromIndex, toIndex);
        quickSort1(target, fromIndex, toIndex - fromIndex, coSort);
    }

    /**
     * Sorts the specified target array of objects into ascending order, according to the natural ordering of its
     * elements and simultaneously permutes the {@code coSort} objects array in the same way then specified target
     * array. <p/> The code was taken from the jdk6 Arrays class. <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. <p/> <p><b>NOTE: this is unstable sort
     * algorithm, so additional combinatorics of the {@code coSort} array can be perfomed. Use this method only if you
     * are sure, in what you are doing. If not - use stable sort methods like an insertion sort or Tim sort.</b>
     *
     * @param target the array to be sorted
     * @param coSort the array, which will be permuted in the same way, then the specified target array, during sorting
     *               procedure
     * @throws IllegalArgumentException if <tt>fromIndex &gt; toIndex</tt>
     * @throws IllegalArgumentException if coSort length less then target length.
     * @throws IllegalArgumentException if target == coSort (as references).
     */
    public static <T extends Comparable<T>> void quickSort(T[] target, Object[] coSort) {
        quickSort(target, 0, target.length, coSort);
    }

    /**
     * Sorts the specified target array of objects into ascending order, according to the natural ordering of its
     * elements and simultaneously permutes the {@code coSort} objects array in the same way then specified target
     * array. 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> <p/> The code was taken from the
     * jdk6 Arrays class. <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. <p/> <p><b>NOTE: this is unstable sort algorithm, so additional combinatorics of the
     * {@code coSort} array can be perfomed. Use this method only if you are sure, in what you are doing. If not - use
     * stable sort methods like an insertion sort or Tim sort.</b>
     *
     * @param target    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
     * @param coSort    the array, which will be permuted in the same way, then the specified target array, during
     *                  sorting procedure
     * @throws IllegalArgumentException       if <tt>fromIndex &gt; toIndex</tt>
     * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or <tt>toIndex &gt; target.length</tt> or
     *                                        <tt>toIndex &gt; coSort.length</tt>
     * @throws IllegalArgumentException       if target == coSort (as references).
     */
    public static <T extends Comparable<T>> void quickSort(T[] target, int fromIndex, int toIndex,
            Object[] coSort) {
        if (target == coSort)
            throw new IllegalArgumentException();
        rangeCheck(target.length, fromIndex, toIndex);
        rangeCheck(coSort.length, fromIndex, toIndex);
        quickSort1(target, fromIndex, toIndex - fromIndex, coSort);
    }

    /**
     * Sorts the specified target array of ints into ascending numerical order and simultaneously permutes the {@code
     * coSort} Objects array in the same way then specified target array. <p/> The code was taken from the jdk6 Arrays
     * class. <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. <p/> <p/> <p><b>NOTE: this is unstable sort algorithm, so additional combinatorics of the {@code
     * coSort} array can be perfomed. Use this method only if you are sure, in what you are doing. If not - use stable
     * sort methods like an insertion sort or Tim sort.</b>
     *
     * @param target the array to be sorted
     * @param coSort the array, which will be permuted in the same way, then the specified target array, during sorting
     *               procedure
     * @throws IllegalArgumentException if coSort length less then target length.
     */
    public static void quickSort(int[] target, Object[] coSort) {
        quickSort1(target, 0, target.length, coSort);
    }

    /**
     * Sorts the specified range of the specified target array of ints into ascending numerical order and simultaneously
     * permutes the {@code coSort} Objects array in the same way then specified target array. 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> <p/> The code was taken from the jdk6 Arrays
     * class. <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. <p/> <p/> <p><b>NOTE: this is unstable sort algorithm, so additional combinatorics of the {@code
     * coSort} array can be perfomed. Use this method only if you are sure, in what you are doing. If not - use stable
     * sort methods like an insertion sort or Tim sort.</b>
     *
     * @param target    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
     * @param coSort    the array, which will be permuted in the same way, then the specified target array, during
     *                  sorting procedure
     * @throws IllegalArgumentException       if <tt>fromIndex &gt; toIndex</tt>
     * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or <tt>toIndex &gt; target.length</tt> or
     *                                        <tt>toIndex &gt; coSort.length</tt>
     */
    public static void quickSort(int[] target, int fromIndex, int toIndex, Object[] coSort) {
        rangeCheck(target.length, fromIndex, toIndex);
        rangeCheck(coSort.length, fromIndex, toIndex);
        quickSort1(target, fromIndex, toIndex - fromIndex, coSort);
    }

    /**
     * Sorts the specified target array of shorts into ascending numerical order and simultaneously permutes the {@code
     * coSort} ints array in the same way then specified target array. <p/> The code was taken from the jdk6 Arrays
     * class. <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. <p/> <p><b>NOTE: remember this is unstable sort algorithm, so additional combinatorics of the {@code
     * coSort} array can be perfomed. Use this method only if you are sure, in what you are doing. If not - use stable
     * sort methods like an insertion sort or Tim sort.</b> <p/> <p><b>NOTE:</b> The method throws {@code
     * IllegalArgumentException} if {@code target == coSort}, because in this case no sorting will be perfomed.
     *
     * @param target the array to be sorted
     * @param coSort the array, which will be permuted in the same way, then the specified target array, during sorting
     *               procedure
     * @throws IllegalArgumentException if coSort length less then target length.
     */
    public static void quickSort(short[] target, int[] coSort) {
        quickSort(target, 0, target.length, coSort);
    }

    /**
     * Sorts the specified range of the specified target array of ints into ascending numerical order and simultaneously
     * permutes the {@code coSort} ints array in the same way then specified target array. 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> <p/> The code was taken from the jdk6 Arrays
     * class. <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. <p/> <p><b>NOTE: remember this is unstable sort algorithm, so additional combinatorics of the {@code
     * coSort} array can be perfomed. Use this method only if you are sure, in what you are doing. If not - use stable
     * sort methods like an insertion sort or Tim sort.</b> <p/> <p><b>NOTE:</b> The method throws {@code
     * IllegalArgumentException} if {@code target == coSort}, because in this case no sorting will be perfomed.
     *
     * @param target    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
     * @param coSort    the array, which will be permuted in the same way, then the specified target array, during
     *                  sorting procedure
     * @throws IllegalArgumentException       if <tt>fromIndex &gt; toIndex</tt>
     * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or <tt>toIndex &gt; target.length</tt> or
     *                                        <tt>toIndex &gt; coSort.length</tt>
     */
    public static void quickSort(short[] target, int fromIndex, int toIndex, int[] coSort) {
        rangeCheck(target.length, fromIndex, toIndex);
        rangeCheck(coSort.length, fromIndex, toIndex);
        quickSort1(target, fromIndex, toIndex - fromIndex, coSort);
    }

    /**
     * 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);
    }

    /**
     * This method is the same as {@link #quickSort(int[], int, int, int[]) }, but without range checking and toIndex ->
     * length (see params). Throws {@code IllegalArgumentException} if {@code target == coSort}, because in this case no
     * sorting will be perfomed . <p/> <p><b>NOTE: this is unstable sort algorithm, so additional combinatorics of the
     * {@code coSort} array can be perfomed. Use this method only if you are sure, in what you are doing. If not - use
     * stable sort methods like an insertion sort or Tim sort.</b>
     *
     * @param target    the array to be sorted
     * @param fromIndex the index of the first element (inclusive) to be sorted
     * @param length    the length of the sorting subarray.
     * @param coSort    the array, which will be permuted in the same way, then the specified target array, during
     *                  sorting procedure
     * @throws IllegalArgumentException if target == coSort (as references).
     */
    public static void quickSort1(int target[], int fromIndex, int length, int[] coSort) {
        if (target == coSort)
            throw new IllegalArgumentException("Target reference == coSort reference.");
        quickSort2(target, fromIndex, length, coSort);
    }

    /**
     * This method is the same as {@link #quickSort(int[], int, int, long[])  ) }, but without range checking. <p/>
     * <p><b>NOTE: this is unstable sort algorithm, so additional combinatorics of the {@code coSort} array can be
     * performed. Use this method only if you are sure, in what you are doing. If not - use stable sort methods like an
     * insertion sort or Tim sort.</b>
     *
     * @param target    the array to be sorted
     * @param fromIndex the index of the first element (inclusive) to be sorted
     * @param length    the length of the sorting subarray.
     * @param coSort    the array, which will be permuted in the same way, then the specified target array, during
     *                  sorting procedure
     */
    public static void quickSort1(int target[], int fromIndex, int length, long[] coSort) {
        // Insertion quickSort on smallest arrays
        if (length < 7) {
            for (int i = fromIndex; i < length + fromIndex; i++)
                for (int j = i; j > fromIndex && target[j - 1] > target[j]; j--)
                    swap(target, j, j - 1, coSort);
            return;
        }

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

        // Establish Invariant: v* (<v)* (>v)* v*
        int a = fromIndex, b = a, c = fromIndex + length - 1, d = c;
        while (true) {
            while (b <= c && target[b] <= v) {
                if (target[b] == v)
                    swap(target, a++, b, coSort);
                b++;
            }
            while (c >= b && target[c] >= v) {
                if (target[c] == v)
                    swap(target, c, d--, coSort);
                c--;
            }
            if (b > c)
                break;
            swap(target, b++, c--, coSort);
        }

        // Swap partition elements back to middle
        int s, n = fromIndex + length;
        s = Math.min(a - fromIndex, b - a);
        vecswap(target, fromIndex, b - s, s, coSort);
        s = Math.min(d - c, n - d - 1);
        vecswap(target, b, n - s, s, coSort);

        // Recursively quickSort non-partition-elements
        if ((s = b - a) > 1)
            quickSort1(target, fromIndex, s, coSort);
        if ((s = d - c) > 1)
            quickSort1(target, n - s, s, coSort);

    }

    /**
     * This method is the same as {@link #quickSort(Comparable[], int, int, Object[])}, but without range checking.
     * <p/> <p><b>NOTE: this is unstable sort algorithm, so additional combinatorics of the {@code coSort} array can be
     * perfomed. Use this method only if you are sure, in what you are doing. If not - use stable sort methods like an
     * insertion sort or Tim sort.</b>
     *
     * @param target    the array to be sorted
     * @param fromIndex the index of the first element (inclusive) to be sorted
     * @param length    the length of the sorting subarray.
     * @param coSort    the array, which will be permuted in the same way, then the specified target array, during
     *                  sorting procedure
     * @throws IllegalArgumentException if target == coSort (as references).
     */
    public static <T extends Comparable<T>> void quickSort1(T[] target, int fromIndex, int length,
            Object[] coSort) {
        // Insertion quickSort on smallest arrays
        if (length < 7) {
            for (int i = fromIndex; i < length + fromIndex; i++)
                for (int j = i; j > fromIndex && target[j - 1].compareTo(target[j]) > 0; j--)
                    swap(target, j, j - 1, coSort);
            return;
        }

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

        // Establish Invariant: v* (<v)* (>v)* v*
        int a = fromIndex, b = a, c = fromIndex + length - 1, d = c;
        while (true) {
            while (b <= c && target[b].compareTo(v) <= 0) {
                if (target[b] == v)
                    swap(target, a++, b, coSort);
                b++;
            }
            while (c >= b && target[c].compareTo(v) >= 0) {
                if (target[c] == v)
                    swap(target, c, d--, coSort);
                c--;
            }
            if (b > c)
                break;
            swap(target, b++, c--, coSort);
        }

        // Swap partition elements back to middle
        int s, n = fromIndex + length;
        s = Math.min(a - fromIndex, b - a);
        vecswap(target, fromIndex, b - s, s, coSort);
        s = Math.min(d - c, n - d - 1);
        vecswap(target, b, n - s, s, coSort);

        // Recursively quickSort non-partition-elements
        if ((s = b - a) > 1)
            quickSort1(target, fromIndex, s, coSort);
        if ((s = d - c) > 1)
            quickSort1(target, n - s, s, coSort);

    }

    /**
     * This method is the same as {@link #quickSort(int[], int, int, Object[])  ) }, but without range checking. <p/>
     * <p><b>NOTE: this is unstable sort algorithm, so additional combinatorics of the {@code coSort} array can be
     * perfomed. Use this method only if you are sure, in what you are doing. If not - use stable sort methods like an
     * insertion sort or Tim sort.</b>
     *
     * @param target    the array to be sorted
     * @param fromIndex the index of the first element (inclusive) to be sorted
     * @param length    the length of the sorting subarray.
     * @param coSort    the array, which will be permuted in the same way, then the specified target array, during
     *                  sorting procedure
     */
    public static void quickSort1(int target[], int fromIndex, int length, Object[] coSort) {
        // Insertion quickSort on smallest arrays
        if (length < 7) {
            for (int i = fromIndex; i < length + fromIndex; i++)
                for (int j = i; j > fromIndex && target[j - 1] > target[j]; j--)
                    swap(target, j, j - 1, coSort);
            return;
        }

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

        // Establish Invariant: v* (<v)* (>v)* v*
        int a = fromIndex, b = a, c = fromIndex + length - 1, d = c;
        while (true) {
            while (b <= c && target[b] <= v) {
                if (target[b] == v)
                    swap(target, a++, b, coSort);
                b++;
            }
            while (c >= b && target[c] >= v) {
                if (target[c] == v)
                    swap(target, c, d--, coSort);
                c--;
            }
            if (b > c)
                break;
            swap(target, b++, c--, coSort);
        }

        // Swap partition elements back to middle
        int s, n = fromIndex + length;
        s = Math.min(a - fromIndex, b - a);
        vecswap(target, fromIndex, b - s, s, coSort);
        s = Math.min(d - c, n - d - 1);
        vecswap(target, b, n - s, s, coSort);

        // Recursively quickSort non-partition-elements
        if ((s = b - a) > 1)
            quickSort1(target, fromIndex, s, coSort);
        if ((s = d - c) > 1)
            quickSort1(target, n - s, s, coSort);

    }

    /**
     * This method is the same as {@link #quickSort(int[], int, int, int[]) }, but without range checking and toIndex ->
     * length (see params). Throws {@code IllegalArgumentException} if {@code target == coSort}, because in this case no
     * sorting will be perfomed . <p/> <p><b>NOTE: this is unstable sort algorithm, so additional combinatorics of the
     * {@code coSort} array can be perfomed. Use this method only if you are sure, in what you are doing. If not - use
     * stable sort methods like an insertion sort or Tim sort.</b>
     *
     * @param target    the array to be sorted
     * @param fromIndex the index of the first element (inclusive) to be sorted
     * @param length    the length of the sorting subarray.
     * @param coSort    the array, which will be permuted in the same way, then the specified target array, during
     *                  sorting procedure
     */
    public static void quickSort1(short target[], int fromIndex, int length, int[] coSort) {
        quickSort2(target, fromIndex, length, coSort);
    }

    private static void quickSort2(int target[], int fromIndex, int length, int[] coSort) {
        // Insertion quickSort on smallest arrays
        if (length < 7) {
            for (int i = fromIndex; i < length + fromIndex; i++)
                for (int j = i; j > fromIndex && target[j - 1] > target[j]; j--)
                    swap(target, j, j - 1, coSort);
            return;
        }

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

        // Establish Invariant: v* (<v)* (>v)* v*
        int a = fromIndex, b = a, c = fromIndex + length - 1, d = c;
        while (true) {
            while (b <= c && target[b] <= v) {
                if (target[b] == v)
                    swap(target, a++, b, coSort);
                b++;
            }
            while (c >= b && target[c] >= v) {
                if (target[c] == v)
                    swap(target, c, d--, coSort);
                c--;
            }
            if (b > c)
                break;
            swap(target, b++, c--, coSort);
        }

        // Swap partition elements back to middle
        int s, n = fromIndex + length;
        s = Math.min(a - fromIndex, b - a);
        vecswap(target, fromIndex, b - s, s, coSort);
        s = Math.min(d - c, n - d - 1);
        vecswap(target, b, n - s, s, coSort);

        // Recursively quickSort non-partition-elements
        if ((s = b - a) > 1)
            quickSort2(target, fromIndex, s, coSort);
        if ((s = d - c) > 1)
            quickSort2(target, n - s, s, coSort);

    }

    private static void quickSort2(short target[], int fromIndex, int length, int[] coSort) {
        // Insertion quickSort on smallest arrays
        if (length < 7) {
            for (int i = fromIndex; i < length + fromIndex; i++)
                for (int j = i; j > fromIndex && target[j - 1] > target[j]; j--)
                    swap(target, j, j - 1, coSort);
            return;
        }

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

        // Establish Invariant: v* (<v)* (>v)* v*
        int a = fromIndex, b = a, c = fromIndex + length - 1, d = c;
        while (true) {
            while (b <= c && target[b] <= v) {
                if (target[b] == v)
                    swap(target, a++, b, coSort);
                b++;
            }
            while (c >= b && target[c] >= v) {
                if (target[c] == v)
                    swap(target, c, d--, coSort);
                c--;
            }
            if (b > c)
                break;
            swap(target, b++, c--, coSort);
        }

        // Swap partition elements back to middle
        int s, n = fromIndex + length;
        s = Math.min(a - fromIndex, b - a);
        vecswap(target, fromIndex, b - s, s, coSort);
        s = Math.min(d - c, n - d - 1);
        vecswap(target, b, n - s, s, coSort);

        // Recursively quickSort non-partition-elements
        if ((s = b - a) > 1)
            quickSort2(target, fromIndex, s, coSort);
        if ((s = d - c) > 1)
            quickSort2(target, n - s, s, coSort);

    }

    private static void swap(int x[], int a, int b, int[] coSort) {
        swap(x, a, b);
        swap(coSort, a, b);
    }

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

    private static void swap(int x[], int a, int b, long[] coSort) {
        swap(x, a, b);
        swap(coSort, a, b);
    }

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

    private static void swap(Object[] x, int a, int b, Object[] coSort) {
        swap(x, a, b);
        swap(coSort, a, b);
    }

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

    private static void swap(int x[], int a, int b, Object[] coSort) {
        swap(x, a, b);
        swap(coSort, a, b);
    }

    private static void swap(short x[], int a, int b, int[] coSort) {
        swap(x, a, b);
        swap(coSort, a, b);
    }

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

    /**
     * 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));
    }

    private static <T extends Comparable<T>> int med3(T[] x, int a, int b, int c) {
        return (x[a].compareTo(x[b]) < 0 ? (x[b].compareTo(x[c]) < 0 ? b : x[a].compareTo(x[c]) < 0 ? c : a)
                : (x[b].compareTo(x[c]) > 0 ? b : x[a].compareTo(x[c]) > 0 ? c : a));
    }

    /**
     * Returns the index of the median of the three indexed integers.
     */
    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));
    }

    private static void vecswap(int x[], int a, int b, int n, int[] coSort) {
        for (int i = 0; i < n; i++, a++, b++)
            swap(x, a, b, coSort);
    }

    private static void vecswap(int x[], int a, int b, int n, long[] coSort) {
        for (int i = 0; i < n; i++, a++, b++)
            swap(x, a, b, coSort);
    }

    private static void vecswap(Object[] x, int a, int b, int n, Object[] coSort) {
        for (int i = 0; i < n; i++, a++, b++)
            swap(x, a, b, coSort);
    }

    private static void vecswap(int x[], int a, int b, int n, Object[] coSort) {
        for (int i = 0; i < n; i++, a++, b++)
            swap(x, a, b, coSort);
    }

    private static void vecswap(short x[], int a, int b, int n, int[] coSort) {
        for (int i = 0; i < n; i++, a++, b++)
            swap(x, a, b, coSort);
    }
}

Related

  1. quickSort(int[] array)
  2. quickSort(int[] array, int lo0, int hi0)
  3. quickSort(int[] array, int[] index, int lo0, int hi0)
  4. quicksort(int[] source)
  5. quickSort(int[] source)
  6. quickSort(int[] x)
  7. quickSort(int[] x)
  8. quickSort(short[] fireZoneInfo, int left, int right)
  9. quickSort(String a[], int lo0, int hi0)