源码 

using System;
using System.Text;

public class 归并
{
    private 归并()
    {

    }
    private static int depth = 0;
    public static void Sort<T>(T[] arr) where T : IComparable<T>
    {
        Sort(arr, 0, arr.Length - 1);
        depth = 0;
    }
    private static void Sort<T>(T[] arr, int l, int r) where T : IComparable<T>
    {
        if (l >= r) return;
        int mid = l + ((r - l)) / 2;
        Sort(arr, l, mid);
        Sort(arr, mid + 1, r);
        morge(arr, l, mid, r);
        StringBuilder stringBuilder = new StringBuilder();
        for (var i = 0; i < arr.Length; i++)
        {
            stringBuilder.Append("_" + arr[i]);
        }
        System.Console.WriteLine(stringBuilder.ToString());

    }
    /// <summary>
    /// 合并两个有用的区间Arr【l,mid】  arr[mid+1,r]
    /// </summary>
    /// <param name="arr"></param>
    /// <param name="l"></param>
    /// <param name="mid"></param>
    /// <param name="r"></param>
    /// <typeparam name="T"></typeparam>
    private static void morge<T>(T[] arr, int l, int mid, int r) where T : IComparable<T>
    {
        // System.Console.WriteLine("R:" + (r - l));

        T[] tempArr = new T[r - l + 1];

        int copynum = l;
        for (var m = 0; m < tempArr.Length; m++)
        {
            tempArr[m] = arr[copynum++];

        }

        int i = l, j = mid + 1;
        for (var k = l; k <= r; k++)
        {
            if (i > mid)
            {
                arr[k] = tempArr[j - l]; j++;
            }
            else if (j > r)
            {
                arr[k] = tempArr[i - l]; i++;
            }
            else if (tempArr[i - l].CompareTo(tempArr[j - l]) <= 0)
            {
                arr[k] = tempArr[i - l]; i++;
            }
            else
            {
                arr[k] = tempArr[j - l]; j++;

            }
        }
    }
}

 带log版本 新增自低向上排序算法

using System;
using System.Text;

public class MergeSort
{
    private MergeSort()
    {

    }
    public static void Sort<T>(T[] arr) where T : IComparable<T>
    {
        Sort(arr, 0, arr.Length - 1, 0);
    }
    private static string generateDepthString(int count)
    {

        StringBuilder stringBuilder = new StringBuilder();
        for (var i = 0; i < count; i++)
        {
            stringBuilder.Append("-");
        }
        return stringBuilder.ToString();
    }
    private static void Sort<T>(T[] arr, int l, int r, int depth) where T : IComparable<T>
    {
        // 生成深度字符串
        string depthString = generateDepthString(depth);

        // 打印当前 sort 处理的数组区间信息
        // System.Console.Write(depthString);
        // System.Console.WriteLine(string.Format("mergesort arr[{0}, {1}]", l, r));



        if (l >= r) return;
        int mid = l + (r - l) / 2;
        Sort(arr, l, mid, depth + 1);
        Sort(arr, mid + 1, r, depth + 1);


        // 打印这次 merge 要处理的区间范围
        // System.Console.Write(depthString);
        // System.Console.WriteLine(string.Format("merge arr[{0}, {1}] and arr[{2}, {3}]", l, mid, mid + 1, r));
        morge(arr, l, mid, r);
        // // 打印 merge 后的数组
        // System.Console.Write(depthString);
        // System.Console.WriteLine(string.Format("after mergesort arr[{0}, {1}] :", l, r));
        // for (E e: arr)
        //     System.out.print(e + " ");
        // System.out.println();
        // for (var i = 0; i < arr.Length; i++)
        // {
        //     System.Console.Write(" " + arr[i]);
        // }
        // System.Console.WriteLine();
    }
    //合并两个有序的区间arr[l,mid] arr[mid+1 ,r]
    private static void morge<T>(T[] arr, int l, int mid, int r) where T : IComparable<T>
    {
        T[] tempArr = new T[r - l + 1];
        // T[] temp = System.Array.Copy()
        // System.Array.Copy( arr,temp,)

        int copynum = l;
        for (var m = 0; m < tempArr.Length; m++)
        {
            tempArr[m] = arr[copynum++];
        }

        int i = l, j = mid + 1;
        //对arr[k] 进行赋值
        for (var k = l; k <= r; k++)
        {
            if (i > mid)
            {
                arr[k] = tempArr[j - l]; j++;
            }
            else if (j > r)
            {
                arr[k] = tempArr[i - l]; i++;
            }
            else if (tempArr[i - l].CompareTo(tempArr[j - l]) <= 0)
            {
                arr[k] = tempArr[i - l]; i++;
            }
            else
            {
                arr[k] = tempArr[j - l]; j++;
            }

        }
    }
    /// <summary>
    /// 优化版 归并排序 算法
    /// </summary>
    /// <param name="arr"></param>
    /// <typeparam name="T"></typeparam>
    public static void Sort2<T>(T[] arr) where T : IComparable<T>
    {
        T[] tempArr = new T[arr.Length];
        System.Array.Copy(arr, tempArr, arr.Length);
        Sort2(arr, tempArr, 0, arr.Length - 1, 0);
    }

    private static void Sort2<T>(T[] arr, T[] tempArr, int l, int r, int depth) where T : IComparable<T>
    {
        // 生成深度字符串
        // string depthString = generateDepthString(depth);

        // 打印当前 sort 处理的数组区间信息
        // System.Console.Write(depthString);
        // System.Console.WriteLine(string.Format("mergesort arr[{0}, {1}]", l, r));

        // if (l >= r) return;
        // 改为插入排序
        if (r - l <= 15)
        {
            // 调用 插入排序算法类中的方法 如果不存在就调用下面的
            InsertionSort.Sort(arr, l, r);
            //本类插入排序
            // insertionSort(arr, l, r);
            return;
        }
        int mid = l + (r - l) / 2;
        Sort2(arr, tempArr, l, mid, depth + 1);
        Sort2(arr, tempArr, mid + 1, r, depth + 1);

        // 打印这次 merge 要处理的区间范围
        // System.Console.Write(depthString);
        // System.Console.WriteLine(string.Format("merge arr[{0}, {1}] and arr[{2}, {3}]", l, mid, mid + 1, r));
        if (arr[mid].CompareTo(arr[mid + 1]) < 0) return;
        morge2(arr, tempArr, l, mid, r);
        // 打印 merge 后的数组
        // System.Console.Write(depthString);
        // System.Console.WriteLine(string.Format("after mergesort arr[{0}, {1}] :", l, r));

        // for (var i = 0; i < arr.Length; i++)
        // {
        //     System.Console.Write(" " + arr[i]);
        // }
        // System.Console.WriteLine();
    }
    //合并两个有序的区间arr[l,mid] arr[mid+1 ,r]

    //插入排序算法
    private static void morge2<T>(T[] arr, T[] tempArr, int l, int mid, int r) where T : IComparable<T>
    {
        System.Array.Copy(arr, l, tempArr, l, r - l + 1);

        int copynum = l;

        int i = l, j = mid + 1;
        //对arr[k] 进行赋值
        for (var k = l; k <= r; k++)
        {
            if (i > mid)
            {
                arr[k] = tempArr[j]; j++;
            }
            else if (j > r)
            {
                arr[k] = tempArr[i]; i++;
            }
            else if (tempArr[i].CompareTo(tempArr[j]) <= 0)
            {
                arr[k] = tempArr[i]; i++;
            }
            else
            {
                arr[k] = tempArr[j]; j++;
            }

        }
    }
    public static void insertionSort<T>(T[] data, int l, int r) where T : IComparable<T>
    {
        for (var i = l; i <= r; i++)
        {
            T temp = data[i];
            int j;
            for (j = i; j > l; j--)
            {
                if (temp.CompareTo(data[j - 1]) < 0)
                {
                    data[j] = data[j - 1];
                }
                else
                {
                    break;
                }
            }
            data[j] = temp;
        }
    }
    //自低向上的归并排序算法
    public static void SortBU<T>(T[] data) where T : IComparable<T>
    {
        int n = data.Length;
        T[] temparray = new T[n];

        System.Array.Copy(data, temparray, n);
        for (var i = 0; i < n; i += 16)
        {
            InsertionSort.Sort(data, i, Math.Min(n - 1, i + 15));
            //或者
            // insertionSort(data,i, Math.Min(n - 1, i + 15));
        }
        // 遍历合并的区间长度
        // 注意,sz 从 16 开始
        for (var sz = 16; sz < n; sz += sz)
        {
            for (var i = 0; i + sz < n; i += sz + sz)
            {
                if (data[i + sz - 1].CompareTo(data[i + sz]) > 0)
                    morge2(data, temparray, i, i + sz - 1, Math.Min(n - 1, i + sz + sz - 1));
            }
        }

    }
}

