归并排序的思想是分治,即将大问题分解成小问题然后逐一解决,该算法先将所有数分成两个两个的很多份,然后两个两个的排序,然后将两个两个的合并成四个四个的,然后再排序,然后再合并成八个八个的再排序,那么如何将n个n(n=2,4,8,16…..)个的合并呢?原理就是例如对于四个四个的合并,由于之前两个四个数的序列是有序的,那么可以在O(n)的复杂度内将两个有序的序列合并成一个有序的序列,这就是归并排序的思想。
例如对于序列: 10 9 8 7 6 5 4 3 2 1
第一次先两个两个:
9 10 7 8 5 6 3 4 1 2
然后再合并成四个:
7 8 9 10 3 4 5 6 1 2
然后八个:
3 4 5 6 7 8 9 10 1 2
然后16个:
1 2 3 4 5 6 7 8 9 10
算法终止
这里采用的是递归的思想进行归并
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn = 1000 + 7;
int t[maxn]; //临时数组
void Sort(int l, int r, int* a) { // 将l 到 r的数字排序
int mid = l + (r - l) / 2;
if (r - l > 1) {
Sort(l, mid, a);
Sort(mid, r, a);
int L = l, R = mid, d = l;
while (L < mid || R < r) { //有序表的合并
if (R >= r || (L < mid && a[L] <= a[R])) t[d++] = a[L++];
else t[d++] = a[R++];
}
for (int i = l; i < r; ++i) a[i] = t[i]; //复制回原数组
}
}
int a[maxn];
int n;
int main() {
scanf("%d", &n);
for (int i = 0; i < n; ++i)
scanf("%d", &a[i]);
Sort(0, n, a);
for (int i = 0; i < n; ++i) printf("%d ", a[i]);
printf("\n");
return 0;
}