1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| static void sort(int[] a, int left, int right, int[] work, int workBase, int workLen) { if (right - left < QUICKSORT_THRESHOLD) { sort(a, left, right, true); return; } int[] run = new int[MAX_RUN_COUNT + 1]; int count = 0; run[0] = left; for (int k = left; k < right; run[count] = k) { while (k < right && a[k] == a[k + 1]) k++; if (k == right) break; if (a[k] < a[k + 1]) { while (++k <= right && a[k - 1] <= a[k]); } else if (a[k] > a[k + 1]) { // descending while (++k <= right && a[k - 1] >= a[k]); for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) { int t = a[lo]; a[lo] = a[hi]; a[hi] = t; } } if (run[count] > left && a[run[count]] >= a[run[count] - 1]) { count--; } if (++count == MAX_RUN_COUNT) { sort(a, left, right, true); return; } } if (count == 0) { return; } else if (count == 1 && run[count] > right) { return; } right++; if (run[count] < right) { run[++count] = right; } byte odd = 0; for (int n = 1; (n <<= 1) < count; odd ^= 1); int[] b; int ao, bo; int blen = right - left; if (work == null || workLen < blen || workBase + blen > work.length) { work = new int[blen]; workBase = 0; } if (odd == 0) { System.arraycopy(a, left, work, workBase, blen); b = a; bo = 0; a = work; ao = workBase - left; } else { b = work; ao = 0; bo = workBase - left; } for (int last; count > 1; count = last) { for (int k = (last = 0) + 2; k <= count; k += 2) { int hi = run[k], mi = run[k - 1]; for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) { if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) { b[i + bo] = a[p++ + ao]; } else { b[i + bo] = a[q++ + ao]; } } run[++last] = hi; } if ((count & 1) != 0) { for (int i = right, lo = run[count - 1]; --i >= lo; b[i + bo] = a[i + ao] ); run[++last] = right; } int[] t = a; a = b; b = t; int o = ao; ao = bo; bo = o; } }
|