/// <summary>Sorts the specified array.</summary> /// <param name="a">Array to be sorted.</param> /// <param name="lo">the index of the first element in the range to be sorted.</param> /// <param name="hi">the index after the last element in the range to be sorted.</param> /// <param name="c">The comparator to determine the order of the sort.</param> public static void Sort(IList <T> a, int lo, int hi, Comparison <T> c) { CheckRange(a.Count, lo, hi); int width = hi - lo; if (width < 2) { return; // Arrays of size 0 and 1 are always sorted } // If array is small, do a "mini-TimSort" with no merges if (width < MIN_MERGE) { int initRunLength = CountRunAndMakeAscending(a, lo, hi, c); BinarySort(a, lo, hi, lo + initRunLength, c); return; } // March over the array once, left to right, finding natural runs, // extending short natural runs to minRun elements, and merging runs // to maintain stack invariant. var sorter = new ListTimSort <T>(a, c); int minRun = GetMinimumRunLength(width); do { // Identify next run int runLen = CountRunAndMakeAscending(a, lo, hi, c); // If run is short, extend to min(minRun, nRemaining) if (runLen < minRun) { int force = width <= minRun ? width : minRun; BinarySort(a, lo, lo + force, lo + runLen, c); runLen = force; } // Push run onto pending-run stack, and maybe merge sorter.PushRun(lo, runLen); sorter.MergeCollapse(); // Advance to find next run lo += runLen; width -= runLen; } while (width != 0); // Merge all remaining runs to complete sort Debug.Assert(lo == hi); sorter.MergeForceCollapse(); Debug.Assert(sorter.m_StackSize == 1); }
public void Test_Common() { Assert.Throws(typeof(ArgumentNullException), () => { SortHelper.QuickSort <ValItem>(null, null); }); Assert.Throws(typeof(ArgumentNullException), () => { SortHelper.MergeSort <ValItem>(null, null); }); Assert.Throws(typeof(ArgumentNullException), () => { ListTimSort <int> .Sort(null, null); }); Random rnd = new Random(); List <ValItem> listQS = new List <ValItem>(); List <ValItem> listMS = new List <ValItem>(); List <ValItem> listTS = new List <ValItem>(); List <ValItem> listCS = new List <ValItem>(); //const int MaxCount = 1000000; // for performance test const int MaxCount = 1000; // for common test for (int i = 0; i < MaxCount; i++) { double val = rnd.NextDouble(); listTS.Add(new ValItem(val)); listQS.Add(new ValItem(val)); listMS.Add(new ValItem(val)); listCS.Add(new ValItem(val)); } listCS.Sort(CompareItems); SortHelper.QuickSort(listQS, CompareItems); SortHelper.MergeSort(listMS, CompareItems); ListTimSort <ValItem> .Sort(listTS, CompareItems); // test for sort valid //(only for numbers, because some methods is with the permutations, and part - no) for (int i = 0; i < MaxCount; i++) { Assert.AreEqual(listTS[i].Value, listQS[i].Value); Assert.AreEqual(listQS[i].Value, listMS[i].Value); Assert.AreEqual(listMS[i].Value, listCS[i].Value); } }