/// <summary> /// Rearrange the array,so the result is random /// </summary> /// <param name="arr"></param> public static void RandomRearrange(T[] arr) { if (arr == null || arr.Length <= 1) { return; } Random rand = new Random(); for (int i = 0; i < arr.Length - 1; i++) { int index = rand.Next(i, arr.Length); SortCommons <T> .Exchange(arr, i, index); } }
/// <summary> /// hi must >= lo, and sort arr[lo...hi] in place. Doesn't affect the element out of [lo,hi] /// </summary> /// <param name="arr"></param> /// <param name="lo"></param> /// <param name="hi"></param> /// <returns></returns> public static T[] Sort(T[] arr, int lo, int hi) { for (int i = hi; i > lo; i--) { for (int j = lo; j < i; j++) { if (arr[j].CompareTo(arr[j + 1]) > 0) { SortCommons <T> .Exchange(arr, j, j + 1); } } } return(arr); }
/// <summary> /// hi must >= lo, and sort arr[lo...hi] in place. Doesn't affect the element out of [lo,hi] /// </summary> /// <param name="arr"></param> /// <param name="lo"></param> /// <param name="hi"></param> /// <returns></returns> public static T[] Sort(T[] arr, int lo, int hi) { for (int i = lo; i < hi; i++) { int minIndex = i; for (int j = i + 1; j <= hi; j++) { if (arr[minIndex].CompareTo(arr[j]) > 0) { minIndex = j; } } SortCommons <T> .Exchange(arr, minIndex, i); } return(arr); }
/// <summary> /// Divide A[p...r] into two part A[p...q-1] and [q+1...r] such that each element of A[p...q-1] is less than or equal to A[q] , which is ,in turn, less than each element of A[q+1....r] /// </summary> /// <param name="arr"></param> /// <param name="lo">you should guarantee the availabity of the index</param> /// <param name="hi"></param> /// <returns></returns> public static int Partition2(T[] arr, int lo, int hi) { T tmp = arr[hi]; //let hi as pivot. from low postion, find the one lower than the pivot and move it to low position int q = lo - 1; for (int i = lo; i < hi; i++) { if (arr[i].CompareTo(tmp) <= 0) { q++; SortCommons <T> .Exchange(arr, q, i); } } SortCommons <T> .Exchange(arr, q + 1, hi); return(q + 1); }
/// <summary> /// heapsort: it runs in place and runs at n(lgn) /// </summary> /// <param name="arr"></param> public static T[] Sort(params T[] arr) { if (arr == null || arr.Length <= 1) { return(arr); } BuildMaxHeap(arr); int heapsize = arr.Length; for (int i = heapsize; i > 1; i--) { heapsize--; SortCommons <T> .Exchange(arr, heapsize, 0); Sink(arr, 0, heapsize); } return(arr); }
/// <summary> /// partition the subarray a[lo .. hi] by returning an index j. so that a[lo .. j-1] <= a[j] <= a[j+1 .. hi] /// </summary> /// <param name="a"></param> /// <param name="lo"></param> /// <param name="hi"></param> /// <returns></returns> public static int Partition4(T[] a, int lo, int hi) { int i = lo; int j = hi + 1; T v = a[lo]; while (true) { // find item on lo to swap //找到第一个比lo大的元素位置 while (a[++i].CompareTo(v) <= 0) { if (i == hi) { break; } } // find item on hi to swap while (v.CompareTo(a[--j]) <= 0) { if (j == lo) { break; // redundant since a[lo] acts as sentinel } } // check if pointers cross if (i >= j) { break; } SortCommons <T> .Exchange(a, i, j); } // put v = a[j] into position SortCommons <T> .Exchange(a, lo, j); // with a[lo .. j-1] <= a[j] <= a[j+1 .. hi] return(j); }
/// <summary> /// lets the value at arr[i] “float down” in the max-heap so that the subtree rooted at index i obeys the max-heap property. /// it runs at O(lgn) /// </summary> /// <param name="arr" /> /// <param name="i"></param> /// <param name="heapsize"> </param> private static void Sink(T[] arr, int i, int heapsize) { int left = Left(i); int right = Right(i); int max = i; if (left < heapsize && arr[left].CompareTo(arr[max]) > 0) { max = left; } if (right < heapsize && arr[right].CompareTo(arr[max]) > 0) { max = right; } if (max != i) { SortCommons <T> .Exchange(arr, max, i); Sink(arr, max, heapsize); } }
/// <summary> /// Divide A[p...r] into two part A[p...q-1] and [k+1...r] such that each element of A[p...q-1] is less than A[q...k] ,a[q...k] are equal, which is ,in turn, less than each element of A[q+1....r] /// </summary> /// <param name="arr"></param> /// <param name="lo">you should guarantee the availabity of the index</param> /// <param name="hi"></param> /// <param name="q"> </param> /// <param name="k"> </param> /// <returns></returns> public static void Partition3(T[] arr, int lo, int hi, out int q, out int k) { q = lo; k = hi; T temp = arr[lo]; int i = lo; while (i <= k) { int cmp = arr[i].CompareTo(temp); if (cmp < 0) { SortCommons <T> .Exchange(arr, q ++, i ++); } else if (cmp > 0) { SortCommons <T> .Exchange(arr, k --, i); } else { i++; } } }