Here you can find the source of sort(int[] keys, int[] values)
public static void sort(int[] keys, int[] values)
//package com.java2s; /**/*from w ww . ja va 2s . co m*/ * **************************************************************************** * Copyright (c) 2008 SAP AG. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * SAP AG - initial API and implementation * ***************************************************************************** */ public class Main { /** * Sorts the keys in an increasing order. Elements key[i] and values[i] are * always swapped together in the corresponding arrays. * <p> * A mixture of several sorting algorithms is used: * <p> * A radix sort performs better on the numeric data we sort, but requires * additional storage to perform the sorting. Therefore only the * not-very-large parts produced by a quick sort are sorted with radix sort. * An insertion sort is used to sort the smallest arrays, where the the * overhead of the radix sort is also bigger */ public static void sort(int[] keys, int[] values) { hybridsort(keys, values, 0, keys.length - 1); } /** * Sorts a range from the keys in an increasing order. Elements key[i] and * values[i] are always swapped together in the corresponding arrays. * <p> * A mixture of several sorting algorithms is used: * <p> * A radix sort performs better on the numeric data we sort, but requires * additional storage to perform the sorting. Therefore only the * not-very-large parts produced by a quick sort are sorted with radix sort. * An insertion sort is used to sort the smallest arrays, where the the * overhead of the radix sort is also bigger */ public static void sort(int[] keys, int[] values, int offset, int length) { hybridsort(keys, values, offset, offset + length - 1); } private static void hybridsort(int[] keys, int[] values, int left, int right) { while (right - left >= 1) { if (right - left < 5000000) { radixsort(keys, values, left, right - left + 1); break; } else { // split the array - the elements between i[0] and i[1] are // equal. // the elements on the left are smaller, on the right - bigger int[] i = split(keys, values, left, right); int sizeLeft = i[0] - left; int sizeRight = right - i[1]; // Limit recursion depth by doing the smaller side first if (sizeLeft <= sizeRight) { // sort all keys smaller than keys[i] hybridsort(keys, values, left, i[0] - 1); // then loop to do all keys bigger than keys[i] left = i[1] + 1; } else { // sort all keys bigger than keys[i] hybridsort(keys, values, i[1] + 1, right); // then loop to do all keys smaller than keys[i] right = i[0] - 1; } } } } private static void radixsort(int[] keys, int[] values, int offset, int length) { int[] tempKeys = new int[length]; int[] tempValues = new int[length]; countsort(keys, tempKeys, values, tempValues, offset, 0, length, 0); countsort(tempKeys, keys, tempValues, values, 0, offset, length, 1); countsort(keys, tempKeys, values, tempValues, offset, 0, length, 2); countsort(tempKeys, keys, tempValues, values, 0, offset, length, 3); } private static int[] split(int[] keys, int[] values, int left, int right) { // just take the median of the middle key and the two border keys int splittingIdx = median(keys, left, right, left + ((right - left) >> 1)); int splittingValue = keys[splittingIdx]; // move splitting element first swap(keys, values, left, splittingIdx); int i = left; int c = 0; // number of elements equal to splittingValue for (int j = left + 1; j <= right; j++) { if (keys[j] < splittingValue) { i++; swap(keys, values, i, j); // if there are duplicates, keep them next to each other if (c > 0) swap(keys, values, i + c, j); } else if (keys[j] == splittingValue) { c++; swap(keys, values, i + c, j); } } swap(keys, values, left, i); return new int[] { i, i + c }; } private static void countsort(int[] srcKeys, int[] destKeys, int[] srcValues, int[] destValues, int srcOffset, int trgOffset, int length, int sortByte) { int[] count = new int[256]; int[] index = new int[256]; int shiftBits = 8 * sortByte; int srcEnd = srcOffset + length; for (int i = srcOffset; i < srcEnd; i++) count[((srcKeys[i] >> (shiftBits)) & 0xff)]++; if (sortByte == 3) { // Sign byte, so sort 128..255 0..127 /* index[128] = 0 */ for (int i = 129; i < 256; i++) index[i] = index[i - 1] + count[i - 1]; index[0] = index[255] + count[255]; for (int i = 1; i < 128; i++) index[i] = index[i - 1] + count[i - 1]; } else { /* index[0] = 0 */ for (int i = 1; i < 256; i++) index[i] = index[i - 1] + count[i - 1]; } for (int i = srcOffset; i < srcEnd; i++) { int idx = ((srcKeys[i] >> (shiftBits)) & 0xff); destValues[trgOffset + index[idx]] = srcValues[i]; destKeys[trgOffset + index[idx]++] = srcKeys[i]; } } private static int median(int x[], int pos1, int pos2, int pos3) { int v1 = x[pos1]; int v2 = x[pos2]; int v3 = x[pos3]; if (v1 < v2) { if (v2 <= v3) { return pos2; } else { return v1 < v3 ? pos3 : pos1; } } /* else -> v1 > v2 */ if (v1 <= v3) { return pos1; } else { return v2 < v3 ? pos3 : pos2; } } private static int median(long x[], int pos1, int pos2, int pos3) { long v1 = x[pos1]; long v2 = x[pos2]; long v3 = x[pos3]; if (v1 < v2) { if (v2 <= v3) { return pos2; } else { return v1 < v3 ? pos3 : pos1; } } /* else -> v1 > v2 */ if (v1 <= v3) { return pos1; } else { return v2 < v3 ? pos3 : pos2; } } private static void swap(int keys[], int values[], int a, int b) { // swap the keys int tmp = keys[a]; keys[a] = keys[b]; keys[b] = tmp; // swap the values tmp = values[a]; values[a] = values[b]; values[b] = tmp; } private static void swap(long keys[], int values[], int a, int b) { // swap the keys long tmpKey = keys[a]; keys[a] = keys[b]; keys[b] = tmpKey; // swap the values int tmpValue = values[a]; values[a] = values[b]; values[b] = tmpValue; } }