#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