Merge Sort Implementation Any reviews/ways to speed up/general improvements for my Merge Sort? Maybe something to simplify it or add more to it?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace prjT02L08_Predator_Prey
{
    abstract class MergeSort
    {
        public static List&lt;Node&gt; Sort(List&lt;Node&gt; input)
        {
        List&lt;Node&gt; Result = new List&lt;Node&gt;();
        List&lt;Node&gt; Left = new List&lt;Node&gt;();
        List&lt;Node&gt; Right = new List&lt;Node&gt;();

        if (input.Count &lt;= 1)
            return input;

        int midpoint = input.Count / 2;
        for (int i = 0; i &lt; midpoint; i++)
            Left.Add(input[i]);
        for (int i = midpoint; i &lt; input.Count; i++)
            Right.Add(input[i]);

        Left = Sort(Left); //Recursion! :o
        Right = Sort(Right);
        Result = Merge(Left, Right);

        return Result;
    }

    private static List&lt;Node&gt; Merge(List&lt;Node&gt; Left, List&lt;Node&gt; Right)
    {
        List&lt;Node&gt; Result = new List&lt;Node&gt;();
        while (Left.Count &gt; 0 &amp;&amp; Right.Count &gt; 0)
        {
            if (Left[0].F &lt; Right[0].F)
            {
                Result.Add(Left[0]);
                Left.RemoveAt(0);
            }
            else
            {
                Result.Add(Right[0]);
                Right.RemoveAt(0);
            }
        }

        while (Left.Count &gt; 0)
        {
            Result.Add(Left[0]);
            Left.RemoveAt(0);
        }

        while (Right.Count &gt; 0)
        {
            Result.Add(Right[0]);
            Right.RemoveAt(0);
        }

        return Result;
    }
}
}
abstract class MergeSort


This class shouldn't be abstract, it should be static.

public static List&lt;Node&gt; Sort(List&lt;Node&gt; input)


Why does the method require List? Wouldn't it be better if it accepted any IList (or IReadOnlyList if you're on .Net 4.5)? Also, it would make sense to make your code generic, so that it would work on types other than Node.

List&lt;Node&gt; Result = new List&lt;Node&gt;();


The usual convention in C# is to name local variables in camelCase, not PascalCase.

return input;


Returning the input might be unexpected. If you don't want to change it, you should clearly document it.

Left.RemoveAt(0);


This is very inefficient operation for a List. Either use a collection that can do this efficiently (like LinkedList or Queue) or, even better, just use indexes instead of modifying the collection.



Your code also does a lot of copying and creating new lists. That's good for readability, but if you want your code to be fast, you need just two lists that you can modify.

You would need to work with sublists (list, start index, length), not whole lists. First, merge the 1-element sublists from list A to list B, then merge the 2-element sublists from B to A, etc.

Also, another optimization is not to start with 1-element sublists, but take advantage of the fast that there are likely to be some sorted sublists in the input already. This is especially effective if the input is already sorted (or mostly sorted). But I think it wouldn't work with your recursive approach.