测试

using System;
using System.IO;
using System.Net;
using System.Text;
using LitJson;

namespace myCode
{
    class Program
    {
        static void Main(string[] args)
        {
            //回文.LongestPalindrome("mmmmmmm");
            // XXCZ();
            //TestNumber();
            // TestGenerate();
            // TestSelectionSort();

            // var tenpArray = ArrayGenerator.GenerateOrderArray(1000, 0, 12999);
            // TestAction(() =>
            // {
            //     TestSelectionSortperformance(tenpArray);
            // });
            // System.Console.WriteLine(SortingHelper.isSortwd(tenpArray));


            Sort();
        }
        static void Sort()
        {

            int[] datasize = { 100000 };
            foreach (var item in datasize)
            {
                //无序 随机
                var tenpArray = ArrayGenerator.GenerateOrderArray(item, 0, item);
                int[] arrays = new int[tenpArray.Length];
                System.Array.Copy(tenpArray, arrays, tenpArray.Length);

                //完全有序  MergeSort2 情况 会变成on级别的排序算法
                // var tenpArray = ArrayGenerator.GenerateOrderArray(item);
                // int[] arrays = new int[tenpArray.Length];
                // System.Array.Copy(tenpArray, arrays, tenpArray.Length);
                try
                {
                    // TestSort("SelectionSort", tenpArray);
                    // TestSort("InsertionSort2", arrays);
                    // TestSort("SelectionSort", tenpArray);
                    // TestSort("SelectionSort", tenpArray);
                    // TestSort("InsertionSort", tenpArray);

                    //TestSort("MergeSort", arrays);
                    TestSort("MergeSort2", tenpArray);
                    TestSort("归并BU", arrays);

                }
                catch (System.Exception e)
                {
                    System.Console.WriteLine(e.Message);
                    // throw;
                }
            }
        }


        static void TestSort<T>(string soreName, T[] dataArray) where T : IComparable<T>
        {

            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();  //开始监视代码运行时间
                            //需要测试的代码

            // StringBuilder stringBuilder = new StringBuilder();
            // for (var i = 0; i < dataArray.Length; i++)
            // {
            //     stringBuilder.Append("_" + dataArray[i]);
            // }
            // System.Console.WriteLine("未排序 :" + stringBuilder.ToString());

            if (soreName.Equals("SelectionSort"))
            {
                SelectionSort.Sort(dataArray);
            }
            else if (soreName.Equals("InsertionSort"))
            {
                InsertionSort.Sort(dataArray);
            }
            else if (soreName.Equals("InsertionSort2"))
            {
                InsertionSort.Sort2(dataArray);
            }
            else if (soreName.Equals("MergeSort"))
            {
                MergeSort.Sort(dataArray);
            }
            else if (soreName.Equals("MergeSort2"))
            {
                MergeSort.Sort2(dataArray);
            }
            else if (soreName.Equals("归并BU"))
            {
                MergeSort.SortBU(dataArray);
            }

            watch.Stop();  //停止监视

            // StringBuilder stringBuilder2 = new StringBuilder();
            // for (var i = 0; i < dataArray.Length; i++)
            // {
            //     stringBuilder2.Append("_" + dataArray[i]);
            // }
            // System.Console.WriteLine("已经排序:" + stringBuilder2.ToString());

            TimeSpan timespan = watch.Elapsed;  //获取当前实例测量得出的总时间
            if (!SortingHelper.isSortwd(dataArray))
            {

                throw new Exception(" 没有经过排序 + sort name :" + soreName);
            }
            string log = string.Format("排序的名字【{0}】,排序的执行时间【{1}(毫秒)】 排序数组长度【{2}】", soreName, timespan.TotalMilliseconds, dataArray.Length);
            // System.Console.WriteLine("打开窗口代码执行时间:{0}(毫秒)", timespan.TotalMilliseconds);  //总毫秒数
            System.Console.WriteLine(log);
        }
        public static T[] TestSelectionSortperformance<T>(T[] tenpArray) where T : IComparable<T>
        {

            SelectionSort.Sort(tenpArray);
            return tenpArray;
            // Equatable(tenpArray);
        }
        public static void TestSelectionSort()
        {
            int[] arr = { 1, 3, 4, 57, 867, 34, 2, 6, };
            string[] selectA = { "A", "B", "C", "FD", "DW" };
            Student[] students = { new Student("AA", 20), new Student("BB", 23), new Student("CC", 100) };
            SelectionSort.Sort(arr);
            SelectionSort.Sort(selectA);
            SelectionSort.Sort(students);
            Equatable(arr);
            Equatable(selectA);
            Equatable(students);
        }
        public static void Equatable<T>(T[] data)
        {
            StringBuilder stringBuilder = new StringBuilder();
            for (var i = 0; i < data.Length; i++)
            {
                stringBuilder.Append("_" + data[i].ToString());
            }
            System.Console.WriteLine(stringBuilder.ToString());
        }
        public static void TestGenerate()
        {
            int[] testArray = ArrayGenerator.GenerateOrderArray(100000);

            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();  //开始监视代码运行时间
                            //需要测试的代码

            var res = 线性查找.search(testArray, 100000);
            watch.Stop();  //停止监视
            TimeSpan timespan = watch.Elapsed;  //获取当前实例测量得出的总时间
            System.Console.WriteLine("打开窗口代码执行时间:{0}(毫秒)", timespan.TotalMilliseconds);  //总毫秒数
            System.Console.WriteLine("res :" + res);
        }

