归并排序大量引用了递归,尽管在代码上比较清晰,易于理解,但是会造成时间和空间上的性能损耗。考虑将递归转化成迭代。
/* 对顺序表L作归并非递归排序 */
void MergeSort2(SqList *L)
{
int* TR=(int* )malloc(L->length*sizeof(int) ) //申请额外空间
int k =1;
while(k<L->length)
{
MergePass(L->r, TR, k, L->length);
k=2*k; //子序列长度加倍
MergePass(TR, L->r, k, L->length);
k=2*k; //子序列长度加倍
}
}
非递归的迭代方法更加直截了当,从最小的序列开始归并直至完成。不需要像归并的递归算法一样,需要先拆分递归,再归并退出递归。下面是MergePass()代码的实现。
/* 将SR[]中相邻长度为s的子序列两两归并到TR[] */
void MergePass(int SR[], int TR[], int s, int n)
{
int i=1;
int j;
while(i <= n-2*s+1)
{
Merge(SR, TR, i, i+s-1, i+2*s-1); //两两归并
i= i+2*s;
}
if(i<n-s+1) //归并最后两个序列
Merge(SR, TR, i, i+s-1, n);
else //若最后只剩下单个子序列
for(j=i; j<=n;j++)
TR[j] = SR[j];
}