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
					
				
					 3 changed files with 71 additions and 57 deletions
				
			
		|  | @ -106,7 +106,9 @@ | |||
|       <DependentUpon>Deque.cs</DependentUpon> | ||||
|     </Compile> | ||||
|     <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\IObservableCollection.cs" /> | ||||
|     <Compile Include="Source\Collections\IRecyclable.cs" /> | ||||
|  | @ -119,7 +121,9 @@ | |||
|       <DependentUpon>ItemReplaceEventArgs.cs</DependentUpon> | ||||
|     </Compile> | ||||
|     <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.ValueCollection.cs"> | ||||
|       <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 testListAsIList = (IList<int>)testList; | ||||
|        | ||||
|       testListAsIList.QuickSort(Comparer<int>.Default); | ||||
|       testListAsIList.QuickSort(); | ||||
| 
 | ||||
|       CollectionAssert.AreEqual( | ||||
|         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> | ||||
|     /// <param name="list">List in which a subset will be sorted</param> | ||||
|     public static void InsertionSort<TElement>(this IList<TElement> list) { | ||||
|       InsertionSort(list, Comparer<TElement>.Default); | ||||
|       InsertionSort(list, 0, list.Count, Comparer<TElement>.Default); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|  | @ -111,68 +111,78 @@ namespace Nuclex.Support.Collections { | |||
|     /// </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="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> | ||||
|     public static void QuickSort<TElement>( | ||||
|       this IList<TElement> list, IComparer<TElement> comparer | ||||
|     ) { | ||||
|       int rightIndex = list.Count - 1; | ||||
| 
 | ||||
|       var remainingPartitions = new Stack<Partition>(); | ||||
|       remainingPartitions.Push(new Partition(0, rightIndex)); | ||||
| 
 | ||||
|       while(remainingPartitions.Count > 0) { | ||||
|         Partition currentPartition = remainingPartitions.Pop(); | ||||
| 
 | ||||
|         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; | ||||
|       QuickSort(list, 0, list.Count, comparer); | ||||
|     } | ||||
| 
 | ||||
|           while(leftIndex <= rightIndex) { | ||||
|             if(comparer.Compare(list[rightIndex], pivot) < 0) { | ||||
|               break; | ||||
|     /// <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> | ||||
|     public static void QuickSort<TElement>(this IList<TElement> list) { | ||||
|       QuickSort(list, 0, list.Count, Comparer<TElement>.Default); | ||||
|     } | ||||
| 
 | ||||
|             --rightIndex; | ||||
|           } | ||||
|     private static int quicksortPartition<TElement>( | ||||
|       IList<TElement> list, int firstIndex, int lastIndex, IComparer<TElement> comparer | ||||
|     ) { | ||||
|       TElement pivot = list[lastIndex]; | ||||
|        | ||||
|           if(rightIndex >= leftIndex) { | ||||
|             TElement temp = list[leftIndex]; | ||||
|             list[leftIndex] = list[rightIndex]; | ||||
|             list[rightIndex] = temp; | ||||
|           } | ||||
|       // 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; | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         if(pivotIndex <= rightIndex) { | ||||
|           if(comparer.Compare(list[pivotIndex], list[rightIndex]) > 0) { | ||||
|             TElement temp = list[pivotIndex]; | ||||
|             list[pivotIndex] = list[rightIndex]; | ||||
|             list[rightIndex] = temp; | ||||
|           ++nextIndex; | ||||
|         } | ||||
|       } | ||||
|      | ||||
|         if(currentPartition.LeftmostIndex < rightIndex) { | ||||
|           remainingPartitions.Push(new Partition(currentPartition.LeftmostIndex, rightIndex - 1)); | ||||
|       // Set the high index value to its sorted position | ||||
|       { | ||||
|         TElement temp = list[nextIndex]; | ||||
|         list[nextIndex] = list[lastIndex]; | ||||
|         list[lastIndex] = temp; | ||||
|       } | ||||
| 
 | ||||
|         if(currentPartition.RightmostIndex > rightIndex) { | ||||
|           remainingPartitions.Push(new Partition(rightIndex + 1, currentPartition.RightmostIndex)); | ||||
|         } | ||||
|       } | ||||
|       // Returns the next sorting  element location | ||||
|       return nextIndex; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|   } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue