/// <summary> /// Rearranges the array in ascending order, using the natural order.</summary> /// <param name="a">a the array to be sorted</param> /// public static void Sort(IComparable[] a) { int N = a.Length; // 3x+1 increment sequence: 1, 4, 13, 40, 121, 364, 1093, ... int h = 1; while (h < N / 3) { h = 3 * h + 1; } while (h >= 1) { // h-sort the array for (int i = h; i < N; i++) { for (int j = i; j >= h && OrderHelper.Less(a[j], a[j - h]); j -= h) { OrderHelper.Exch(a, j, j - h); } } Debug.Assert(IsHsorted(a, h)); h /= 3; } Debug.Assert(OrderHelper.IsSorted(a)); }
// quicksort the subarray a[lo .. hi] using 3-way partitioning private static void Sort(IComparable[] a, int lo, int hi) { if (hi <= lo) { return; } int lt = lo, gt = hi; IComparable v = a[lo]; int i = lo; while (i <= gt) { int cmp = a[i].CompareTo(v); if (cmp < 0) { OrderHelper.Exch(a, lt++, i++); } else if (cmp > 0) { OrderHelper.Exch(a, i, gt--); } else { i++; } } // a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi]. Sort(a, lo, lt - 1); Sort(a, gt + 1, hi); Debug.Assert(OrderHelper.IsSorted(a, lo, hi)); }
/// <summary> /// Rearranges the array in ascending order, using the natural order.</summary> /// <param name="a">the array to be sorted</param> /// public static void Sort(IComparable[] a) { int N = a.Length; // put smallest element in position to serve as sentinel int exchanges = 0; for (int i = N - 1; i > 0; i--) { if (OrderHelper.Less(a[i], a[i - 1])) { OrderHelper.Exch(a, i, i - 1); exchanges++; } } if (exchanges == 0) return; // insertion sort with half-exchanges for (int i = 2; i < N; i++) { IComparable v = a[i]; int j = i; while (OrderHelper.Less(v, a[j - 1])) { a[j] = a[j - 1]; j--; } a[j] = v; } Debug.Assert(OrderHelper.IsSorted(a)); }
/*************************************************************************** * Helper functions to restore the heap invariant. ***************************************************************************/ private void swim(int k) { while (k > 1 && OrderHelper.Greater <Key>(pq[k / 2], pq[k])) { OrderHelper.Exch(pq, k, k / 2); k = k / 2; } }
/// <summary> /// Rearranges the subarray a[lo..hi] in ascending order, using the natural order.</summary> /// <param name="a">a the array to be sorted</param> /// <param name="lo">lo left endpoint</param> /// <param name="hi">hi right endpoint</param> /// public static void Sort(IComparable[] a, int lo, int hi) { for (int i = lo; i <= hi; i++) { for (int j = i; j > lo && OrderHelper.Less(a[j], a[j - 1]); j--) { OrderHelper.Exch(a, j, j - 1); } } Debug.Assert(OrderHelper.IsSorted(a, lo, hi)); }
/// <summary> /// Rearranges the subarray a[lo..hi] in ascending order, using a generic comparator.</summary> /// <param name="a">a the array</param> /// <param name="lo">lo left endpoint</param> /// <param name="hi">hi right endpoint</param> /// <param name="comparator">comparator the comparator specifying the order</param> /// public static void Sort <T>(T[] a, int lo, int hi, Comparer <T> comparator) { for (int i = lo; i <= hi; i++) { for (int j = i; j > lo && OrderHelper.Less(a[j], a[j - 1], comparator); j--) { OrderHelper.Exch <T>(a, j, j - 1); } } Debug.Assert(OrderHelper.IsSorted(a, lo, hi, comparator)); }
/// <summary> /// Rearranges the array in ascending order, using the natural order.</summary> /// <param name="a">a the array to be sorted</param> /// public static void Sort(IComparable[] a) { int N = a.Length; for (int i = 0; i < N; i++) { for (int j = i; j > 0 && OrderHelper.Less(a[j], a[j - 1]); j--) { OrderHelper.Exch(a, j, j - 1); } Debug.Assert(OrderHelper.IsSorted(a, 0, i)); } Debug.Assert(OrderHelper.IsSorted(a)); }
/// <summary> /// Rearranges the array in ascending order, using a comparator.</summary> /// <param name="a">a the array</param> /// <param name="comparator">comparator the comparator specifying the order</param> /// public static void Sort(object[] a, System.Collections.Comparer comparator) { int N = a.Length; for (int i = 0; i < N; i++) { for (int j = i; j > 0 && OrderHelper.Less(a[j], a[j - 1], comparator); j--) { OrderHelper.Exch(a, j, j - 1); } Debug.Assert(OrderHelper.IsSorted(a, 0, i, comparator)); } Debug.Assert(OrderHelper.IsSorted(a, comparator)); }
private void sink(int k) { while (2 * k <= N) { int j = 2 * k; if (j < N && OrderHelper.Greater <Key>(pq[j], pq[j + 1])) { j++; } if (!OrderHelper.Greater <Key>(pq[k], pq[j])) { break; } OrderHelper.Exch(pq, k, j); k = j; } }
/// <summary> /// Removes and returns a smallest key on this priority queue.</summary> /// <returns>a smallest key on this priority queue</returns> /// <exception cref="InvalidOperationException">if this priority queue is empty</exception> /// public Key DelMin() { if (IsEmpty) { throw new InvalidOperationException("Priority queue underflow"); } OrderHelper.Exch(pq, 1, N); Key min = pq[N--]; sink(1); pq[N + 1] = default(Key); // avoid loitering and help with garbage collection if ((N > 0) && (N == (pq.Length - 1) / 4)) { resize(pq.Length / 2); } Debug.Assert(isMinHeap()); return(min); }
/// <summary> /// Rearranges the array in ascending order, using a comparator.</summary> /// <param name="a">a the array</param> /// <param name="c">c the comparator specifying the order</param> /// public static void Sort <T>(T[] a, Comparer <T> c) { int N = a.Length; for (int i = 0; i < N; i++) { int min = i; for (int j = i + 1; j < N; j++) { if (OrderHelper.Less <T>(a[j], a[min], c)) { min = j; } } OrderHelper.Exch(a, i, min); Debug.Assert(OrderHelper.IsSorted(a, 0, i, c)); } Debug.Assert(OrderHelper.IsSorted(a, c)); }
/// <summary> /// Rearranges the array in ascending order, using the natural order.</summary> /// <param name="a">a the array to be sorted</param> /// public static void Sort(IComparable[] a) { int N = a.Length; for (int i = 0; i < N; i++) { int min = i; for (int j = i + 1; j < N; j++) { if (OrderHelper.Less(a[j], a[min])) { min = j; } } OrderHelper.Exch(a, i, min); Debug.Assert(OrderHelper.IsSorted(a, 0, i)); } Debug.Assert(OrderHelper.IsSorted(a)); }
/// <summary> /// Returns a permutation that gives the elements in the array in ascending order, /// while not changing the original array a[]</summary> /// <param name="a">a the array</param> /// <returns>a permutation <c>p[]</c> such that <c>a[p[0]]</c>, <c>a[p[1]]</c>, /// ..., <c>a[p[N-1]]</c> are in ascending order</returns> /// public static int[] IndexSort(int[] a) { int N = a.Length; int[] index = new int[N]; for (int i = 0; i < N; i++) { index[i] = i; } for (int i = 0; i < N; i++) { for (int j = i; j > 0 && OrderHelper.Less(a[index[j]], a[index[j - 1]]); j--) { OrderHelper.Exch(index, j, j - 1); } } return(index); }
// partition the subarray a[lo..hi] so that a[lo..j-1] <= a[j] <= a[j+1..hi] // and return the index j. private static int partition(IComparable[] a, int lo, int hi) { int i = lo; int j = hi + 1; IComparable v = a[lo]; while (true) { // find item on lo to swap while (OrderHelper.Less(a[++i], v)) { if (i == hi) { break; } } // find item on hi to swap while (OrderHelper.Less(v, a[--j])) { if (j == lo) { break; // redundant since a[lo] acts as sentinel } } // check if pointers cross if (i >= j) { break; } OrderHelper.Exch(a, i, j); } // put partitioning item v at a[j] OrderHelper.Exch(a, lo, j); // now, a[lo .. j-1] <= a[j] <= a[j+1 .. hi] return(j); }
private static void Sort(IComparable[] a, int lo, int hi) { int N = hi - lo + 1; // cutoff to insertion sort if (N <= CUTOFF) { Insertion.Sort(a, lo, hi); return; } // use median-of-3 as partitioning element else if (N <= 40) { int m = median3(a, lo, lo + N / 2, hi); OrderHelper.Exch(a, m, lo); } // use Tukey ninther as partitioning element else { int eps = N / 8; int mid = lo + N / 2; int m1 = median3(a, lo, lo + eps, lo + eps + eps); int m2 = median3(a, mid - eps, mid, mid + eps); int m3 = median3(a, hi - eps - eps, hi - eps, hi); int ninther = median3(a, m1, m2, m3); OrderHelper.Exch(a, ninther, lo); } // Bentley-McIlroy 3-way partitioning int i = lo, j = hi + 1; int p = lo, q = hi + 1; IComparable v = a[lo]; while (true) { while (OrderHelper.Less(a[++i], v)) { if (i == hi) { break; } } while (OrderHelper.Less(v, a[--j])) { if (j == lo) { break; } } // pointers cross if (i == j && OrderHelper.Eq(a[i], v)) { OrderHelper.Exch(a, ++p, i); } if (i >= j) { break; } OrderHelper.Exch(a, i, j); if (OrderHelper.Eq(a[i], v)) { OrderHelper.Exch(a, ++p, i); } if (OrderHelper.Eq(a[j], v)) { OrderHelper.Exch(a, --q, j); } } i = j + 1; for (int k = lo; k <= p; k++) { OrderHelper.Exch(a, k, j--); } for (int k = hi; k >= q; k--) { OrderHelper.Exch(a, k, i++); } Sort(a, lo, j); Sort(a, i, hi); }