280-归并排序算法(递归和非递归)

归并排序算法(递归和非递归)

在这里插入图片描述
从left到m下标是从小到大排序,从m+1到right下标是从小到大排序。
我们要把这些数据并轨到目标块中,然后我们再把目标块中的数据拷贝到src圆里面

非递归实现

在这里插入图片描述
右图是我们的圆src,分为2个部分,左半部分从小到大,右半部分从小到大,left是左半部分的首地址,m是中间划分的地址,right是右半部分的尾地址。k指向左半部分的首地址,也是目的的首地址。
在这里插入图片描述
谁小就把谁往目的里放。这个程序是把圆的数据导入到目的。并没有把目的往圆里拷贝。

void Merge(int *dist,int *src, int left, int m, int right)
{
	int i = left, j = m + 1;
	int k = left;
	while (i <= m && j <= right)
	{
		dist[k++] = src[i] < src[j] ? src[i++] : src[j++];
	}
	while (i <= m)
	{
		dist[k++] = src[i++];
	}
	while (j <= right)
	{
		dist[k++] = src[j++];
	}
}

拷贝函数

void Copy(int* dist, int* src, int left, int right)
{
	for (int i = left; i <= right; ++i)
	{
		dist[i] = src[i];
	}
}

并轨排序(递归)

void MergePass(int* br, int* ar, int left, int right)//划分 
{
	if (left < right) 
	{
		int mid = (right - left) / 2 + left;
		MergePass(br, ar, left, mid);
		MergePass(br, ar, mid + 1, right);

		Merge(br, ar, left, mid, right);
		Copy(ar, br, left, right);
	}
}
void MergeSort(int* ar, int n)
{
	if (ar == nullptr || n < 1) return;
	int* br = new int[n];

	MergePass(br, ar, 0, n - 1);

	delete[] br;

}
int main()
{
	int ar[] = { 14,56,34,100,23,78,93,12,45,67,88 };
	int n = sizeof(ar) / sizeof(ar[0]);
	MergeSort(ar, n);

	for (auto & x : ar)
	{
		cout << x << " ";
	}
	cout << endl;
	return 0;
}

在这里插入图片描述

并轨排序(非递归)

首先ar向br并轨
在这里插入图片描述
然后br向ar并轨
在这里插入图片描述
然后继续while循环
在这里插入图片描述
在这里插入图片描述
s就是每个区域有几个值
在这里插入图片描述
for ( ; i+2*s <= n; i = i + 2 * s)
i = i + 2 * s 两个区域加上起始位置的值,就是下一个区域的起始位置
在这里插入图片描述
图解在这里插入图片描述

并轨排序非递归的程序代码

void MergePass(int* dist, int* src,int n,int s)//划分 
{          //  i+2*s-1 <= n-1
	int i = 0;
	for (  ; i+2*s <= n; i = i + 2 * s)
	{
		Merge(dist, src, i, i + s - 1, i + 2 * s - 1);//0,1,3 
	}
	if (n-1 > i+s-1)//最后一个元素的下标大于前一个下标,说明第二部分有数据,要并轨 
	//并轨到最后的部分,有缺失的数据,如,两个值和一个值并轨 
	{
		Merge(dist, src, i, i + s - 1, n - 1);//n-1:最后一个元素的下标 
	}
	else//直接拷贝进去 
	{
		for (int j = i; j < n; ++j)
		{
			dist[j] = src[j];
		}
	}
}
void MergeSort(int* ar, int n)//并轨排序 
{
	if (ar == nullptr || n < 1) return;
	int* br = new int[n];
	int s = 1;
	while (s < n)
	{
		MergePass(br, ar, n, s); //s的值//1//4//16
		s += s;
		MergePass(ar, br, n, s);  //s的值//2//8
		s += s;
	}
	delete[]br;
}	

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林林林ZEYU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值