/// <include file='../docs.xml' /// path='docs/doc[@name="M:PeterO.ArrayUtil.StableSort``1(System.Collections.Generic.IList{``0})"]/*'/> public static void StableSort <T>(IList <T> list) where T : IComparable <T> { if (list == null) { throw new ArgumentNullException("list"); } var da = new DeferredArray <T>(list.Count); StableSortInternal( list, 0, list.Count, Comparer <T> .Default, da); }
/// <include file='../docs.xml' /// path='docs/doc[@name="M:PeterO.ArrayUtil.Sort(System.Int32[])"]/*'/> public static void Sort(int[] array) { if (array == null) { throw new ArgumentNullException("array"); } var defarray = new DeferredArray <int>(array.Length); StableSortInternal( array, 0, array.Length, Comparer <int> .Default, defarray); }
/// <include file='../docs.xml' /// path='docs/doc[@name="M:PeterO.ArrayUtil.Sort``1(System.Collections.Generic.IList{``0},System.Int32,System.Int32,System.Collections.Generic.IComparer{``0})"]/*'/> public static void Sort <T>( IList <T> list, int offset, int count, IComparer <T> comparer) { if (list == null) { throw new ArgumentNullException("list"); } if (offset < 0) { throw new ArgumentException("offset (" + offset + ") is less than 0"); } if (offset > list.Count) { throw new ArgumentException("offset (" + offset + ") is more than " + list.Count); } if (count < 0) { throw new ArgumentException("count (" + count + ") is less than 0"); } if (count > list.Count) { throw new ArgumentException("count (" + count + ") is more than " + list.Count); } if (list.Count - offset < count) { throw new ArgumentException("list's length minus " + offset + " (" + (list.Count - offset) + ") is less than " + count); } if (comparer == null) { throw new ArgumentNullException("comparer"); } var da = new DeferredArray <T>(list.Count); StableSortInternal( list, offset, count, comparer, da); }
/// <include file='../docs.xml' /// path='docs/doc[@name="M:PeterO.ArrayUtil.StableSort``1(System.Collections.Generic.IList{``0},System.Collections.Generic.IComparer{``0})"]/*'/> public static void StableSort <T>(IList <T> list, IComparer <T> comparer) { if (list == null) { throw new ArgumentNullException("list"); } if (comparer == null) { throw new ArgumentNullException("comparer"); } var da = new DeferredArray <T>(list.Count); StableSortInternal( list, 0, list.Count, comparer, da); }
private static void StableSortInternal <T>( IList <T> list, int a, int n, IComparer <T> comparer, DeferredArray <T> tempArray) { #if DEBUG if (list == null) { throw new ArgumentNullException("list"); } if (a < 0) { throw new ArgumentException("a (" + a + ") is less than 0"); } if (a > list.Count) { throw new ArgumentException("a (" + a + ") is more than " + list.Count); } if (n < 0) { throw new ArgumentException("n (" + n + ") is less than 0"); } if (n > list.Count) { throw new ArgumentException("n (" + n + ") is more than " + list.Count); } if (list.Count - a < n) { throw new ArgumentException("list's length minus " + a + " (" + (list.Count - a) + ") is less than " + n); } if (comparer == null) { throw new ArgumentNullException("comparer"); } #endif int pl, pm; T tmp; if (n < 7) { // Use insertion sort (already a stable sort) for (pm = a + 1; pm < a + n; ++pm) { for (pl = pm; pl > a && comparer.Compare(list[pl - 1], list[pl]) > 0; --pl) { tmp = list[pl]; list[pl] = list[pl - 1]; list[pl - 1] = tmp; } } return; } var middle = n >> 1; StableSortInternal(list, a, middle, comparer, tempArray); StableSortInternal(list, a + middle, n - middle, comparer, tempArray); if (comparer.Compare(list[a + middle - 1], list[a + middle]) <= 0) { return; } var right = a + n; middle = a + middle; var temp = tempArray.GetArray(); var i = a; var j = a; var k = middle; while (j < middle && k < right) { // "<=" ensures stable sort var leq = comparer.Compare(list[j], list[k]) <= 0; temp[i++] = leq ? list[j++] : list[k++]; } while (j < middle) { temp[i++] = list[j++]; } for (i = a; i < k; ++i) { list[i] = temp[i]; } }