二路歸併排序
阿新 • • 發佈:2019-02-10
歸併排序是建立在歸併操作操作上的一種有效的排序演算法。該演算法是採用分治法的一個非常典型的應用。將已有序的子序列合併,得到完整有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱為二路歸併。
演算法描述:
- 把長度為n的輸入序列分為兩個長度為n/2的子序列
- 對這兩個子序列分別採用歸併排序
- 將兩個排序好的子序列合併成一個最終的排序序列
程式碼實現:
# include<stdio.h> # include<stdlib.h> # include<assert.h> void Meger(int *arr, int len, int width) { int low1 = 0; int high1 = low1 + width - 1; int low2 = high1 + 1; int high2 = low2 + width - 1 < len - 1 ? low2 + width - 1 : len - 1; int *brr = (int *)malloc(sizeof(int)* len); assert(brr != NULL); int index = 0; while (low1 < len)//只要有一個段還沒合併進brr中,迴圈都得執行 { //按順序歸併兩個相鄰的段,退出時,有可能第一個段資料歸併完成,也有可能第二個段資料歸併完成 while (low1 <= high1 && low2 <= high2) { if (arr[low1] < arr[low2]) { brr[index++] = arr[low1++]; } else { brr[index++] = arr[low2++]; } } while (low1 <= high1) { brr[index++] = arr[low1++]; } while (low2 <= high2) { brr[index++] = arr[low2++]; } low1 = high2 + 1; high1 = low1 + width - 1 < len - 1 ? low1 + width - 1 : len - 1; low2 = high1 + 1; high2 = low2 + width - 1 < len - 1 ? low2 + width - 1 : len - 1; } for (int i = 0; i < len; ++i) { arr[i] = brr[i]; } free(brr); } void MegerSort(int *arr, int len) { for (int i = 1; i < len; i *= 2) { Meger(arr, len, i); } } void Show(int *arr, int len) { for (int i = 0; i < len; i++) { printf("%d ", arr[i]); } printf("\n"); } int main() { int arr[] = { 2, 7, 96, 45, 32, 45, 76, 29, 94 }; int len = sizeof(arr) / sizeof(arr[0]); Show(arr, len); MegerSort(arr, len); Show(arr, len); return 0; }
演算法特性:
時間複雜度 | 空間複雜度 | 穩定性 |
O(nlogn) | O(n) | 穩定 |