归并排序思想:
1.把序列分为两部分,对两部分分别排序(拆分的边界条件:元素大于1个)
2.合并已排序两部分
1.把序列分为两部分,对两部分分别排序(拆分的边界条件:元素大于1个)
2.合并已排序两部分
时间复杂度分析:
T(1) = 1;
T(n) = 2*T(n/2) + a*n;(a为常数,每次合并时,复杂度为O(n))
= 2*(2*T(n/4)+a*n/2) + a*n
= 4*T(n/4) + 2*a*n
= 4*(2*T(n/8)+a*n/4) + 2*a*n
= 8*T(n/8) + 3*a*n
=......
= 2^k*T(1) + k*a*n (其中n==2^k,即k=log2(n))
= n + a*n*log2(n);
所以时间复杂度为O(nlogn)
#include <cstdio>
#include <iostream>
#define N 10005
using namespace std;
int a[N], b[N];//b为辅助数组,故空间复杂度为O(n)
void Merge(int a[], int s, int m, int e, int tmp[])
{
int p = 0, p1 = s, p2 = m + 1;
//开始合并
while (p1 <= m && p2 <= e)
{
if (a[p1] < a[p2])
tmp[p++] = a[p1++];
else
tmp[p++] = a[p2++];
}
while (p1 <= m)
tmp[p++] = a[p1++];
while (p2 <= m)
tmp[p++] = a[p2++];
for (int i = 0; i < p; i++)//把结果拷贝到全局数组a中
a[i + s] = tmp[i];
}
void Mergesort(int a[], int s, int e, int tmp[])
{
if (s < e)//分治终止条件s==e,即只剩下一个元素
{
int m = s + (e - s) / 2;
Mergesort(a, s, m, tmp);//分为两部分
Mergesort(a, m + 1, e, tmp);
Merge(a, s, m, e, tmp);//治:对两部分进行合并
}
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
Mergesort(a, 0, n - 1, b);//a为待排数组,中间两个参数代表对下标此范围内进行排序,b为辅助数组
for (int i = 0; i < n; i++)
printf("%d ", a[i]);
printf("\n");
return 0;
}