 <p>Heres an answer I cribbed, genericised and brought up to date from <a href="http://www.cs.nyu.edu/~vs667/articles/mergesort/" rel="nofollow">here</a></p> <pre><code>public static IList&lt;T&gt; MergeSort&lt;T&gt;( this IList&lt;T&gt; unsorted, IComparer&lt;T&gt; comparer = null) { if (unsorted == null || unsorted.Count &lt; 2) { return unsorted; } if (comparer == null) { comparer = Comparer&lt;T&gt;.Default; } IList&lt;T&gt; sorted = new List&lt;T&gt;(); int middle = (int)unsorted.Count/2; Ilist&lt;T&gt; left = unsorted.GetRange(0, middle); IList&lt;T&gt; right = unsorted.GetRange(middle, unsorted.Count - middle); var sortLeft = Task&lt;IList&lt;T&gt;&gt;.Factory.StartNew( () =&gt; left.MergeSort(comparer)); var sortRight = Task&lt;IList&lt;T&gt;&gt;.Factory.StartNew( () =&gt; right.MergeSort(comparer)); left = sortLeft.Result; right = sortRight.Result; int leftPtr = 0; int rightPtr = 0; for (int i = 0; i &lt; left.Count + right.Count; i++) { if (leftPtr == left.Count) { sorted.Add(right[rightPtr]); rightPtr++; } else if (rightPtr == right.Count) { sorted.Add(left[leftPtr]); leftPtr++; } else if (comparer.Compare(left[leftPtr], right[rightPtr]) &lt; 0) { sorted.Add(left[leftPtr]); leftPtr++; } else { sorted.Add(right[rightPtr]); rightPtr++; } } return sorted; } </code></pre> <p>This code, will use the default <code>IComparer&lt;T&gt;</code> unless you pass your own.</p> <p>As you can see this code self iterates on each half of the unsorted array, I've added some code using the <a href="http://msdn.microsoft.com/en-us/library/dd537613.aspx" rel="nofollow"><code>Task</code></a> TPL class to run those calls asynchronously on seperate threads.</p> <p>You could use the code like this,</p> <pre><code>var strings = new List&lt;string&gt; { "cixymn", "adfxij", "adxhxy", "abcdef", "iejfyq", "uqbzxo", "aaaaaa" }; var sortedStrings = strings.MergeSort(); </code></pre> <p>If the default string comparer is not lexicographical enough for you, you could instantiate and pass your a selected <a href="http://msdn.microsoft.com/en-us/library/system.stringcomparer.aspx" rel="nofollow"><code>StringComparer</code></a>, perhaps like this,</p> <pre><code>var sortedStrings = strings.MergeSort(StringComparer.OrdinalIgnoreCase); </code></pre> <p>In the unlikely event that none of the <code>StringComparer</code>s meet your requirements, you could write your own implementation of <code>IComparer&lt;string&gt;</code> and pass that to the <code>MergeSort</code> function instead.</p> <p>In any case, it makes sense to keep the merge sort generic and resuable for all types and pass the specialization into the function. </p>