Java Array Sort sortDesc(long[] keys, int[] values)

Here you can find the source of sortDesc(long[] keys, int[] values)

Description

Sorts the keys in an decreasing order.

License

Open Source License

Declaration

public static void sortDesc(long[] keys, int[] values) 

Method Source Code

//package com.java2s;
/**/*from  w  w w . j a 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 decreasing 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 sortDesc(long[] keys, int[] values) {
        hybridsortDesc(keys, values, null, null, 0, keys.length - 1);
    }

    /**
     * Sorts the keys in an decreasing 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
     * <p>
     * This version of the method allows the temporarily needed arrays for the
     * radix sort to be provided externally - tempa and tempb. This saves
     * unnecessary array creation and cleanup
     */
    public static void sortDesc(long[] a, int[] b, long[] tmpa, int[] tmpb) {
        hybridsortDesc(a, b, tmpa, tmpb, 0, a.length - 1);
    }

    private static void hybridsortDesc(long[] keys, int[] values, long[] tmpKeys, int[] tmpValues, int left,
            int right) {
        while (right - left >= 1) {
            if (right - left < 5000000) {
                // use insert sort on the small ones
                // to avoid the loop in radix sort
                if (right - left < 12) {
                    for (int i = left; i <= right; i++)
                        for (int j = i; j > left && keys[j - 1] < keys[j]; j--)
                            swap(keys, values, j, j - 1);
                    return;
                }
                radixsortDesc(keys, values, tmpKeys, tmpValues, 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 bigger, on the right - smaller
                int[] i = splitDesc(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 bigger than keys[i]
                    hybridsortDesc(keys, values, tmpKeys, tmpValues, left, i[0] - 1);
                    // then loop to sort all keys smaller than keys[i]
                    left = i[1] + 1;
                } else {
                    // sort all keys smaller than keys[i]
                    hybridsortDesc(keys, values, tmpKeys, tmpValues, i[1] + 1, right);
                    // then loop to sort all keys bigger than keys[i]
                    right = i[0] - 1;
                }
            }
        }
    }

    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;
    }

    private static void radixsortDesc(long[] keys, int[] values, long[] tempKeys, int[] tempValues, int offset,
            int length) {
        if (tempKeys == null)
            tempKeys = new long[length];
        if (tempValues == null)
            tempValues = new int[length];
        countsortDesc(keys, tempKeys, values, tempValues, offset, 0, length, 0);
        countsortDesc(tempKeys, keys, tempValues, values, 0, offset, length, 1);
        countsortDesc(keys, tempKeys, values, tempValues, offset, 0, length, 2);
        countsortDesc(tempKeys, keys, tempValues, values, 0, offset, length, 3);
        countsortDesc(keys, tempKeys, values, tempValues, offset, 0, length, 4);
        countsortDesc(tempKeys, keys, tempValues, values, 0, offset, length, 5);
        countsortDesc(keys, tempKeys, values, tempValues, offset, 0, length, 6);
        countsortDesc(tempKeys, keys, tempValues, values, 0, offset, length, 7);
    }

    private static int[] splitDesc(long[] 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));
        long 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 countsortDesc(long[] srcKeys, long[] 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[(int) ((srcKeys[i] >> (shiftBits)) & 0xff)]++;

        if (sortByte == 7) {
            // Sign byte, so sort 127..0 255..128
            /* index[127] = 0 */
            for (int i = 126; i >= 0; i--)
                index[i] = index[i + 1] + count[i + 1];
            index[255] = index[0] + count[0];
            for (int i = 254; i >= 128; i--)
                index[i] = index[i + 1] + count[i + 1];
        } else {
            /* index[255] = 0 */
            for (int i = 254; i >= 0; i--)
                index[i] = index[i + 1] + count[i + 1];
        }

        for (int i = srcOffset; i < srcEnd; i++) {
            int idx = (int) ((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;
        }
    }
}

Related

  1. sortByLengthDesc(String[] ss)
  2. sortByString(Object[] array)
  3. sortByValue(int start, int end, double[] values, int[] indexes)
  4. sortByValueStable(int start, int end, double[] values, int[] indexes)
  5. sortCompare(String[] valuesOne, String[] valuesTwo)
  6. sortDescending(T[] a, int fromIndex, int toIndex)
  7. SortDoubleDimensionArray(String StrArr[][])
  8. sorted(int[] array)
  9. sortedArraysEqual(Object[] arr1, Object[] arr2)