合并排序算法体现了递归和分而治之的思想,代码如下
#include<iostream>
using namespace std;
void merge(int l, int r, int a[]);//合并
void mergesort(int ll, int lr, int rl, int rr, int a[],int *b);//排序
int main(){
int a[10];
for (int i = 0; i < 10; i++) {
cin >> a[i];//输入数组十个数字
}
int l = 0, r = 9;//左右边界确定
merge(l,r,a);//调用
for (int i = 0; i < 10; i++) {
cout << a[i] << " ";
}//输出
return 0;
}
void merge(int l, int r, int a[]) {
int mid = (l + r) / 2;//取中间值
int b[10] = { 0 };//定义数组b,用来排序
if (l == r) {
return;
}//结束条件
int ll = l, lr = mid;
merge(ll, lr, a);
int rl = mid + 1, rr = r;
merge(rl, rr, a);//更新边界并递归
mergesort(ll,lr,rl,rr,a,b);//排序
for (; ll <= rr; ll++) {
a[ll] = b[ll];
}
}
void mergesort(int ll, int lr, int rl, int rr, int a[],int *b) {
int t = ll;
while (ll <= lr && rl <= rr) {
if (a[ll] < a[rl]) {
b[t] = a[ll];
ll++;
}
else {
b[t] = a[rl];
rl++;
}
t++;
}
if (ll > lr) {
while (rl <= rr) {
b[t] = a[rl];
t++;
rl++;
}
return;
}
if (rl > rr) {
while (ll <= lr) {
b[t] = a[ll];
t++;
ll++;
}
}
}
原理:每次数组取半,当数组元素数目为一时返回,当两个merge(左区间数组和右区间数组)返回到同一层次时,调用mergesort排序。
如:数组32857:
第零层:32857
第一层:32 857
第二层:3 2 8 57
第三层: 5 7
由于从左到右:3比2先返回第一层,32比857先返回第零层,8比57先返回第一层,5比7先返回第二层
所以排序如下
1:3 2->2 3第一层
2:5 7->5 7第二层
3:8 5 7->5 7 8第一层
4:2 3 5 7 8->2 3 5 7 8第零层
时间复杂度:
可以看到该算法每次区间减半,栈高为log(n);
每层时间复杂度n
总时间复杂度总为nlog(n)。