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); } }
/// <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 }