迭代法实现归并排序

本文探讨如何在面试中实现归并排序的迭代版本。通常归并排序采用递归方式,但通过迭代同样可以达到相同效果。我们将分析迭代过程的关键步骤和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

归并排序往往以递归的形式实现,如果面试官要求你实现一个迭代版本,又该如何实现呢?

首先给出常见的递归版本:

<span style="font-family:Times New Roman;font-size:14px;">static void merge(int a[], int left, int mid, int right, int temp[])
{
   int i = left, j = mid+1, k = 0;
   while(i <= mid && j <= right)
   {
	   if(a[i] <= a[j])
		   temp[k++] = a[i++];
	   else
		   temp[k++] = a[j++];
   }
   while(i <= mid)
	   temp[k++] = a[i++];
   while(j <= right)
	   temp[k++] = a[j++];
   for(int idx = 0; idx < k; idx++)
	   a[idx+left] = temp[idx];
}

static void mergeSort2(int ar[], int left, int right, int temp[])
{
	if(left < right)
	{
		int mid = (right - left)/2 + left;
		mergeSort2(ar, left, mid, temp);
		mergeSort2(ar, mid+1, right, temp);
		merge(ar, left, mid, right, temp);
	}
}
void mergeSortRecur(int a[], int len)
{
	int *temp = (int *)malloc(sizeof(int)*len);
	mergeSort2(a, 0, len-1, temp);
}</span>

其原理不再详细阐述,下面给出迭代版本(其中merge 函数和递归版本的一样),参考自点击打开链接,附带部分注释:

<span style="font-family:Times New Roman;font-size:14px;">static void mergePass(int a[], int temp[], int s, int n)
{
	int i = 0;
	while(i < n - 2 * s)
	{
		merge(a, i , i+s-1, i + 2 * s -1, temp);
		//Merge two adjacent segments of size s
		i = i + 2 * s;
	}
	 // fewer than 2s elements remain
	//possible 1,(s, 2s) left
	if(i + s < n)
		merge(a,  i, i + s-1, n-1, temp);
	else   //possible 2, (0, 2)left
		for(int j = i; j <= n-1; j++)
			temp[j] = a[j];
}
void mergeSortItera(int a[], int len)
{
	int *temp = (int *)malloc(sizeof(int)*len);
	int start = 1;
	while(start  < len)
	{
		mergePass(a, temp, start, len);
		start += start;
        /*mergePass(temp, a, start, len);
		start += start;*/
	}
}</span>
可以看出,迭代版的归并排序依然需要 O(n) 的额外空间,其首先设置步长为1,然后逐步加倍,完成归排序过程。边界条件是,在某个步长处,可能存在不能等分的情况,此时需要视情况而定。设步长为s,则不外乎如下两种情况:1、剩下的元素个数为 (s, 2*s) ,2、剩下的元素个数为 (0, s) 。前者可以再次归并,后者按照元素原来的顺序拷贝回去就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值