C# 歸併排序

黄舟
發布: 2017-02-09 16:17:20
原創
1502 人瀏覽過

 C# 歸併排序

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
namespace Sort  
{  
    class MergeSorter  
    {  
        /// <summary>  
        /// 归并排序之归:归并排序入口   
        /// </summary>  
        /// <param name="data">无序数组</param>  
        /// <returns>有序数组</returns>  
         public static int[] Sort(int[] data)  
        {  
            //若data为null,或只剩下1 or 0个元素,返回,不排序  
            if (null == data || data.Length <= 1)  
            {  
                return data;  
            }  
            //取数组中间下标  
            int middle = data.Length >> 1;  
            //初始化临时数组let,right,并定义result作为最终有序数组,若数组元素奇数个,将把多余的那元素空间预留在right临时数组  
            int[] left = new int[middle];  
            int[] right =  new int[data.Length - middle];  
            int[] result = new int[data.Length];  
            for (int i = 0; i < data.Length; i++)  
            {  
                if (i < middle)  
                {  
                    left[i] = data[i];  
                }  
                else  
                {  
                    right[i-middle] = data[i]; //此处i-middle,让我省掉定义一个j,性能有所提高  
                }  
            }  
            left = Sort(left);//递归左数组  
            right = Sort(right);//递归右数组  
            result = Merge(left, right);//开始排序  
            return result;  
        }  
        /// <summary>  
        /// 归并排序之并:排序在这一步  
        /// </summary>  
        /// <param name="a">左数组</param>  
        /// <param name="b">右数组</param>  
        /// <returns>合并左右数组排序后返回</returns>  
         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-路歸併。

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

C# 歸併排序


從上圖可以看出,我們先把一個未排序的序列從中間分割成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] (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] (7)A[2]和B[3]比較,A[2] = 34,B[3] = 87,A[2] (8)A[3]和B[3]比較,A[3] = 65,B[ 3] = 87,A[3] (9)最後將B[3]複製到C中,則C[7] = 87。歸併完成。 


C#移位運算(左移與右移)


歸併排序,時間複雜度為O(nlogn)。

歸併排序的效率是比較高的,設數列長為N,將數列分開成小數列一共要logN步,每步都是一個合併有序數列的過程,時間複雜度可以記為O(N) ,故一共為O(N*logN)。因為歸併排序每次都是在相鄰的資料中進行操作,所以歸併排序在O(N*logN)的幾種排序方法(快速排序,歸併排序,希爾排序,堆排序)也是效率比較高的。

以上就是 C# 歸併排序的內容,更多相關內容請關注PHP中文網(www.php.cn)!


相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板