Partial QuickSort in Java
Posted Escape The Well
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Partial QuickSort in Java相关的知识,希望对你有一定的参考价值。
1 import java.util.Comparator; 2 import java.util.Random; 3 4 /** 5 * Created by william on 08/04/2018. 6 */ 7 public class QuickSort<T> { 8 9 private static final int MAX_STACK_SIZE = 64; 10 private static final int MAX_ARRAY_SIZE; 11 static { 12 long maxArraySize = 1L << (MAX_STACK_SIZE / 2 - 1); 13 MAX_ARRAY_SIZE = (int) Math.min( 14 maxArraySize, (long) Integer.MAX_VALUE); 15 } 16 17 private static final int INSERTION_SORT_THRESHOLD = 16; 18 19 private static final int MEDIAN_OF_THREE_THRESHOLD = 48; 20 21 public static <T> void sort(T[] a, int fromIndex, int toIndex, 22 Comparator<? super T> c) { 23 partialSort(a, fromIndex, toIndex, toIndex, c); 24 } 25 26 /** 27 * This method implements the Partial QuickSort introduced by 28 * Conrado Martínez in his paper "Partial QuickSort". 29 * 30 * 31 * - Pseudo Code ------------------------------------------------ 32 * 33 * function partial_quicksort(a, i, j, k) 34 * if i < j 35 * p ← partition(a, i, j) 36 * partial_quicksort(a, i, p-1, k) 37 * if p < k-1 38 * partial_quicksort(a, p+1, j, k) 39 * 40 * -------------------------------------------------------------- 41 * 42 * Partial QuickSort works as follows. In every recursive call 43 * we receive a subarray a[i..j] and a k that k >= i. We must 44 * rearrange the subarray so that a[i..k] contains the k - i + 1 45 * smallest elements of a[i, j] in ascending order; if k > j 46 * that means we must fully sort a[i..j]. 47 * 48 * This algorithm required an expected time of only O(n + m log m) 49 * where n is the size of the subarray a[i..j] and m is the number 50 * of smallest elements we need 51 * 52 * See http://www.lsi.upc.edu/~conrado/research/reports/ALCOMFT-TR-03-50.pdf 53 * for more details 54 * 55 */ 56 public static <T> void partialSort( 57 T[] a, int fromIndex, int toIndex, int middleIndex, 58 Comparator<? super T> c) { 59 rangeCheck(a.length, fromIndex, toIndex); 60 61 int[] stack = new int[MAX_STACK_SIZE]; 62 int top = 0; 63 64 stack[top++] = fromIndex; 65 stack[top++] = toIndex; 66 67 while (top > 0) { 68 toIndex = stack[--top]; 69 fromIndex = stack[--top]; 70 71 if (toIndex - fromIndex <= INSERTION_SORT_THRESHOLD) { 72 for (int i = fromIndex + 1; i < toIndex; i++) { 73 T x = a[i]; 74 int j = i; 75 while (--j >= fromIndex && c.compare(x, a[j]) < 0) { 76 a[j + 1] = a[j]; 77 } 78 a[j + 1] = x; 79 } 80 continue; 81 } 82 83 int pivotIndex = partition(a, fromIndex, toIndex, c); 84 85 if (pivotIndex - fromIndex >= toIndex - pivotIndex - 1) { 86 stack[top++] = fromIndex; 87 stack[top++] = pivotIndex; 88 89 if (pivotIndex < middleIndex - 1) { 90 stack[top++] = pivotIndex + 1; 91 stack[top++] = toIndex; 92 } 93 } else { 94 if (pivotIndex < middleIndex - 1) { 95 stack[top++] = pivotIndex + 1; 96 stack[top++] = toIndex; 97 } 98 if (pivotIndex > fromIndex) { 99 stack[top++] = fromIndex; 100 stack[top++] = pivotIndex; 101 } 102 } 103 } 104 } 105 106 private static void rangeCheck( 107 int arrayLength, int fromIndex, int toIndex) { 108 109 if (arrayLength > MAX_ARRAY_SIZE) { 110 throw new IllegalArgumentException("size of array is " + 111 "too large, maximum array size allowed: " + 112 MAX_ARRAY_SIZE); 113 } 114 115 if (fromIndex < 0) { 116 throw new ArrayIndexOutOfBoundsException(fromIndex); 117 } 118 119 if (toIndex > arrayLength) { 120 throw new ArrayIndexOutOfBoundsException(toIndex); 121 } 122 123 if (fromIndex > toIndex) { 124 throw new IllegalArgumentException( 125 "fromIndex(" + fromIndex + ") > " + 126 "toIndex(" + toIndex + ")"); 127 } 128 } 129 130 private static final long RANDOM_SEED = System.currentTimeMillis(); 131 132 private static <T> int partition(T[] a, int fromIndex, int toIndex, 133 Comparator<? super T> c) { 134 int n = toIndex - fromIndex; 135 int pivotIndex = fromIndex + (n >> 1); 136 if (n > MEDIAN_OF_THREE_THRESHOLD) { 137 Random random = new Random(RANDOM_SEED); 138 pivotIndex = medianOfThree(a, 139 fromIndex + random.nextInt(n), 140 fromIndex + random.nextInt(n), 141 fromIndex + random.nextInt(n), 142 c); 143 } 144 swap(a, fromIndex, pivotIndex); 145 146 T pivot = a[fromIndex]; 147 int i = fromIndex; 148 for (int j = fromIndex + 1; j < toIndex; j++) { 149 if (c.compare(a[j], pivot) < 0) { 150 swap(a, ++i, j); 151 } 152 } 153 swap(a, fromIndex, i); 154 return i; 155 } 156 157 private static <T> int medianOfThree(T[] a, int i, int j, int k, 158 Comparator<? super T> c) { 159 return c.compare(a[i], a[j]) < 0 ? 160 (c.compare(a[j], a[k]) < 0 ? j : 161 c.compare(a[i], a[k]) < 0 ? k : i) : 162 (c.compare(a[k], a[j]) < 0 ? j : 163 c.compare(a[i], a[k]) < 0 ? i : k); 164 } 165 166 private static <T> void swap(T[] a, int i, int j) { 167 T temp = a[i]; 168 a[i] = a[j]; 169 a[j] = temp; 170 } 171 172 public static <T> void sort(T[] a, Comparator<? super T> c) { 173 sort(a, 0, a.length, c); 174 } 175 176 public static <T> void partialSort(T[] a, int k, 177 Comparator<? super T> c) { 178 partialSort(a, 0, a.length, k, c); 179 } 180 }
以上是关于Partial QuickSort in Java的主要内容,如果未能解决你的问题,请参考以下文章
A Partial Lunar Eclipse Will Be Visible Tonight in China
Typescript的高级tricks(in,keyof,Partial,Pick,Exclude等)
Some features we need to keep in mind about the implementation of QuickSort algorithm