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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| public static void QuickSort<T>(IList<T> arr) where T : IComparable<T> { DoQuickSort_1(arr, 0, arr.Count - 1); }
private static void DoQuickSort_1<T>(IList<T> arr, int l, int r) where T : IComparable<T> { if (r - l < 16) { InsertSort(arr, l, r); return; } var pivot = arr[l]; int indexL = l + 1, indexR = r; while (indexL < indexR) { bool moved = false; while (indexL < indexR && arr[indexL].CompareTo(pivot) < 0) { ++indexL; moved = true; } while (indexL < indexR && arr[indexR].CompareTo(pivot) > 0) { --indexR; moved = true; } Swap(arr, indexL, indexR); if (!moved) { ++indexL; --indexR; } } if (arr[indexL].CompareTo(pivot) >= 0) --indexL; Swap(arr, l, indexL); DoQuickSort_1(arr, l, indexL - 1); DoQuickSort_1(arr, indexL + 1, r); }
private static void DoQuickSort_Scratch<T>(IList<T> arr, int l, int r) where T : IComparable<T> { if (r - l < 16) { InsertSort(arr, l, r); return; } var pivot = arr[l]; int indexL = l, indexR = r + 1; while (true) { while (arr[--indexR].CompareTo(pivot) > 0) ; while (indexL < indexR && arr[++indexL].CompareTo(pivot) < 0) ; if (indexL < indexR) Swap(arr, indexL, indexR); else break; } Swap(arr, l, indexL); DoQuickSort_Scratch(arr, l, indexL - 1); DoQuickSort_Scratch(arr, indexL + 1, r); }
private static void DoQuickSort_Three<T>(IList<T> arr, int l, int r) where T : IComparable<T> { if (r - l < 16) { InsertSort(arr, l, r); return; } int m = (l + r) >> 1; if (arr[l].CompareTo(arr[m]) > 0) Swap(arr, l, m); if (arr[m].CompareTo(arr[r]) > 0) Swap(arr, m, r); if (arr[l].CompareTo(arr[m]) > 0) Swap(arr, l, m); Swap(arr, m, r - 1); var pivot = arr[r - 1]; int indexL = l, indexR = r - 1; while (true) { while (arr[++indexL].CompareTo(pivot) < 0) ; while (arr[--indexR].CompareTo(pivot) > 0) ; if (indexL < indexR) Swap(arr, indexL, indexR); else break; } Swap(arr, indexL, r - 1); DoQuickSort_Three(arr, l, indexL - 1); DoQuickSort_Three(arr, indexL + 1, r); }
|