歸併排序(MERGE-SORT)是創建在歸併操做上的一種有效的排序算法,該算法是採用分治法(Divide and Conquer)的一個很是典型的應用。html
將已有序的子序列合併,獲得徹底有序的序列;即先使每一個子序列有序,再使子序列段間有序。算法
若將兩個有序表合併成一個有序表,稱爲二路歸併。歸併排序是一種穩定的排序方法。數組
佔內存;ide
1. 申請空間,使其大小爲兩個已經排序序列之和,該空間用來存放合併後的序列;函數
2. 設定兩個指針,最初位置分別爲兩個已經排序序列的起始位置;性能
3. 比較兩個指針所指向的元素,選擇相對小的元素放入到合併空間,並移動指針到下一位置;spa
4. 重複步驟3直到某一指針超出序列尾;3d
5. 將另外一序列剩下的全部元素直接複製到合併序列尾指針
private static void MergeConsole(string location, int[] arr) { Console.Write($"{location}: "); foreach (var i in arr) { Console.Write("{0}\t", i); } Console.WriteLine(); } /// <summary> /// 歸併數組 /// </summary> /// <param name="arr">要歸併的數組</param> /// <param name="left">歸併左序列首元素下標</param> /// <param name="mid">拆分元素的下標</param> /// <param name="right">歸併右序列最後元素下標</param> private static void MergeArray(int[] arr, int left, int mid, int right) { int[] temp = new int[right - left + 1]; int m = left, n = mid + 1, k = 0; while (n <= right && m <= mid) { if (arr[m] > arr[n]) { temp[k++] = arr[n++]; } else { temp[k++] = arr[m++]; } } while (n < right + 1) { temp[k++] = arr[n++]; } while (m < mid + 1) { temp[k++] = arr[m++]; } for (k = 0, m = left; m < right + 1; k++, m++) { arr[m] = temp[k]; } } /// <summary> /// 歸併排序 /// </summary> /// <param name="arr">要歸併的數組</param> /// <param name="left">歸併左序列首元素下標</param> /// <param name="right">歸併右序列最後元素下標</param> public static void MergeSort(int[] arr, int left, int right) { if (left < right) { int mid = (left + right) / 2; MergeSort(arr, left, mid); MergeConsole("_left: ", arr); MergeSort(arr, mid + 1, right); MergeConsole("right: ", arr); MergeArray(arr, left, mid, right); MergeConsole("merge: ", arr); Console.WriteLine(); } } static void Main(string[] args) { int[] array = { 149, 100, 112, 38, 80, 35, 615, 297, 592, 976, 143, 217 }; MergeSort(array, 0, array.Length - 1); Console.ReadLine(); }
1. 時間複雜度:O(n log n),最好、最壞、平均時間複雜度都是同樣的,由於不關心要排序的數組初始狀態;code
2. 空間複雜度:O(n),在任意時刻只有一個函數執行,只有一個臨時的內存空間在使用;
3. 穩定性: 穩定;相同的值能夠選擇是放在左邊仍是右邊的。