private void QuickSort(IComparer <T> comparer)
        {
            Contracts.Contract.RequireNotNull(comparer, out IComparer <T> Comparer);

            QuickSortRange Range            = QuickSortStack.Pop();
            int            SegmentIndexLow  = Range.SegmentIndexFirst;
            int            ElementIndexLow  = Range.ElementIndexFirst;
            int            SegmentIndexHigh = Range.SegmentIndexLast;
            int            ElementIndexHigh = Range.ElementIndexLast;

            Debug.Assert(IsValidPosition(SegmentIndexLow, ElementIndexLow, false));
            Debug.Assert(IsValidPosition(SegmentIndexHigh, ElementIndexHigh, false));
            Debug.Assert(SegmentIndexLow < SegmentIndexHigh || (SegmentIndexLow == SegmentIndexHigh && ElementIndexLow <= ElementIndexHigh));

            if (SegmentIndexLow == SegmentIndexHigh)
            {
                ISegment <T> Segment = SegmentTable[SegmentIndexLow];
                Segment.Sort(ElementIndexLow, ElementIndexHigh, Comparer);
            }
            else if (SegmentIndexLow < SegmentIndexHigh || (SegmentIndexLow == SegmentIndexHigh && ElementIndexLow < ElementIndexHigh))
            {
                int SegmentIndexMiddle;
                int ElementIndexMiddle;
                SplitSortInterval(SegmentIndexLow, ElementIndexLow, SegmentIndexHigh, ElementIndexHigh, Comparer, out SegmentIndexMiddle, out ElementIndexMiddle);

                QuickSortRange RangeLow = new QuickSortRange()
                {
                    SegmentIndexFirst = SegmentIndexLow, ElementIndexFirst = ElementIndexLow, SegmentIndexLast = SegmentIndexMiddle, ElementIndexLast = ElementIndexMiddle
                };

                if (ElementIndexMiddle + 1 < SegmentTable[SegmentIndexMiddle].Count)
                {
                    ElementIndexMiddle++;
                }
                else
                {
                    SegmentIndexMiddle++;
                    Debug.Assert(SegmentIndexMiddle < SegmentTable.Count && SegmentTable[SegmentIndexMiddle].Count > 0);
                    ElementIndexMiddle = 0;
                }

                QuickSortRange RangeHigh = new QuickSortRange()
                {
                    SegmentIndexFirst = SegmentIndexMiddle, ElementIndexFirst = ElementIndexMiddle, SegmentIndexLast = SegmentIndexHigh, ElementIndexLast = ElementIndexHigh
                };

                QuickSortStack.Push(RangeLow);
                QuickSortStack.Push(RangeHigh);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Sorts the elements in a range of elements in <see cref="Partition{T}"/> using the specified comparer.
        /// </summary>
        /// <param name="segmentIndexBegin">The segment index of the position of the first item in the range.</param>
        /// <param name="elementIndexBegin">The element index of the position of the first item in the range.</param>
        /// <param name="segmentIndexEnd">The segment index of the position after the last item in the range.</param>
        /// <param name="elementIndexEnd">The element index of the position after the last item in the range.</param>
        /// <param name="count">The number of elements in the range.</param>
        /// <param name="comparer">The <see cref="System.Collections.Generic.IComparer{T}"/> implementation to use when comparing elements.</param>
        public void Sort(int segmentIndexBegin, int elementIndexBegin, int segmentIndexEnd, int elementIndexEnd, long count, IComparer <T> comparer)
        {
            Contract.RequireNotNull(comparer, out IComparer <T> Comparer);

            Debug.Assert(IsValidPosition(segmentIndexBegin, elementIndexBegin, true));
            Debug.Assert(IsValidPosition(segmentIndexEnd, elementIndexEnd, true));
            Debug.Assert((count == 0 && segmentIndexBegin == segmentIndexEnd && elementIndexBegin == elementIndexEnd) || (count > 0 && ((segmentIndexBegin < segmentIndexEnd) || (segmentIndexBegin == segmentIndexEnd && elementIndexBegin < elementIndexEnd))));
            Debug.Assert(comparer != null);

            if (count > 0)
            {
                Debug.Assert(QuickSortStack.Count == 0);

                if (elementIndexEnd > 0)
                {
                    elementIndexEnd--;
                }
                else
                {
                    segmentIndexEnd--;
                    Debug.Assert(segmentIndexEnd >= 0 && SegmentTable[segmentIndexEnd].Count > 0);
                    elementIndexEnd = SegmentTable[segmentIndexEnd].Count - 1;
                }

                QuickSortRange Range = new QuickSortRange()
                {
                    SegmentIndexFirst = segmentIndexBegin, ElementIndexFirst = elementIndexBegin, SegmentIndexLast = segmentIndexEnd, ElementIndexLast = elementIndexEnd
                };
                QuickSortStack.Push(Range);

                while (QuickSortStack.Count > 0)
                {
                    QuickSort(Comparer);
                }

                Debug.Assert(QuickSortStack.Count == 0);
            }

#if DEBUG
            AssertInvariant();
#endif
        }