演算法 | 分治 | 歸併排序
阿新 • • 發佈:2018-12-30
歸併排序演算法是一個非常經典的分治演算法,和快速排序有些類似,都是將問題分解成規模更小的子問題,分別解決。但是快速排序的子問題求解完成之後就是最優解,無需進行處理。歸併演算法需要對分別排序完成的子序列進行合併操作。
合併操作非常簡單,定義如下:每次取陣列a和b第一個元素中較小者放入新的佇列,直到有個佇列為空,然後將另一個佇列中的元素全部放入新的佇列。
當問題分解成只剩下一個元素的子問題時,必然有序,成為問題分解的邊界。
輸入要求
多組輸入。
每行輸入一組用空格分隔的數字,第一個數字N表示接下來會跟上多少個數字。(100個以內)
輸出要求
輸出排序後的N個數字,用空格隔開。對於每組資料佔一行
測試資料
輸入示例
5 5 4 3 2 1
輸出示例
1 2 3 4 5
小貼士
本題只能採用歸併排序演算法(分治/遞迴),其他演算法不得分
#include<stdio.h> int b[100]; //作為排序結果暫存陣列 void Merge(int c[], int d[], int l, int m, int r) { int i = l, j = m + 1, k = l; while ((i <= m) && (j <= r)) { if (c[i] <= c[j]) { d[k++] = c[i++]; } else { d[k++] = c[j++]; } } if (i > m) { for (int q = j; q <= r; q++) { d[k++] = c[q]; } } else { for (int q = i; q <= r; q++) { d[k++] = c[q]; } } } void Copy(int a[], int b[], int left, int right) { for (int i = left; i <= right; i++) { a[i] = b[i]; } } void MergeSort(int a[],int left,int right) { int mid; if (left < right) { mid = (left + right) >> 1; //取中間值 MergeSort(a, left, mid); //分: left~mid 範圍進行 MergeSort(a, mid + 1, right); //分:mid+1 ~ right 範圍進行 Merge(a, b, left, mid, right); // 治 Copy(a, b, left, right); } } void print(int a[],int n) { for (int i = 1; i <= n; i++) { if (i != 1) { printf(" "); } printf("%d", a[i]); } printf("\n"); } int main() { int a[100]; int n; while (~scanf("%d", &n)) { for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); } MergeSort(a, 1, n); print(a, n); } return 0; }