归并排序的递归形式与非递归形式(C++版)

归并排序的核心思想是分治法,即将待排序数据分成多个小块,对每个小块进行排序,然后在两两合并小块,最终完成对整体的排序

时间复杂度是nlogn

输入:25,12,17,21,15,48

结果:


递归实现:递归类似于对此方法的场景再现,即先对整体进行划分,然后对划分后的部分进行排序(对递归函数的理解可以认为是从上层向下层进入),排序好之后再进行合并(可以认为是从下层上层开始返回)代码如下:

//归并排序
void MergeSort(int arr[],int length)
{
	if(length<=1||arr==NULL)return;
	MergeSortRecursion(arr,0,length-1);
}
//把检查边缘问题放在递归循环的外侧
void MergeSortRecursion(int arr[],int low,int high)//high表示最高坐标
{
	if(low==high)return;
	int mid=(low+high)/2;
	MergeSortRecursion(arr,0,mid);
	MergeSortRecursion(arr,mid+1,high);
	//归并
	int *tmp=new int[high-low+1];
	//如果内存分配不足,两侧成分已排序好,直接返回
	if(tmp==NULL) return;
	int i=low;int j=mid+1;int curTmp=0;
	while(i<=mid&&j<=high)
	{
		if(arr[i]>arr[j])//升序
		{
			tmp[curTmp++]=arr[j++];
		}else
		{
			tmp[curTmp++]=arr[i++];
		}
	}
	if(i<=mid)
	{
		for(;i<=mid;i++)
			tmp[curTmp++]=arr[i];
	}
	if(j<=high)
	{
		for(;j<=high;j++)
			tmp[curTmp++]=arr[j];
	}
	//返还给arr
	curTmp=0;
	for(int i=low;i<=high;i++)
		arr[i]=tmp[curTmp++];
	delete[] tmp;
}
非递归的实现是对递归形式的模拟,但是不能够实现从上到下在由下到上的返回,因此我们之间利用从下向上返回的模拟,利用step一步一步上向上层爬,一直爬到最上层,具体代码如下:

//非递归
void MergeSortNonRecursion(int arr[],int length)//length表示数组长度
{
	int *tmp=new int[length];
	int step=1;
	
	while(step<length)//由于步长小于length所以左侧的必然存在
	{
		int i=0;//控制坐标变化
		int left,right,leftToPos,rightToPos;
		while(i<length)
		{
			left=i;leftToPos=left+step-1;
			right=leftToPos+1;//保证剩下的部分不足low+step时用剩余部分
			rightToPos=right+step-1>length-1?length-1:right+step-1;
			int p=left;int q=right;int k=left;
			while(p<=leftToPos&&q<=rightToPos)
			{
				if(arr[p]>arr[q])//升序
				{
					tmp[k++]=arr[q++];
				}else
				{
					tmp[k++]=arr[p++];
				}
			}
			if(p<=leftToPos)
			{
				while(p<=leftToPos)
					tmp[k++]=arr[p++];
			}
			if(q<=rightToPos)
			{
				while(q<=rightToPos)
					tmp[k++]=arr[q++];
			}
			//返还给arr
			for(int j=left;j<=rightToPos;j++)
			{
				arr[j]=tmp[j];
			}
			i+=2*step;
		}
		step*=2;
	}
	delete[] tmp;
}


其中对于参数数组进行说明:C++中传递参数分为传值和传址,其中基本数据类型是传值即生成一个新的副本存储在调用函数的栈空间中,因此对其进行内容修改不会对原数据造成信息改动;当进行传址引用的时候对调用函数内的该数据进行改动的时候可以修改原数据信息。数组作为参数进行传递的时候默认会退化成指针类型,此处相当于传址所以可以改动原数据信息。

数组做参数退化成指针类型


  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值