From a10d30e6ea9de850fc11286af1b880b20aeb1330 Mon Sep 17 00:00:00 2001 From: Markus Ewald Date: Wed, 2 Nov 2022 22:39:33 +0000 Subject: [PATCH] Created a separate 'Partition' structure for the QuickSort() method so the Stack (used to avoid recursion) is a bit cleaner git-svn-id: file:///srv/devel/repo-conversion/nusu@339 d2e56fa2-650e-0410-a79f-9358c0239efd --- Source/Collections/IListExtensions.cs | 52 +++++++++++++++++++-------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/Source/Collections/IListExtensions.cs b/Source/Collections/IListExtensions.cs index 5891a90..b512525 100644 --- a/Source/Collections/IListExtensions.cs +++ b/Source/Collections/IListExtensions.cs @@ -27,6 +27,32 @@ namespace Nuclex.Support.Collections { /// Extension methods for the IList interface public static class ListExtensions { + #region struct Partition + + /// + /// Stores the left and right index of a partition for the quicksort algorithm + /// + private struct Partition { + + /// + /// Initializes a new partition using the specified left and right index + /// + /// Index of the leftmost element in the partition + /// Index of the rightmost element in the partition + public Partition(int leftmostIndex, int rightmostIndex) { + this.LeftmostIndex = leftmostIndex; + this.RightmostIndex = rightmostIndex; + } + + /// Index of the leftmost element in the partition + public int LeftmostIndex; + /// Index of the rightmost element in the partition + public int RightmostIndex; + + } + + #endregion // struct Partition + /// /// Sorts a subset of the elements in an IList<T> using the insertion sort algorithm /// @@ -91,17 +117,15 @@ namespace Nuclex.Support.Collections { ) { int rightIndex = list.Count - 1; - var spans = new Stack(); - spans.Push(0); - spans.Push(rightIndex); + var remainingPartitions = new Stack(); + remainingPartitions.Push(new Partition(0, rightIndex)); - while(spans.Count > 0) { - int partitionRightEndIndex = spans.Pop(); - int partitionLeftEndIndex = spans.Pop(); + while(remainingPartitions.Count > 0) { + Partition currentPartition = remainingPartitions.Pop(); - int leftIndex = partitionLeftEndIndex + 1; - int pivotIndex = partitionLeftEndIndex; - rightIndex = partitionRightEndIndex; + int leftIndex = currentPartition.LeftmostIndex + 1; + int pivotIndex = currentPartition.LeftmostIndex; + rightIndex = currentPartition.RightmostIndex; TElement pivot = list[pivotIndex]; @@ -141,14 +165,12 @@ namespace Nuclex.Support.Collections { } } - if(partitionLeftEndIndex < rightIndex) { - spans.Push(partitionLeftEndIndex); - spans.Push(rightIndex - 1); + if(currentPartition.LeftmostIndex < rightIndex) { + remainingPartitions.Push(new Partition(currentPartition.LeftmostIndex, rightIndex - 1)); } - if(partitionRightEndIndex > rightIndex) { - spans.Push(rightIndex + 1); - spans.Push(partitionRightEndIndex); + if(currentPartition.RightmostIndex > rightIndex) { + remainingPartitions.Push(new Partition(rightIndex + 1, currentPartition.RightmostIndex)); } } }