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:
parent
48dce94f47
commit
e3ca928636
|
@ -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
|
||||
|
|
|
@ -38,13 +38,10 @@ namespace Nuclex.Support.Collections {
|
|||
public static void InsertionSort<TElement>(
|
||||
this IList<TElement> list, int startIndex, int count, IComparer<TElement> 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<TElement>.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sorts all the elements in an IList<T> 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
|
||||
|
|
Loading…
Reference in New Issue
Block a user