Implemented a messy QuickSort method for IList, appears to be working but needs to be cleaned and optimized still

git-svn-id: file:///srv/devel/repo-conversion/nusu@338 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
Markus Ewald 2022-11-02 22:27:51 +00:00
parent 48dce94f47
commit e3ca928636
2 changed files with 93 additions and 6 deletions

View File

@ -60,6 +60,21 @@ namespace Nuclex.Support.Collections {
); );
} }
/// <summary>Tests whether the insertion sort algorithm can be applied to 'Text' property works as expected</summary>
[Test]
public void QuickSortCanSortWholeList() {
var testList = new List<int>(capacity: 5) { 1, 5, 2, 4, 3 };
var testListAsIList = (IList<int>)testList;
testListAsIList.QuickSort(Comparer<int>.Default);
CollectionAssert.AreEqual(
new List<int>(capacity: 5) { 1, 2, 3, 4, 5 },
testList
);
}
} }
} // namespace Nuclex.Support.Collections } // namespace Nuclex.Support.Collections

View File

@ -38,13 +38,10 @@ namespace Nuclex.Support.Collections {
public static void InsertionSort<TElement>( public static void InsertionSort<TElement>(
this IList<TElement> list, int startIndex, int count, IComparer<TElement> comparer this IList<TElement> list, int startIndex, int count, IComparer<TElement> comparer
) { ) {
int index = startIndex; int rightIndex = startIndex;
int endIndex = startIndex + count - 1;
while(index < endIndex) { int lastIndex = startIndex + count - 1;
int rightIndex = index; for(int index = startIndex + 1; index <= lastIndex; ++index) {
++index;
TElement temp = list[index]; TElement temp = list[index];
while(rightIndex >= startIndex) { while(rightIndex >= startIndex) {
@ -57,6 +54,8 @@ namespace Nuclex.Support.Collections {
} }
list[rightIndex + 1] = temp; list[rightIndex + 1] = temp;
rightIndex = index;
} }
} }
@ -81,6 +80,79 @@ namespace Nuclex.Support.Collections {
InsertionSort(list, Comparer<TElement>.Default); InsertionSort(list, Comparer<TElement>.Default);
} }
/// <summary>
/// Sorts all the elements in an IList&lt;T&gt; using the quicksort algorithm
/// </summary>
/// <typeparam name="TElement">Type of elements the list contains</typeparam>
/// <param name="list">List in which a subset will be sorted</param>
/// <param name="comparer">Comparison function to use for comparing list elements</param>
public static void QuickSort<TElement>(
this IList<TElement> list, IComparer<TElement> comparer
) {
int rightIndex = list.Count - 1;
var spans = new Stack<int>();
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 } // namespace Nuclex.Support.Collections