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-路歸併。
假設我們有一個沒有排好序的序列,那麼首先我們使用分割的辦法將這個序列分割成一個一個已經排好序的子序列,然後再利用歸併的方法將一個個的子序列合并成排序好的序列。分割和歸併的過程可以看下面的圖例。
從可以看出,我們首先把一個未排序的序列從中間分割成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。歸併完成。
C#移位元運算(左移和右移)
歸併排序,時間複雜度為O(nlogn)。
歸併排序的效率是比較高的,設數列長為N,將數列分開成小數列一共要logN步,每步都是一個合并有序數列的過程,時間複雜度可以記為O(N),故一共為O(N*logN)。因為歸併排序每次都是在相鄰的資料中進行操作,所以歸併排序在O(N*logN)的幾種排序方法(快速排序,歸併排序,希爾排序,堆排序)也是效率比較高的。
以上就是 C# 歸併排序的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!