tsJensen

A quest for software excellence...

Insertion Sort and Sorted Merge in C#

Update (9/6/2014) - Updated code on GitHub with performance enhancement to sorted merge algorithm.

As promised a few days ago, here’s the first installment in the algorithm series. A simple insertion sort and the previous sorted merge combine to provide you with a quick way to sort and merge multiple arrays without copying data from one array to another. You can find complete code and tests on GitHub.

Here’s the insertion sort code:

/// <summary>
/// Simple insertion sort of IList or array in place.
/// </summary>
/// <typeparam name="T">Type to be sorted.</typeparam>
/// <param name="data">IList or array to be sorted.</param>
public static void InsertionSort<T>(IList<T> data) 
   where T : IComparable
{
   if (data == null || data.Count < 2) return;
   for (int keyIndex = 1; keyIndex < data.Count; keyIndex++)
   {
      var key = data[keyIndex];
      var priorIndex = keyIndex - 1;
      while (priorIndex > -1 
         && data[priorIndex] != null 
         && data[priorIndex].CompareTo(key) > 0)
      {
         data[priorIndex + 1] = data[priorIndex];
         priorIndex -= 1;
      }
      data[priorIndex + 1] = key;
   }
}

And here’s one test example:

[TestMethod]
public void CombinedMergeSortTest()
{
   IList<MergeSortTestData> a = new List<MergeSortTestData> 
   { 
      new MergeSortTestData { Name = "Robert", Age = 43.5 },
      null,
   };
   IList<MergeSortTestData> b = new List<MergeSortTestData> 
   { 
      new MergeSortTestData { Name = "Robert", Age = 23.5 },
      null,
   };

   Sorter.InsertionSort(a);
   Sorter.InsertionSort(b);

   MergeSortTestData prev = null;
   int count = 0;
   foreach (var val in Merger.SortedMerge<MergeSortTestData>(a, b))
   {
      if (null != val) Assert.IsTrue(val.CompareTo(prev) > 0);
      prev = val;
      count++;
   }
   Assert.AreEqual(count, 4);
}


public class MergeSortTestData : IComparable
{
   public string Name { get; set; }
   public double Age { get; set; }

   public int CompareTo(object obj)
   {
      var other = obj as MergeSortTestData;
      if (null == other) return 1; //null is always less
      if (this.Name == other.Name)
      {
         return this.Age.CompareTo(other.Age);
      }
      return this.Name.CompareTo(other.Name);
   }
}