算法 | 分治 | 归并排序
归并排序算法是一个非常经典的分治算法,和快速排序有些类似,都是将问题分解成规模更小的子问题,分别解决。但是快速排序的子问题求解完成之后就是最优解,无需进行处理。归并算法需要对分别排序完成的子序列进行合并操作。
合并操作非常简单,定义如下:每次取数组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; }