Here you can find the source of sort(int[] array)
Parameter | Description |
---|---|
array | this array is not changed by the method! |
public static int[] sort(int[] array)
//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); } }