Exemple #1
0
        /// <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);
            }
        }