归并排序的优化
归并排序的图解
递归实现二路归并排序
#include
#include
using namespace std;
void merge(int arr[],int min,int m,int max){
int *tem=new int [max-min+1];
int k=0,i=min,j=m+1;
while(i<=m&&j<=max){
if(arr[i]>arr[j])
tem[k++]=arr[j++];
else
tem[k++]=arr[i++];
}
while(i<=m)tem[k++]=arr[i++];
while(j<=max)tem[k++]=arr[j++];
//for(int l=0;l<=max-min;l++)
//arr[l]=tem[l];//此处传递值是错误的,因为在一次循环中完成的是min到max的排序,
//只要把该区间的数值传递即可
for(int l=min,p=0;l<=max;p++,l++)
arr[l]=tem[p];
for(int ll=0;ll<10;ll++)//改代码可以清晰的看见排序过程,每次执行该函数的时候,
//就是对min到max的排序,而且在排序结束之后改变了原arr数组的值
cout<=max)
return;
else{
Msort(arr,min,(min+max)/2);
Msort(arr,(max+min)/2+1,max);
merge(arr,min,(min+max)/2,max);
}
}
int main(){
int arr[]={0,7,2,5,1,3,4,6,9,8};
Msort(arr,0,9);
for(int i=0;i<10;i++)
cout<
分析:如果对Merge的每个递归调用均局部声明一个临时数组,那么在任意时刻就可能有logn个数组处在活动期,对内存是一个极大的消耗。另外在分配和收回上也会消耗很多时间。
时间复杂度的推算很复杂,涉及到叠缩求和,我认为在Msort函数中调用了logn次merge函数,在merge函数的排序的时间复杂度是N所以整个的时间复杂度是nlogn
另外二路归并排序的迭代做法有效的防止了栈溢出,但是代码不够简洁,等我摸清楚后再更新
迭代实现二路递归排序
#include
#include
using namespace std;
void merge(int arr[],int min,int m,int max){
int *tem=new int [max-min+1];
int k=0,i=min,j=m+1;
while(i<=m&&j<=max){
if(arr[i]>arr[j])
tem[k++]=arr[j++];
else
tem[k++]=arr[i++];
}
while(i<=m)tem[k++]=arr[i++];
while(j<=max)tem[k++]=arr[j++];
for(int l=min,p=0;l<=max;p++,l++)
arr[l]=tem[p];
for(int ll=0;ll<10;ll++)
cout<
分析:其实递归和非递归的merge函数基本没什么变化,主要思想就是怎么将目标序列拆分,并按传入merge函数,merge(arr,i,i+step/2-1,min(n-1,i+step-1));中的i+step/2-1表示传入区间的中点,注意,该中点并非(min+max)/2,比如在区间为0 1 2 3 4 5 6 7 8 9 中,当步长为8时,前后区间的个数分别为8和2.
本来想使用vector数组,这样省去了动态申请数组的过程,无奈道行太浅,怎么都调试不出来。稍后再试试。
#include
#include
using namespace std;
void merge(vector&v,int min,int mid,int max){
vectors;
int i=min,j=mid+1;
while(i<=mid&&j<=max){
if(v[i]>=v[j])
s.push_back(v[j++]);
else
s.push_back(v[i++]);
}
while(i<=mid)
s.push_back(v[i++]);
while(j<=max)
s.push_back(v[j++]);
for(int l=min,k=0;l<=max;k++,l++)
v[l]=s[k];
cout<<"输出v";
for(int oo=0;oo&v,int min,int max){
if(min>=max)
return;
else{
Msort(v,min,(max+min)/2);
Msort(v,(min+max)/2+1,max);
merge(v,min,(min+max)/2,max);
}
}
int main(){
vectorv(10);
for(int i=0;i<10;i++)
v[i]=9-i;
Msort(v,0,9);
}
我特么折腾了几天总算折腾出来了,传参,传参啊,传参时只是传递了vector的值,在merge中修改时并没有真正的修改该数组,还是道行不够啊