Here is an implementation of the merge sort algorithm, which operates on a sequence/list of items:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace MergeSort
{
public static class MergeSort_Extensions
{
public static IEnumerable<T> MergeSort<T>(this IList<T> items, Comparison<T> comparison)
{
return MergeSortInternal<T>(items, items.Count, comparison);
}
public static IEnumerable<T> MergeSort<T>(this IEnumerable<T> items, Comparison<T> comparison)
{
return MergeSortInternal<T>(items, items.Count(), comparison);
}
private static IEnumerable<T> MergeSortInternal<T>(IEnumerable<T> items, int count, Comparison<T> comparison)
{
Debug.Assert(items != null);
Debug.Assert(comparison != null);
if (count == 0)
yield break;
if (count == 1)
{
yield return items.First();
yield break;
}
// sort both halves recursively
IEnumerator<T> enumA = MergeSortInternal<T>(items.Take<T>(count / 2), count / 2, comparison).GetEnumerator();
IEnumerator<T> enumB = MergeSortInternal<T>(items.Skip<T>(count / 2), count - count / 2, comparison).GetEnumerator();
bool movedA = enumA.MoveNext();
bool movedB = enumB.MoveNext();
Debug.Assert(movedA && movedB);
// merge
while (true)
{
if (comparison(enumA.Current, enumB.Current) > 0)
{
// swap enumerators
IEnumerator<T> iterTemp = enumA;
enumA = enumB;
enumB = iterTemp;
}
yield return enumA.Current;
if (enumA.MoveNext() == false)
{
// return the remaining items
do yield return enumB.Current;
while (enumB.MoveNext());
break;
}
}
}
}
}
P.S. The code was formatted with http://formatmysourcecode.blogspot.com/