排序算法-归并排序

排序算法-----归并排序

归并算法的思想就是 分而治之。将序列不换分成不同的序列,分别进行序列化然后归并所有的序列。

具体步骤:
  • 把长度为n的输入序列分成两个长度为n/2的子序列;
  • 对这两个子序列分别采用归并排序;
  • 将两个排序好的子序列合并成一个最终的排序序列。
    归并排序
    对数组{3,55,10,2,66,30,6,19,25,9};序列最左端下标为L 中间M 右端R;
    不断进行序列的划分,直到L>R,然后进行序列的归并。
采用递归方法

代码如下:

//并轨函数
void Merge(int *dst, int *src, int left, int m, int right)
{
	int i = left, j = m + 1;
	int k = left;
	while (i <= m && j <= right)
	{
		dst[k++] = src[i] < src[j] ? src[i++] : src[j++];
	}
	while (i <= m)
	{
		dst[k++] = src[i++];
	}
	while (j <= right)
	{
		dst[k++] = src[j++];
	}
}
//并轨排序(递归)
void MergePass(int *br, int *ar, int left, int right)
{//     2      2
	if (left < right)
	{
		int mid = (right - left + 1) / 2 + left - 1;//
		MergePass(br, ar, left, mid);
		MergePass(br, ar, mid + 1, right);
		Merge(br, ar, left, mid, right);
		cout << left << " " << mid << " " << right << endl;
		Copy_Ar(ar, br, left, right);//自己写的简单的数组拷贝
	}
}
void MergeSort(int *ar, int num)//(数组, 长度)
{
	int * br = (int*)malloc(sizeof(int)*num);
	MergePass(br, ar, 0, num - 1);
	free(br);
}
打印结果:
原始数据:3 55 10 2 66 30 6 19 25 9
0 0 1
3 55 10 2 66 30 6 19 25 9

3 3 4
3 55 10 2 66 30 6 19 25 9

2 2 4
3 55 2 10 66 30 6 19 25 9

0 1 4
2 3 10 55 66 30 6 19 25 9

5 5 6
2 3 10 55 66 6 30 19 25 9

8 8 9
2 3 10 55 66 6 30 19 9 25

7 7 9
2 3 10 55 66 6 30 9 19 25

5 6 9
2 3 10 55 66 6 9 19 25 30

0 4 9
2 3 6 9 10 19 25 30 55 66

并轨过程,就是两个序列排序的过程,这两个序列是(L,M)和(M+1, R)在比较的过程中,将比较结果保存在一个数组dst中,无论是(L,M)或者(M+1, R)哪个序列先遍历结束,然后将剩余部分直接保存在数组dst中即可。然后再将dst中的元素拷贝到原始序列(L,M)中。

非递归
//并轨排序(非递归)
void MergePass(int *dst, int *src, int s, int n)
{
	int i;
	for (i = 0; i + 2 * s - 1 <= n - 1; i += (2 * s))
	{
	//并轨函数与递归方法并轨函数相同
		Merge(dst, src, i, i + s - 1, i + 2 * s - 1);
	}
	if (n - 1 >= i + s)
	{
		Merge(dst, src, i, i + s - 1, n - 1);
	}
	else
	{//没有办法参与的数据进行拷贝回去。
		for (int j = i; j < n; j++)
		{
			dst[j] = src[j];
		}
	}
}
void MergeSort(int *ar, int num)
{
	int s = 1;
	int n = num;
	int *br = (int*)malloc(sizeof(int)*n);
	while (s < n)
	{
		MergePass(br, ar, s, n);
		s += s;
		MergePass(ar, br, s, n);
		s += s;
	}
	free(br);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值