递归的归并排序很常见,本文在递归的基础上,给出了非递归的写法。
//递归的写法
void Merge(vector<int>& ans, vector<int>& src, int left, int mid, int right) //对一个vector中两个排序好的部分进行合并
{
int i = left, j = mid+1, k=left;
while (i<=mid && j<=right)
{
ans[k++] = src[i] <= src[j] ? src[i++] : src[j++];
}
while (i<=mid) { ans[k++] = src[i++]; }
while (j<=right) { ans[k++] = src[j++];
}
}
void MergePass(vector<int>& ans, vector<int>& src, int left, int right)
{
int n = src.size();
vector<int> v3(n); //给出n的大小
if (left == right) ans[left] = src[left];
else {
int mid = (right - left)/2 + left;
MergePass(v3,src,left,mid);
MergePass(v3,src,mid+1,right); //将数据存放到v3中
Merge(ans,v3,left,mid,right); //将v3中的数据进行合并
}
}
void MergeSort(vector<int>& ans,vector<int>& src)
{
int n = src.size();
MergePass(ans,src,0,n-1);
}
//非递归的方法
void Merge(vector<int>& ans, vector<int>& src, int left, int mid, int right)
{
int i = left, j = mid+1, k=left;
while (i<=mid && j<=right)
{
ans[k++] = src[i] <= src[j] ? src[i++] : src[j++];
}
while (i<=mid) { ans[k++] = src[i++]; }
while (j<=right) { ans[k++] = src[j++];
}
}
void NiceMergePass(vector<int>& ans, vector<int>& src, int n, int s)
{
int i=0;
for (i;i+2*s-1<=n-1;i=i+2*s) //判断是否满足2s的大小,若满足,则可以进行2s大小的合并
{
Merge(ans,src,i,i+s-1,i+2*s-1);
}
if (i+s <= n-1) //此步为不够2s大小,但是大于s,比如s为4,剩下的数据为5,则将4个与一个进行合并
{
Merge(ans,src,i,i+s-1,n-1);
}
else //剩下的数据不够s
{
ans[i] = src[i];
i++;
}
}
void NiceMergeSort(vector<int>& src)
{
int n = src.size();
vector<int> ans(n);
int s = 1; //s为进行归并的大小,从1开始,成倍增长
while (s<n) //若s的大小大于vector的长度,则终止
{
NiceMergePass(ans,src,n,s); //将src分别进行两个s大小的合并,至ans中
s+=s;
NiceMergePass(src,ans,n,s); //将ans分别进行两个s大小的合并,至src中
s+=s;
}
}
河汉清且浅,相去复几许。