代码参考《算法笔记》但稍有改动,使用语言C++。
#include <iostream>
using namespace std;
/**归并排序**/
//递归实现
const int maxn=100;
//将数组A的[L1,R1]和[L2,R2]区间合并为有序区间(L2即R1+1)
void _merge(int A[],int L1,int R1,int L2,int R2)
{
int temp[maxn]; //用于临时存放合并排序后的数组
int ptr_left=L1,ptr_right=L2,ptr_tmp=0;
while(ptr_left<=R1&&ptr_right<=R2)
{
if(A[ptr_left]<=A[ptr_right])
temp[ptr_tmp++]=A[ptr_left++];
else
temp[ptr_tmp++]=A[ptr_right++];
}
while(ptr_left<=R1)
temp[ptr_tmp++]=A[ptr_left++];
while(ptr_right<=R2)
temp[ptr_tmp++]=A[ptr_right++];
//将已排序合并的临时数组复制到A中
for(int i=0;i<ptr_tmp;i++)
A[L1+i]=temp[i];
}
//将数组A当前区间[left,right]进行归并排序(主排序函数)
void mergeSort_1(int A[],int left,int right)
{
if(left==right) //需要进行排序的数组范围内只有一个数据,不需排序
return;
int mid=left+(right-left)/2;
mergeSort_1(A,left,mid);
mergeSort_1(A,mid+1,right);
_merge(A,left,mid,mid+1,right); //将左区间和右区间进行排序合并
}
//非递归实现
//令步长step初值为2,将数组中每step个元素为一组进行内部排序,再令step*2,重复操作
//直到step/2超过元素个数n(step/2==n为边界条件,此时左区间为整个数组,右区间为空,即将整个数组进行合并)
void mergeSort_2(int A[],int left,int right)
{
int n=(right-left)+1; //元素个数
for(int step=2;step/2<=n;step*=2) //每step个元素为一组进行内部排序合并
{
for(int i=left;i<=right;i+=step) //i为每一小组的开头元素下标地址
{
int mid=i+step/2-1;
if(mid+1<=right) //判断小组是否只有一个元素,即右区间是否为空,为空则不用归并
_merge(A,i,mid,mid+1,min(i+step-1,right)); //min(i+step-1,n)是为了防止右区间的右边界超出边界
}
}
}
int main()
{
int A[9]={5,3,7,5,10,2,7,6,8};
mergeSort_1(A,0,8);
//输出测试
for(int i=0;i<9;i++)
cout<<A[i]<<" ";
cout<<endl;
int B[9]={5,3,7,5,10,2,7,6,8};
mergeSort_2(B,0,8);
//输出测试
for(int i=0;i<9;i++)
cout<<B[i]<<" ";
cout<<endl;
return 0;
}
对于非递归的合并排序,代码中的排序过程如下图: