归并排序的非递归实现

归并排序的递归算法代码虽然简单,但是递归函数每一次调用自身都会开辟一个栈空间,使它的空间复杂度增加。而非递归算法不会因为函数嵌套次数太多造成栈溢出。

递归算法是通过递归最后分成两个数一组进行排序,非递归是直接把两个数一组进行排序,再分成四个数一组排序,最后把数组分成两组,结束。

非递归算法原理

例如
2 1 5 7 4 3
非递归的思路有点类似希尔排序中的消除逆序对。
假设我们需排序的数字存在数组res[],让dlta=1(dlta是左部分和右部分的元素个数 即子序列长度为2*dlt=2)先用i记录2的下标,消除逆序对2和1后;再移动到5,消除逆序对5和7;再移动到4,消除逆序对4和3;再回到res[0],此时dlta=2(即子序列长度为4),消除2 1 5 7中的逆序对,再移动到4,消除 7 2中的逆序对;再回到a[0],直到dlta>=数组长度,结束。
具体代码

void Mergesort(int res[], int left, int right,int n)//n是要排序的数组长度 
{
	int t[n];//创立临时数组 
	int dlta = 1;//希尔排序中dlta是增量 这里是左部分和右部分的元素个数 即子序列长度为2*dlta 
	while (dlta < n)
	{
		//排序数组 2 1 5 7 4 3
		for (int i = 0; i <= right; i = i + 2 * dlta)
//例如dlta=1,即要先排2 1两个数,i=0,i<right,i=0+2*1=2 即下一个子序列的首元素下标是2 
		{
			//将子序列分成左右两部分 
			int start1 = i, end1 = i + dlta - 1, mid = i + dlta - 1;
			int start2 = mid + 1, end2 = i + 2 * dlta - 1;
			int j = i;
			if (start2 > right) break;
			if (end2 > right) end2 = right;
			while (start1 <= end1 && start2 <= end2)//下面与归并排序的递归算法相同 
			{
				if (res[start1] < res[start2]) t[j++] = res[start1++];
				else t[j++] = res[start2++];//把最小的先放到临时数组再移动下标 
			}
			while (start1 <= end1)
			{
				t[j++] = res[start1++];
			}
			while (start2 <= end2)
			{
				t[j++] = res[start2++];
			}
			for (int j = i; j <= end2; j++)//再把临时数组t的元素存回到res[] 
			{
				res[j] = t[j];
			}
		}
		dlta = 2 * dlta;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值