diff --git a/Source/Collections/IListExtensions.Test.cs b/Source/Collections/IListExtensions.Test.cs
index ae1b27e..215089b 100644
--- a/Source/Collections/IListExtensions.Test.cs
+++ b/Source/Collections/IListExtensions.Test.cs
@@ -60,6 +60,21 @@ namespace Nuclex.Support.Collections {
);
}
+ /// Tests whether the insertion sort algorithm can be applied to 'Text' property works as expected
+ [Test]
+ public void QuickSortCanSortWholeList() {
+ var testList = new List(capacity: 5) { 1, 5, 2, 4, 3 };
+ var testListAsIList = (IList)testList;
+
+ testListAsIList.QuickSort(Comparer.Default);
+
+ CollectionAssert.AreEqual(
+ new List(capacity: 5) { 1, 2, 3, 4, 5 },
+ testList
+ );
+ }
+
+
}
} // namespace Nuclex.Support.Collections
diff --git a/Source/Collections/IListExtensions.cs b/Source/Collections/IListExtensions.cs
index c00e025..5891a90 100644
--- a/Source/Collections/IListExtensions.cs
+++ b/Source/Collections/IListExtensions.cs
@@ -38,13 +38,10 @@ namespace Nuclex.Support.Collections {
public static void InsertionSort(
this IList list, int startIndex, int count, IComparer comparer
) {
- int index = startIndex;
- int endIndex = startIndex + count - 1;
+ int rightIndex = startIndex;
- while(index < endIndex) {
- int rightIndex = index;
-
- ++index;
+ int lastIndex = startIndex + count - 1;
+ for(int index = startIndex + 1; index <= lastIndex; ++index) {
TElement temp = list[index];
while(rightIndex >= startIndex) {
@@ -57,6 +54,8 @@ namespace Nuclex.Support.Collections {
}
list[rightIndex + 1] = temp;
+
+ rightIndex = index;
}
}
@@ -81,6 +80,79 @@ namespace Nuclex.Support.Collections {
InsertionSort(list, Comparer.Default);
}
+ ///
+ /// Sorts all the elements in an IList<T> using the quicksort 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;
+
+ var spans = new Stack();
+ spans.Push(0);
+ spans.Push(rightIndex);
+
+ while(spans.Count > 0) {
+ int partitionRightEndIndex = spans.Pop();
+ int partitionLeftEndIndex = spans.Pop();
+
+ int leftIndex = partitionLeftEndIndex + 1;
+ int pivotIndex = partitionLeftEndIndex;
+ rightIndex = partitionRightEndIndex;
+
+ 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(partitionLeftEndIndex < rightIndex) {
+ spans.Push(partitionLeftEndIndex);
+ spans.Push(rightIndex - 1);
+ }
+
+ if(partitionRightEndIndex > rightIndex) {
+ spans.Push(rightIndex + 1);
+ spans.Push(partitionRightEndIndex);
+ }
+ }
+ }
+
}
} // namespace Nuclex.Support.Collections