        static void XXCZ()
        {
            // 线性查找 xxcz = new 线性查找();
            int[] data = { 23, 45, 1, 35, 12, 567, 124, 4 };
            string[] strs = { "123", "SS", "ss" };

            // Student[] students = { new Student("hh"),
            // new Student("sh"), new Student("qq") };
            // // var res = 线性查找.search(data, 12);
            // // var res = 线性查找.search(strs, "ss");
            // var res = 线性查找.search(students,
            // new Student("qq"));
            // System.Console.WriteLine("res :" + res);

        }
        static void TestNumber()
        {
            Random rnd = new Random();
            for (int ctr = 0; ctr <= 9; ctr++)
            {
                int randomN = rnd.Next(Int32.MinValue, Int32.MaxValue);
                Number n = new Number(randomN);
                Console.WriteLine("n = {0,12}, hash code = {1,12}", n, n.GetHashCode());
            }
        }






    }
}

public struct Number
{
    private int n;

    public Number(int value)
    {
        n = value;
    }

    public int Value
    {
        get { return n; }
    }

    public override bool Equals(Object obj)
    {
        if (obj == null || !(obj is Number))
            return false;
        else
            return n == ((Number)obj).n;
    }

    public override int GetHashCode()
    {
        return n;
    }

    public override string ToString()
    {
        return n.ToString();
    }
}

// The example displays output like the following:
//       n =   -634398368, hash code =   -634398368
//       n =   2136747730, hash code =   2136747730
//       n =  -1973417279, hash code =  -1973417279
//       n =   1101478715, hash code =   1101478715
//       n =   2078057429, hash code =   2078057429
//       n =   -334489950, hash code =   -334489950
//       n =    -68958230, hash code =    -68958230
//       n =   -379951485, hash code =   -379951485
//       n =    -31553685, hash code =    -31553685
//       n =   2105429592, hash code =   2105429592
using System;

public class ArrayGenerator
{
    public ArrayGenerator()
    {

    }
    public static int[] GenerateOrderArray(int n)
    {
        int[] arr = new int[n];
        for (var i = 0; i < n; i++)
        {
            arr[i] = i;
        }
        return arr;
    }
    public static int[] GenerateOrderArray(int n, int min, int max)
    {
        int[] arr = new int[n];
        Random random = new Random();

        for (var i = 0; i < n; i++)
        {
            arr[i] = random.Next(min, max);
        }
        return arr;
    }
}