diff --git a/Nuclex.Support (net-4.0).csproj b/Nuclex.Support (net-4.0).csproj
index 346adfe..65713bc 100644
--- a/Nuclex.Support (net-4.0).csproj
+++ b/Nuclex.Support (net-4.0).csproj
@@ -106,7 +106,9 @@
Deque.cs
-
+
+ IListExtensions.cs
+
@@ -119,7 +121,9 @@
ItemReplaceEventArgs.cs
-
+
+ ListSegment.cs
+
MultiDictionary.cs
diff --git a/Source/Collections/IListExtensions.Test.cs b/Source/Collections/IListExtensions.Test.cs
index 215089b..097e9ba 100644
--- a/Source/Collections/IListExtensions.Test.cs
+++ b/Source/Collections/IListExtensions.Test.cs
@@ -66,7 +66,7 @@ namespace Nuclex.Support.Collections {
var testList = new List(capacity: 5) { 1, 5, 2, 4, 3 };
var testListAsIList = (IList)testList;
- testListAsIList.QuickSort(Comparer.Default);
+ testListAsIList.QuickSort();
CollectionAssert.AreEqual(
new List(capacity: 5) { 1, 2, 3, 4, 5 },
diff --git a/Source/Collections/IListExtensions.cs b/Source/Collections/IListExtensions.cs
index b512525..ba46a0d 100644
--- a/Source/Collections/IListExtensions.cs
+++ b/Source/Collections/IListExtensions.cs
@@ -103,7 +103,7 @@ namespace Nuclex.Support.Collections {
/// Type of elements the list contains
/// List in which a subset will be sorted
public static void InsertionSort(this IList list) {
- InsertionSort(list, Comparer.Default);
+ InsertionSort(list, 0, list.Count, Comparer.Default);
}
///
@@ -111,68 +111,78 @@ namespace Nuclex.Support.Collections {
///
/// Type of elements the list contains
/// List in which a subset will be sorted
+ /// Index at which the sorting process will begin
+ /// Index one past the last element that will be sorted
+ /// Comparison function to use for comparing list elements
+ public static void QuickSort(
+ this IList list, int startIndex, int count, IComparer comparer
+ ) {
+ var remainingPartitions = new Stack();
+ remainingPartitions.Push(new Partition(startIndex, startIndex + count - 1));
+
+ while(remainingPartitions.Count > 0) {
+ Partition current = remainingPartitions.Pop();
+ int leftEnd = current.LeftmostIndex;
+ int rightEnd = current.RightmostIndex;
+
+ int pivotIndex = quicksortPartition(list, leftEnd, rightEnd, comparer);
+ if(pivotIndex - 1 > leftEnd) {
+ remainingPartitions.Push(new Partition(leftEnd, pivotIndex - 1));
+ }
+ if(pivotIndex + 1 < rightEnd) {
+ remainingPartitions.Push(new Partition(pivotIndex + 1, rightEnd));
+ }
+ }
+ }
+
+ ///
+ /// Sorts all the elements in an IList<T> using the insertion sort algorithm
+ ///
+ /// Type of elements the list contains
+ /// List in which a subset will be sorted
/// Comparison function to use for comparing list elements
public static void QuickSort(
this IList list, IComparer comparer
) {
- int rightIndex = list.Count - 1;
+ QuickSort(list, 0, list.Count, comparer);
+ }
- var remainingPartitions = new Stack();
- remainingPartitions.Push(new Partition(0, rightIndex));
+ ///
+ /// Sorts all the elements in an IList<T> using the insertion sort algorithm
+ ///
+ /// Type of elements the list contains
+ /// List in which a subset will be sorted
+ public static void QuickSort(this IList list) {
+ QuickSort(list, 0, list.Count, Comparer.Default);
+ }
- while(remainingPartitions.Count > 0) {
- Partition currentPartition = remainingPartitions.Pop();
+ private static int quicksortPartition(
+ IList list, int firstIndex, int lastIndex, IComparer comparer
+ ) {
+ TElement pivot = list[lastIndex];
+
+ // Set the high index element to its proper sorted position
+ int nextIndex = firstIndex;
+ for(int index = firstIndex; index < lastIndex; ++index) {
+ if(comparer.Compare(list[index], pivot) < 0) {
+ TElement temp = list[nextIndex];
+ list[nextIndex] = list[index];
+ list[index] = temp;
- int leftIndex = currentPartition.LeftmostIndex + 1;
- int pivotIndex = currentPartition.LeftmostIndex;
- rightIndex = currentPartition.RightmostIndex;
-
- TElement pivot = list[pivotIndex];
-
- if(leftIndex > rightIndex)
- continue;
-
- while(leftIndex < rightIndex) {
-
- while(leftIndex <= rightIndex) {
- if(comparer.Compare(list[leftIndex], pivot) > 0) {
- break;
- }
- ++leftIndex;
- }
-
- while(leftIndex <= rightIndex) {
- if(comparer.Compare(list[rightIndex], pivot) < 0) {
- break;
- }
-
- --rightIndex;
- }
-
- if(rightIndex >= leftIndex) {
- TElement temp = list[leftIndex];
- list[leftIndex] = list[rightIndex];
- list[rightIndex] = temp;
- }
-
- }
-
- if(pivotIndex <= rightIndex) {
- if(comparer.Compare(list[pivotIndex], list[rightIndex]) > 0) {
- TElement temp = list[pivotIndex];
- list[pivotIndex] = list[rightIndex];
- list[rightIndex] = temp;
- }
- }
-
- if(currentPartition.LeftmostIndex < rightIndex) {
- remainingPartitions.Push(new Partition(currentPartition.LeftmostIndex, rightIndex - 1));
- }
-
- if(currentPartition.RightmostIndex > rightIndex) {
- remainingPartitions.Push(new Partition(rightIndex + 1, currentPartition.RightmostIndex));
+ ++nextIndex;
}
}
+
+ // Set the high index value to its sorted position
+ {
+ TElement temp = list[nextIndex];
+ list[nextIndex] = list[lastIndex];
+ list[lastIndex] = temp;
+ }
+
+ // Returns the next sorting element location
+ return nextIndex;
+
}
}