Vastly simplified the quicksort implementation (split out the partition sorting code into a separate method like most code examples did)
git-svn-id: file:///srv/devel/repo-conversion/nusu@340 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
parent
a10d30e6ea
commit
41691ddf94
|
@ -106,7 +106,9 @@
|
||||||
<DependentUpon>Deque.cs</DependentUpon>
|
<DependentUpon>Deque.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Source\Collections\IListExtensions.cs" />
|
<Compile Include="Source\Collections\IListExtensions.cs" />
|
||||||
<Compile Include="Source\Collections\IListExtensions.Test.cs" />
|
<Compile Include="Source\Collections\IListExtensions.Test.cs">
|
||||||
|
<DependentUpon>IListExtensions.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Source\Collections\IMultiDictionary.cs" />
|
<Compile Include="Source\Collections\IMultiDictionary.cs" />
|
||||||
<Compile Include="Source\Collections\IObservableCollection.cs" />
|
<Compile Include="Source\Collections\IObservableCollection.cs" />
|
||||||
<Compile Include="Source\Collections\IRecyclable.cs" />
|
<Compile Include="Source\Collections\IRecyclable.cs" />
|
||||||
|
@ -119,7 +121,9 @@
|
||||||
<DependentUpon>ItemReplaceEventArgs.cs</DependentUpon>
|
<DependentUpon>ItemReplaceEventArgs.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Source\Collections\ListSegment.cs" />
|
<Compile Include="Source\Collections\ListSegment.cs" />
|
||||||
<Compile Include="Source\Collections\ListSegment.Test.cs" />
|
<Compile Include="Source\Collections\ListSegment.Test.cs">
|
||||||
|
<DependentUpon>ListSegment.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Source\Collections\MultiDictionary.cs" />
|
<Compile Include="Source\Collections\MultiDictionary.cs" />
|
||||||
<Compile Include="Source\Collections\MultiDictionary.ValueCollection.cs">
|
<Compile Include="Source\Collections\MultiDictionary.ValueCollection.cs">
|
||||||
<DependentUpon>MultiDictionary.cs</DependentUpon>
|
<DependentUpon>MultiDictionary.cs</DependentUpon>
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace Nuclex.Support.Collections {
|
||||||
var testList = new List<int>(capacity: 5) { 1, 5, 2, 4, 3 };
|
var testList = new List<int>(capacity: 5) { 1, 5, 2, 4, 3 };
|
||||||
var testListAsIList = (IList<int>)testList;
|
var testListAsIList = (IList<int>)testList;
|
||||||
|
|
||||||
testListAsIList.QuickSort(Comparer<int>.Default);
|
testListAsIList.QuickSort();
|
||||||
|
|
||||||
CollectionAssert.AreEqual(
|
CollectionAssert.AreEqual(
|
||||||
new List<int>(capacity: 5) { 1, 2, 3, 4, 5 },
|
new List<int>(capacity: 5) { 1, 2, 3, 4, 5 },
|
||||||
|
|
|
@ -103,7 +103,7 @@ namespace Nuclex.Support.Collections {
|
||||||
/// <typeparam name="TElement">Type of elements the list contains</typeparam>
|
/// <typeparam name="TElement">Type of elements the list contains</typeparam>
|
||||||
/// <param name="list">List in which a subset will be sorted</param>
|
/// <param name="list">List in which a subset will be sorted</param>
|
||||||
public static void InsertionSort<TElement>(this IList<TElement> list) {
|
public static void InsertionSort<TElement>(this IList<TElement> list) {
|
||||||
InsertionSort(list, Comparer<TElement>.Default);
|
InsertionSort(list, 0, list.Count, Comparer<TElement>.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -111,68 +111,78 @@ namespace Nuclex.Support.Collections {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TElement">Type of elements the list contains</typeparam>
|
/// <typeparam name="TElement">Type of elements the list contains</typeparam>
|
||||||
/// <param name="list">List in which a subset will be sorted</param>
|
/// <param name="list">List in which a subset will be sorted</param>
|
||||||
|
/// <param name="startIndex">Index at which the sorting process will begin</param>
|
||||||
|
/// <param name="count">Index one past the last element that 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, int startIndex, int count, IComparer<TElement> comparer
|
||||||
|
) {
|
||||||
|
var remainingPartitions = new Stack<Partition>();
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sorts all the elements in an IList<T> using the insertion sort 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>
|
/// <param name="comparer">Comparison function to use for comparing list elements</param>
|
||||||
public static void QuickSort<TElement>(
|
public static void QuickSort<TElement>(
|
||||||
this IList<TElement> list, IComparer<TElement> comparer
|
this IList<TElement> list, IComparer<TElement> comparer
|
||||||
) {
|
) {
|
||||||
int rightIndex = list.Count - 1;
|
QuickSort(list, 0, list.Count, comparer);
|
||||||
|
}
|
||||||
|
|
||||||
var remainingPartitions = new Stack<Partition>();
|
/// <summary>
|
||||||
remainingPartitions.Push(new Partition(0, rightIndex));
|
/// Sorts all the elements in an IList<T> using the insertion sort algorithm
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TElement">Type of elements the list contains</typeparam>
|
||||||
|
/// <param name="list">List in which a subset will be sorted</param>
|
||||||
|
public static void QuickSort<TElement>(this IList<TElement> list) {
|
||||||
|
QuickSort(list, 0, list.Count, Comparer<TElement>.Default);
|
||||||
|
}
|
||||||
|
|
||||||
while(remainingPartitions.Count > 0) {
|
private static int quicksortPartition<TElement>(
|
||||||
Partition currentPartition = remainingPartitions.Pop();
|
IList<TElement> list, int firstIndex, int lastIndex, IComparer<TElement> 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;
|
++nextIndex;
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user