#include <stdio.h>
#define N 17
void print(int a[], int n)
{
int j;
for(j=0; j < n; j++)
{
if(a[j])
printf("%2d ", a[j]);
}
printf("\n");
}
/*将src[i…m]和src[m +1 …n]归并到辅助数组des[i…n]*/
void two_merge(int *src, int *des, int i, int m, int n)
{
int j, k;
for(j=m+1, k=i; i<=m && j<=n ; k++)
{
if(src[j] < src[i])
des[k] = src[j++];
else
des[k] = src[i++];
}
while(i <= m)
des[k++] = src[i++];
while(j <= n)
des[k++] = src[j++];
printf("合并结果: ");
print(des, N);
}
void merge_sort(int *s, int *d, int length)
{
int step = 1;
int *tmp, *src = s, *des = d;
int i;
/*先将src[0],src[1]合并为src1,src[2],src[3]合并为src2...,再将src1,src2合并...*/
while(step < length)
{
i = 0;
step *= 2; /*step的起始步长应该为2*/
while(i+step <= length) /*length/step能够整除的部分先合并*/
{
two_merge(src, des, i, i+step/2-1, i+step-1);
i = i + step;
}
if((i+step/2) < length) /*i==length表示刚好整除*/
/*除不够且能够合并的在这里合并*/
/*不能合并的状态举例:以step=4合并但是只余了<=2个元素*/
{
two_merge(src, des, i, i+step/2-1, length-1); /*i+step/2-1>length-1的时候two_merge函数会排错*/
}
tmp = src;
src = des;
des = tmp; /*交换src和des数组*/
}
}
int main()
{
int src[N] = {1, 3, 7, 6, 8, 10, 2, 5, 4, 9, 12, 11, 13, 17, 15, 14, 16};
int des[N] = {0};
merge_sort(src, des, N);
printf("排序之后的src:");
print(src, N);
printf("排序之后的des:");
print(des, N);
return 0;
}
程序运行结果:
N=13时
N=17时
分析:从程序输出的结果看,排好序的结果可能最终存放于src数组,也可能最终存放于des数组,这是因为在归并排序的时候,不停的再交换src和des数组,即把一个的合并结果放到另一个数组,另一个的合并结果又反过来放到当前的数组,如此交替,如果需要制定最终结果放到哪个数组,那么可以在merge_sort函数的末尾判断s与src的关系,再进行一次数据复制即可。
归并排序的特点:
时间复杂度:O(nlog(2^n)),因为对于归并排序来说,一个元素比较log(2^n)就会放到最终的位置上,一共有n个元素。
空间复杂度:O(n),用到了一个辅助数组。
稳定性:稳定。
原文地址:http://blog.csdn.net/laoniu_c/article/details/38657969