CSharp examples for System:Array Compare
Sorts a list or array in place. A supplied IComparer<T> is used to compare the items in the list.
using System.Collections.Generic; using System.Collections; using System;//from ww w. j ava 2s . c o m public class Main{ /// <summary> /// Sorts a list or array in place. A supplied IComparer<T> is used /// to compare the items in the list. /// </summary> /// <remarks><para>The Quicksort algorithms is used to sort the items. In virtually all cases, /// this takes time O(N log N), where N is the number of items in the list.</para> /// <para>Although arrays cast to IList<T> are normally read-only, this method /// will work correctly and modify an array passed as <paramref name="list"/>.</para></remarks> /// <param name="list">The list or array to sort.</param> /// <param name="comparer">The comparer instance used to compare items in the collection. Only /// the Compare method is used.</param> public static void SortInPlace<T>(IList<T> list, IComparer<T> comparer) { if(list == null) throw new ArgumentNullException("Cannot sort a 'null' list."); if(comparer == null) throw new ArgumentNullException("The comparer is 'null'."); // If we have an array, use the built-in array sort (faster than going through IList accessors // with virtual calls). if(list is T[]) { Array.Sort((T[]) list, comparer); return; } if(list.IsReadOnly) throw new ArgumentException("The list is readonly.", "list"); // Instead of a recursive procedure, we use an explicit stack to hold // ranges that we still need to sort. int[] leftStack = new int[32], rightStack = new int[32]; int stackPtr = 0; int l = 0; // the inclusive left edge of the current range we are sorting. int r = list.Count - 1; // the inclusive right edge of the current range we are sorting. T partition; // The partition value. // Loop until we have nothing left to sort. On each iteration, l and r contains the bounds // of something to sort (unless r <= l), and leftStack/rightStack have a stack of unsorted // pieces (unles stackPtr == 0). for(; ; ) { if(l == r - 1) { // We have exactly 2 elements to sort. Compare them and swap if needed. T e1, e2; e1 = list[l]; e2 = list[r]; if(comparer.Compare(e1, e2) > 0) { list[r] = e1; list[l] = e2; } l = r; // sort complete, find other work from the stack. } else if(l < r) { // Sort the items in the inclusive range l .. r // Get the left, middle, and right-most elements and sort them, yielding e1=smallest, e2=median, e3=largest int m = l + (r - l) / 2; T e1 = list[l], e2 = list[m], e3 = list[r], temp; if(comparer.Compare(e1, e2) > 0) { temp = e1; e1 = e2; e2 = temp; } if(comparer.Compare(e1, e3) > 0) { temp = e3; e3 = e2; e2 = e1; e1 = temp; } else if(comparer.Compare(e2, e3) > 0) { temp = e2; e2 = e3; e3 = temp; } if(l == r - 2) { // We have exactly 3 elements to sort, and we've done that. Store back and we're done. list[l] = e1; list[m] = e2; list[r] = e3; l = r; // sort complete, find other work from the stack. } else { // Put the smallest at the left, largest in the middle, and the median at the right (which is the partitioning value) list[l] = e1; list[m] = e3; list[r] = partition = e2; // Partition into three parts, items <= partition, items == partition, and items >= partition int i = l, j = r; T item_i, item_j; for(; ; ) { do { ++i; item_i = list[i]; } while(comparer.Compare(item_i, partition) < 0); do { --j; item_j = list[j]; } while(comparer.Compare(item_j, partition) > 0); if(j < i) break; list[i] = item_j; list[j] = item_i; // swap items to continue the partition. } // Move the partition value into place. list[r] = item_i; list[i] = partition; ++i; // We have partitioned the list. // Items in the inclusive range l .. j are <= partition. // Items in the inclusive range i .. r are >= partition. // Items in the inclusive range j+1 .. i - 1 are == partition (and in the correct final position). // We now need to sort l .. j and i .. r. // To do this, we stack one of the lists for later processing, and change l and r to the other list. // If we always stack the larger of the two sub-parts, the stack cannot get greater // than log2(Count) in size; i.e., a 32-element stack is enough for the maximum list size. if((j - l) > (r - i)) { // The right partition is smaller. Stack the left, and get ready to sort the right. leftStack[stackPtr] = l; rightStack[stackPtr] = j; l = i; } else { // The left partition is smaller. Stack the right, and get ready to sort the left. leftStack[stackPtr] = i; rightStack[stackPtr] = r; r = j; } ++stackPtr; } } else if(stackPtr > 0) { // We have a stacked sub-list to sort. Pop it off and sort it. --stackPtr; l = leftStack[stackPtr]; r = rightStack[stackPtr]; } else { // We have nothing left to sort. break; } } } #endregion Predicate operations #region Sorting /// <summary> /// Sorts a list or array in place. /// </summary> /// <remarks><para>The Quicksort algorithms is used to sort the items. In virtually all cases, /// this takes time O(N log N), where N is the number of items in the list.</para> /// <para>Values are compared by using the IComparable<T> /// interfaces implementation on the type T.</para> /// <para>Although arrays cast to IList<T> are normally read-only, this method /// will work correctly and modify an array passed as <paramref name="list"/>.</para></remarks> /// <param name="list">The list or array to sort.</param> public static void SortInPlace<T>(IList<T> list) where T : IComparable<T> { SortInPlace<T>(list, Comparer<T>.Default); } }