Java Array Sort sort(int[] array)

Here you can find the source of sort(int[] array)

Description

Sorts a given array of integers in ascending order and returns an array of integers with the positions of the elements of the original array in the sorted array.

License

Open Source License

Parameter

Parameter Description
array this array is not changed by the method!

Return

an array of integers with the positions in the sorted array.

Declaration

public static  int[] sort(int[] array) 

Method Source Code

//package com.java2s;
/*//w ww . j  a  va2 s  .  co  m
 *   This program 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.
 *
 *   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 */

public class Main {
    /**
     * Sorts a given array of integers in ascending order and returns an 
     * array of integers with the positions of the elements of the original 
     * array in the sorted array. The sort is stable. (Equal elements remain
     * in their original order.)
     *
     * @param array this array is not changed by the method!
     * @return an array of integers with the positions in the sorted
     * array.
     */
    public static /*@pure@*/ int[] sort(int[] array) {

        int[] index = initialIndex(array.length);
        int[] newIndex = new int[array.length];
        int[] helpIndex;
        int numEqual;

        quickSort(array, index, 0, array.length - 1);

        // Make sort stable
        int i = 0;
        while (i < index.length) {
            numEqual = 1;
            for (int j = i + 1; ((j < index.length) && (array[index[i]] == array[index[j]])); j++) {
                numEqual++;
            }
            if (numEqual > 1) {
                helpIndex = new int[numEqual];
                for (int j = 0; j < numEqual; j++) {
                    helpIndex[j] = i + j;
                }
                quickSort(index, helpIndex, 0, numEqual - 1);
                for (int j = 0; j < numEqual; j++) {
                    newIndex[i + j] = index[helpIndex[j]];
                }
                i += numEqual;
            } else {
                newIndex[i] = index[i];
                i++;
            }
        }
        return newIndex;
    }

    /**
     * Sorts a given array of doubles in ascending order and returns an
     * array of integers with the positions of the elements of the
     * original array in the sorted array. NOTE THESE CHANGES: the sort
     * is no longer stable and it doesn't use safe floating-point
     * comparisons anymore. Occurrences of Double.NaN are treated as 
     * Double.MAX_VALUE.
     *
     * @param array this array is not changed by the method!
     * @return an array of integers with the positions in the sorted
     * array.  
     */
    public static /*@pure@*/ int[] sort(/*@non_null@*/ double[] array) {

        int[] index = initialIndex(array.length);
        if (array.length > 1) {
            array = (double[]) array.clone();
            replaceMissingWithMAX_VALUE(array);
            quickSort(array, index, 0, array.length - 1);
        }
        return index;
    }

    /**
     * Initial index, filled with values from 0 to size - 1.
     */
    private static int[] initialIndex(int size) {

        int[] index = new int[size];
        for (int i = 0; i < size; i++) {
            index[i] = i;
        }
        return index;
    }

    /**
     * Implements quicksort with median-of-three method and explicit sort for
     * problems of size three or less. 
     *
     * @param array the array of doubles to be sorted
     * @param index the index into the array of doubles
     * @param left the first index of the subset to be sorted
     * @param right the last index of the subset to be sorted
     */
    //@ requires 0 <= first && first <= right && right < array.length;
    //@ requires (\forall int i; 0 <= i && i < index.length; 0 <= index[i] && index[i] < array.length);
    //@ requires array != index;
    //  assignable index;
    private static void quickSort(/*@non_null@*/ double[] array, /*@non_null@*/ int[] index, int left, int right) {

        int diff = right - left;

        switch (diff) {
        case 0:

            // No need to do anything
            return;
        case 1:

            // Swap two elements if necessary
            conditionalSwap(array, index, left, right);
            return;
        case 2:

            // Just need to sort three elements
            conditionalSwap(array, index, left, left + 1);
            conditionalSwap(array, index, left, right);
            conditionalSwap(array, index, left + 1, right);
            return;
        default:

            // Establish pivot
            int pivotLocation = sortLeftRightAndCenter(array, index, left, right);

            // Move pivot to the right, partition, and restore pivot
            swap(index, pivotLocation, right - 1);
            int center = partition(array, index, left, right, array[index[right - 1]]);
            swap(index, center, right - 1);

            // Sort recursively
            quickSort(array, index, left, center - 1);
            quickSort(array, index, center + 1, right);
        }
    }

    /**
     * Implements quicksort according to Manber's "Introduction to
     * Algorithms".
     *
     * @param array the array of integers to be sorted
     * @param index the index into the array of integers
     * @param left the first index of the subset to be sorted
     * @param right the last index of the subset to be sorted
     */
    //@ requires 0 <= first && first <= right && right < array.length;
    //@ requires (\forall int i; 0 <= i && i < index.length; 0 <= index[i] && index[i] < array.length);
    //@ requires array != index;
    //  assignable index;
    private static void quickSort(/*@non_null@*/ int[] array, /*@non_null@*/ int[] index, int left, int right) {

        if (left < right) {
            int middle = partition(array, index, left, right);
            quickSort(array, index, left, middle);
            quickSort(array, index, middle + 1, right);
        }
    }

    /**
     * Replaces all "missing values" in the given array of double values with
     * MAX_VALUE.
     *
     * @param array the array to be modified.
     */
    public static void replaceMissingWithMAX_VALUE(double[] array) {

        for (int i = 0; i < array.length; i++) {
            if (isMissingValue(array[i])) {
                array[i] = Double.MAX_VALUE;
            }
        }
    }

    /**
     * Conditional swap for quick sort.
     */
    private static void conditionalSwap(double[] array, int[] index, int left, int right) {

        if (array[index[left]] > array[index[right]]) {
            int help = index[left];
            index[left] = index[right];
            index[right] = help;
        }
    }

    /**
     * Sorts left, right, and center elements only, returns resulting center as pivot.
     */
    private static int sortLeftRightAndCenter(double[] array, int[] index, int l, int r) {

        int c = (l + r) / 2;
        conditionalSwap(array, index, l, c);
        conditionalSwap(array, index, l, r);
        conditionalSwap(array, index, c, r);
        return c;
    }

    /**
     * Swaps two elements in the given integer array.
     */
    private static void swap(int[] index, int l, int r) {

        int help = index[l];
        index[l] = index[r];
        index[r] = help;
    }

    /**
     * Partitions the instances around a pivot. Used by quicksort and
     * kthSmallestValue.
     *
     * @param array the array of doubles to be sorted
     * @param index the index into the array of doubles
     * @param l the first index of the subset 
     * @param r the last index of the subset 
     *
     * @return the index of the middle element
     */
    private static int partition(double[] array, int[] index, int l, int r, double pivot) {

        r--;
        while (true) {
            while ((array[index[++l]] < pivot))
                ;
            while ((array[index[--r]] > pivot))
                ;
            if (l >= r) {
                return l;
            }
            swap(index, l, r);
        }
    }

    /**
     * Partitions the instances around a pivot. Used by quicksort and
     * kthSmallestValue.
     *
     * @param array the array of integers to be sorted
     * @param index the index into the array of integers
     * @param l the first index of the subset 
     * @param r the last index of the subset 
     *
     * @return the index of the middle element
     */
    private static int partition(int[] array, int[] index, int l, int r) {

        double pivot = array[index[(l + r) / 2]];
        int help;

        while (l < r) {
            while ((array[index[l]] < pivot) && (l < r)) {
                l++;
            }
            while ((array[index[r]] > pivot) && (l < r)) {
                r--;
            }
            if (l < r) {
                help = index[l];
                index[l] = index[r];
                index[r] = help;
                l++;
                r--;
            }
        }
        if ((l == r) && (array[index[r]] > pivot)) {
            r--;
        }

        return r;
    }

    /**
     * Tests if the given value codes "missing".
     *
     * @param val the value to be tested
     * @return true if val codes "missing"
     */
    public static boolean isMissingValue(double val) {

        return Double.isNaN(val);
    }
}

Related

  1. Sort(float cais[])
  2. sort(int v[], int left, int right)
  3. sort(int values[])
  4. sort(int[] array)
  5. sort(int[] array)
  6. sort(int[] array)
  7. sort(int[] array)
  8. sort(int[] array)
  9. sort(int[] asd)