C# 歸併排序

世紀緣發表於2016-10-12
    class MergeSorter
    {
        public static int[] Sort(int[] data)
        {
            if (data == null || data.Length <= 1)
            {
                return data;
            }

            int avg = data.Length >> 1;

            int[] left = new int[avg];
            int[] right = new int[data.Length - avg];
            int[] result = new int[data.Length];

            for (int i = 0; i < data.Length; i++)
            {
                if (i < avg)
                {
                    left[i] = data[i];
                }
                else
                {
                    right[i - avg] = data[i];
                }
            }

            left = Sort(left);
            right = Sort(right);
            result = Merge(left,right);
            return result;
        }

        private static int[] Merge(int[] a, int[] b)
        {
            int[] result = new int[a.Length + b.Length];

            int i = 0, j = 0, k = 0;

            while (i < a.Length && j < b.Length)
            {
                if (a[i] < b[j])
                {
                    result[k++] = a[i++];
                }
                else
                {
                    result[k++] = b[j++];
                }
            }

            while (i < a.Length)
            {
                result[k++] = a[i++];
            }

            while (j < b.Length)
            {
                result[k++] = b[j++];
            }

            return result;
        }
    }


歸併排序:

歸併(Merge)排序法是將兩個(或兩個以上)有序表合併成一個新的有序表,即把待排序序列分為若干個子序列,每個子序列是有序的。然後再把有序子序列合併為整體有序序列。該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用。

將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱為2-路歸併。

假設我們有一個沒有排好序的序列,那麼首先我們使用分割的辦法將這個序列分割成一個一個已經排好序的子序列,然後再利用歸併的方法將一個個的子序列合併成排序好的序列。分割和歸併的過程可以看下面的圖例。



 從上圖可以看出,我們首先把一個未排序的序列從中間分割成2部分,再把2部分分成4部分,依次分割下去,直到分割成一個一個的資料,再把這些資料兩兩歸併到一起,使之有序,不停的歸併,最後成為一個排好序的序列。

如何把兩個已經排序好的子序列歸併成一個排好序的序列呢?可以參看下面的方法。

假設我們有兩個已經排序好的子序列。

序列A:1  23  34  65

序列B:2  13  14  87

那麼可以按照下面的步驟將它們歸併到一個序列中。

(1)首先設定一個新的數列C[8]。
         (2)A[0]和B[0]比較,A[0]= 1,B[0] = 2,A[0] < B[0],那麼C[0] = 1
         (3)A[1]和B[0]比較,A[1]= 23,B[0] = 2,A[1] > B[0],那麼C[1] = 2
         (4)A[1]和B[1]比較,A[1]= 23,B[1] = 13,A[1] > B[1],那麼C[2] = 13
         (5)A[1]和B[2]比較,A[1]= 23,B[2] = 14,A[1] > B[2],那麼C[3] = 14
         (6)A[1]和B[3]比較,A[1]= 23,B[3] = 87,A[1] < B[3],那麼C[4] = 23
         (7)A[2]和B[3]比較,A[2]= 34,B[3] = 87,A[2] < B[3],那麼C[5] = 34
         (8)A[3]和B[3]比較,A[3]= 65,B[3] = 87,A[3] < B[3],那麼C[6] = 65
         (9)最後將B[3]複製到C中,那麼C[7]= 87。歸併完成。 

 

原文連結:http://blog.163.com/pinbo_jiankun/blog/static/133546488201391831822169/


相關文章