归并排序的基础概念就不讲了,我的博客只会写有创造性的东西。
归并排序的代码如下:
void mergesort(int* arr,int n){
if(n>1){
mergesort(arr,n/2);
mergesort(arr+n/2,n-n/2);
merge(buff,arr,n/2,arr+n/2,n-n/2);
memcpy(arr,buff,n);
}
}
迭代版
标准的归并排序是个递归过程,不过要用迭代过程表达也很简单,就是先两个两个一排,再四个四个一排。。。。
如:
98 15 73 20 76 27 34 82
15 98 20 73 27 76 34 82 //第一趟
15 20 73 98 27 34 76 82 //第二趟
15 20 27 34 73 76 82 98 //第三趟
代码不写了,代码比递归版的复杂一点,效率也提高了一点
原地归并算法
标准归并排序使用的归并算法要额外申请一个大小为n的数组暂时存放归并数据,原地归并算法就不用,不过要以时间为代价,它的一次归并过程的时间复杂度是O(n^2)。
举个例子:
15 20 76 98 27 34 73 82
这里有两段有序数组,检测到应该把27、34、73插入到20和76之间,也就是把
76 98 27 34 73 这段数组循环左移两位。
如何把数组循环左移k位呢?
用的是翻大饼算法,先把前k个元素翻转过来,再把后n-k个元素翻转过来,在翻转这n个元素。
过