Mega Code Archive

 
Categories / C# / Collections Data Structure
 

A simple stable sorting routine - far from being efficient, only for small collections

#region License /*  * Copyright  2002-2005 the original author or authors.  *   * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *   *      http://www.apache.org/licenses/LICENSE-2.0  *   * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  */ #endregion #region Imports using System; using System.Collections; using System.Reflection; #endregion namespace Spring.Util {     /// <summary>     /// Miscellaneous collection utility methods.     /// </summary>     /// <remarks>     /// Mainly for internal use within the framework.     /// </remarks>     /// <author>Mark Pollack (.NET)</author>     public sealed class CollectionUtils     {         /// <summary>         /// A callback method used for comparing to items.         /// </summary>         /// <remarks>         /// </remarks>         /// <param name="left">the first object to compare</param>         /// <param name="right">the second object to compare</param>         /// <returns>Value Condition Less than zero x is less than y. Zero x equals y. Greater than zero x is greater than y.</returns>         /// <seealso cref="IComparer.Compare"/>         /// <seealso cref="CollectionUtils.StableSort(IEnumerable,CompareCallback)"/>         public delegate int CompareCallback(object left, object right);         /// <summary>         /// A simple stable sorting routine - far from being efficient, only for small collections.         /// </summary>         /// <param name="input"></param>         /// <param name="comparer"></param>         /// <returns></returns>         public static ICollection StableSort(IEnumerable input, IComparer comparer)         {             return StableSort(input, new CompareCallback(comparer.Compare));         }         /// <summary>         /// A simple stable sorting routine - far from being efficient, only for small collections.         /// </summary>         /// <remarks>         /// Sorting is not(!) done in-place. Instead a sorted copy of the original input is returned.         /// </remarks>         /// <param name="input">input collection of items to sort</param>         /// <param name="comparer">the <see cref="CompareCallback"/> for comparing 2 items in <paramref name="input"/>.</param>         /// <returns>a new collection of stable sorted items.</returns>         public static ICollection StableSort(IEnumerable input, CompareCallback comparer)         {             ArrayList ehancedInput = new ArrayList();             IEnumerator it = input.GetEnumerator();             int index = 0;             while (it.MoveNext())             {                 ehancedInput.Add(new Entry(index, it.Current));                 index++;             }             ehancedInput.Sort(Entry.GetComparer(comparer));             for (int i = 0; i < ehancedInput.Count; i++)             {                 ehancedInput[i] = ((Entry)ehancedInput[i]).Value;             }             return ehancedInput;         }         /// <summary>         /// A simple stable sorting routine - far from being efficient, only for small collections.         /// </summary>         /// <remarks>         /// Sorting is not(!) done in-place. Instead a sorted copy of the original input is returned.         /// </remarks>         /// <param name="input">input collection of items to sort</param>         /// <param name="comparer">the <see cref="IComparer"/> for comparing 2 items in <paramref name="input"/>.</param>         /// <returns>a new collection of stable sorted items.</returns>         public static void StableSortInPlace(IList input, IComparer comparer)         {             StableSortInPlace(input, new CompareCallback(comparer.Compare));         }         /// <summary>         /// A simple stable sorting routine - far from being efficient, only for small collections.         /// </summary>         /// <remarks>         /// Sorting is not(!) done in-place. Instead a sorted copy of the original input is returned.         /// </remarks>         /// <param name="input">input collection of items to sort</param>         /// <param name="comparer">the <see cref="CompareCallback"/> for comparing 2 items in <paramref name="input"/>.</param>         /// <returns>a new collection of stable sorted items.</returns>         public static void StableSortInPlace(IList input, CompareCallback comparer)         {             ArrayList ehancedInput = new ArrayList();             IEnumerator it = input.GetEnumerator();             int index = 0;             while (it.MoveNext())             {                 ehancedInput.Add(new Entry(index, it.Current));                 index++;             }             ehancedInput.Sort(Entry.GetComparer(comparer));             for (int i = 0; i < ehancedInput.Count; i++)             {                 input[i] = ((Entry)ehancedInput[i]).Value;             }         }         #region StableSort Utility Classes         private class Entry         {             private class EntryComparer : IComparer             {                 private readonly CompareCallback innerComparer;                 public EntryComparer(CompareCallback innerComparer)                 {                     this.innerComparer = innerComparer;                 }                 public int Compare(object x, object y)                 {                     Entry ex = (Entry)x;                     Entry ey = (Entry)y;                     int result = innerComparer(ex.Value, ey.Value);                     if (result == 0)                     {                         result = ex.Index.CompareTo(ey.Index);                     }                     return result;                 }             }             public static IComparer GetComparer(CompareCallback innerComparer)             {                 return new EntryComparer(innerComparer);             }             public readonly int Index;             public readonly object Value;             public Entry(int index, object value)             {                 Index = index;                 Value = value;             }         }         #endregion     } }