📄 arrays.java
字号:
* @return the index (a, b, or c) which has the middle value of the three */ private static int med3(int a, int b, int c, short[] d) { return (d[a] < d[b] ? (d[b] < d[c] ? b : d[a] < d[c] ? c : a) : (d[b] > d[c] ? b : d[a] > d[c] ? c : a)); } /** * Swaps the elements at two locations of an array * * @param i the first index * @param j the second index * @param a the array */ private static void swap(int i, int j, short[] a) { short c = a[i]; a[i] = a[j]; a[j] = c; } /** * Swaps two ranges of an array. * * @param i the first range start * @param j the second range start * @param n the element count * @param a the array */ private static void vecswap(int i, int j, int n, short[] a) { for ( ; n > 0; i++, j++, n--) swap(i, j, a); } /** * Performs a recursive modified quicksort. * * @param a the array to sort * @param from the start index (inclusive) * @param count the number of elements to sort */ private static void qsort(short[] array, int from, int count) { // Use an insertion sort on small arrays. if (count <= 7) { for (int i = from + 1; i < from + count; i++) for (int j = i; j > 0 && array[j - 1] > array[j]; j--) swap(j, j - 1, array); return; } // Determine a good median element. int mid = count / 2; int lo = from; int hi = from + count - 1; if (count > 40) { // big arrays, pseudomedian of 9 int s = count / 8; lo = med3(lo, lo + s, lo + 2 * s, array); mid = med3(mid - s, mid, mid + s, array); hi = med3(hi - 2 * s, hi - s, hi, array); } mid = med3(lo, mid, hi, array); int a, b, c, d; int comp; // Pull the median element out of the fray, and use it as a pivot. swap(from, mid, array); a = b = from; c = d = from + count - 1; // Repeatedly move b and c to each other, swapping elements so // that all elements before index b are less than the pivot, and all // elements after index c are greater than the pivot. a and b track // the elements equal to the pivot. while (true) { while (b <= c && (comp = array[b] - array[from]) <= 0) { if (comp == 0) { swap(a, b, array); a++; } b++; } while (c >= b && (comp = array[c] - array[from]) >= 0) { if (comp == 0) { swap(c, d, array); d--; } c--; } if (b > c) break; swap(b, c, array); b++; c--; } // Swap pivot(s) back in place, the recurse on left and right sections. hi = from + count; int span; span = Math.min(a - from, b - a); vecswap(from, b - span, span, array); span = Math.min(d - c, hi - d - 1); vecswap(b, hi - span, span, array); span = b - a; if (span > 1) qsort(array, from, span); span = d - c; if (span > 1) qsort(array, hi - span, span); } /** * Performs a stable sort on the elements, arranging them according to their * natural order. * * @param a the int array to sort */ public static void sort(int[] a) { qsort(a, 0, a.length); } /** * Performs a stable sort on the elements, arranging them according to their * natural order. * * @param a the int array to sort * @param fromIndex the first index to sort (inclusive) * @param toIndex the last index to sort (exclusive) * @throws IllegalArgumentException if fromIndex > toIndex * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 * || toIndex > a.length */ public static void sort(int[] a, int fromIndex, int toIndex) { if (fromIndex > toIndex) throw new IllegalArgumentException(); qsort(a, fromIndex, toIndex - fromIndex); } /** * Finds the index of the median of three array elements. * * @param a the first index * @param b the second index * @param c the third index * @param d the array * @return the index (a, b, or c) which has the middle value of the three */ private static int med3(int a, int b, int c, int[] d) { return (d[a] < d[b] ? (d[b] < d[c] ? b : d[a] < d[c] ? c : a) : (d[b] > d[c] ? b : d[a] > d[c] ? c : a)); } /** * Swaps the elements at two locations of an array * * @param i the first index * @param j the second index * @param a the array */ private static void swap(int i, int j, int[] a) { int c = a[i]; a[i] = a[j]; a[j] = c; } /** * Swaps two ranges of an array. * * @param i the first range start * @param j the second range start * @param n the element count * @param a the array */ private static void vecswap(int i, int j, int n, int[] a) { for ( ; n > 0; i++, j++, n--) swap(i, j, a); } /** * Compares two integers in natural order, since a - b is inadequate. * * @param a the first int * @param b the second int * @return < 0, 0, or > 0 accorting to the comparison */ private static int compare(int a, int b) { return a < b ? -1 : a == b ? 0 : 1; } /** * Performs a recursive modified quicksort. * * @param a the array to sort * @param from the start index (inclusive) * @param count the number of elements to sort */ private static void qsort(int[] array, int from, int count) { // Use an insertion sort on small arrays. if (count <= 7) { for (int i = from + 1; i < from + count; i++) for (int j = i; j > 0 && array[j - 1] > array[j]; j--) swap(j, j - 1, array); return; } // Determine a good median element. int mid = count / 2; int lo = from; int hi = from + count - 1; if (count > 40) { // big arrays, pseudomedian of 9 int s = count / 8; lo = med3(lo, lo + s, lo + 2 * s, array); mid = med3(mid - s, mid, mid + s, array); hi = med3(hi - 2 * s, hi - s, hi, array); } mid = med3(lo, mid, hi, array); int a, b, c, d; int comp; // Pull the median element out of the fray, and use it as a pivot. swap(from, mid, array); a = b = from; c = d = from + count - 1; // Repeatedly move b and c to each other, swapping elements so // that all elements before index b are less than the pivot, and all // elements after index c are greater than the pivot. a and b track // the elements equal to the pivot. while (true) { while (b <= c && (comp = compare(array[b], array[from])) <= 0) { if (comp == 0) { swap(a, b, array); a++; } b++; } while (c >= b && (comp = compare(array[c], array[from])) >= 0) { if (comp == 0) { swap(c, d, array); d--; } c--; } if (b > c) break; swap(b, c, array); b++; c--; } // Swap pivot(s) back in place, the recurse on left and right sections. hi = from + count; int span; span = Math.min(a - from, b - a); vecswap(from, b - span, span, array); span = Math.min(d - c, hi - d - 1); vecswap(b, hi - span, span, array); span = b - a; if (span > 1) qsort(array, from, span); span = d - c; if (span > 1) qsort(array, hi - span, span); } /** * Performs a stable sort on the elements, arranging them according to their * natural order. * * @param a the long array to sort */ public static void sort(long[] a) { qsort(a, 0, a.length); } /** * Performs a stable sort on the elements, arranging them according to their * natural order. * * @param a the long array to sort * @param fromIndex the first index to sort (inclusive) * @param toIndex the last index to sort (exclusive) * @throws IllegalArgumentException if fromIndex > toIndex * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 * || toIndex > a.length */ public static void sort(long[] a, int fromIndex, int toIndex) { if (fromIndex > toIndex) throw new IllegalArgumentException(); qsort(a, fromIndex, toIndex - fromIndex); } /** * Finds the index of the median of three array elements. * * @param a the first index * @param b the second index * @param c the third index * @param d the array * @return the index (a, b, or c) which has the middle value of the three */ private static int med3(int a, int b, int c, long[] d) { return (d[a] < d[b] ? (d[b] < d[c] ? b : d[a] < d[c] ? c : a) : (d[b] > d[c] ? b : d[a] > d[c] ? c : a)); } /** * Swaps the elements at two locations of an array * * @param i the first index * @param j the second index * @param a the array */ private static void swap(int i, int j, long[] a) { long c = a[i]; a[i] = a[j]; a[j] = c; } /** * Swaps two ranges of an array. * * @param i the first range start * @param j the second range start * @param n the element count * @param a the array */ private static void vecswap(int i, int j, int n, long[] a) { for ( ; n > 0; i++, j++, n--) swap(i, j, a); } /** * Compares two longs in natural order, since a - b is inadequate. * * @param a the first long * @param b the second long * @return < 0, 0, or > 0 accorting to the comparison */ private static int compare(long a, long b) { return a < b ? -1 : a == b ? 0 : 1; } /** * Performs a recursive modified quicksort. * * @param a the array to sort * @param from the start index (inclusive) * @param count the number of elements to sort */ private static void qsort(long[] array, int from, int count) { // Use an insertion sort on small arrays. if (count <= 7) { for (int i = from + 1; i < from + count; i++) for (int j = i; j > 0 && array[j - 1] > array[j]; j--) swap(j, j - 1, array); return; } // Determine a good median element. int mid = count / 2; int lo = from; int hi = from + count - 1; if (count > 40) { // big arrays, pseudomedian of 9 int s = count / 8; lo = med3(lo, lo + s, lo + 2 * s, array); mid = med3(mid - s, mid, mid + s, array); hi = med3(hi - 2 * s, hi - s, hi, array); } mid = med3(lo, mid, hi, array); int a, b, c, d; int comp; // Pull the median element out of the fray, and use it as a pivot. swap(from, mid, array); a = b = from; c = d = from + count - 1; // Repeatedly move b and c to each other, swapping elements so // that all elements before index b are less than the pivot, and all // elements after index c are greater than the pivot. a and b track // the elements equal to the pivot. while (true) { while (b <= c && (comp = compare(array[b], array[from])) <= 0) { if (comp == 0) { swap(a, b, array); a++; } b++; } while (c >= b && (comp = compare(array[c], array[from])) >= 0) { if (comp == 0) { swap(c, d, array); d--; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -