归并排序 —— C语言

一.归并排序递归实现

        归并递归的思想是,将所有元素分割到最小单位,当元素都是单个时,此时可以认为单个元素是有序的,然后进行壹壹归,之后进行贰贰归、肆肆归(2的倍数)。。。。以此类推最后将所有元素归并为有序。归并的整个过程是比较大小后进行尾插。

 1.代码图解

2.代码实现

void MergeSort(int* a,int* tmp, int begin ,int end)
{
	if (begin >= end)//b=e代表只有一个元素了,1个默认有序,直接返回。b>e代表已经越界
		return;
	int mid = (end + begin) / 2;//取中间坐标进行分割
	MergeSort(a, tmp, begin, mid);
	MergeSort(a, tmp, mid + 1 , end);

	int begin1 = begin, end1 = mid;// 11归 --> 22归 -->33归 
	int begin2 = mid + 1, end2 = end;
	int index = begin;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1] < a[begin2])
			tmp[index++] = a[begin1++];
		if (a[begin2] < a[begin1])
			tmp[index++] = a[begin2++];
	}

	while (begin1 <= end1)
	{
		tmp[index++] = a[begin1++];
	}
	while (begin2 <= end2)
	{
		tmp[index++] = a[begin2++];
	}
	memcpy(a + begin, tmp + begin, ((end - begin) + 1) * sizeof(int));
	
}

二.归并排序非递归实现

        非递归归并排序的思想是直接先将集合内的元素分成单个进行归并比较尾插,总体实现方法跟递归归并还是一样,只是说没有进行递归,而是用一个下标变量来控制归并的范围,元素还是先进行壹壹归并,然后贰贰归并,叁叁归并、肆肆归并(2的倍数),归并的整个过程是比较大小后进行尾插。

1. 代码图解

2. 代码实现

// 归并排序非递归实现
void MergeSortNonR(int* a, int* tmp, int begin, int end)
{
	int gap = 1;

	while (gap < end)//gap  1 2 4 8 --> 11归 22归 44归 88归
	{
		for (int i = 0; i < end; i+=2*gap)// 0 2 4 6 --> 0011 2233 4455 6677
		{
			int begin1 = i ; int end1 = i + gap - 1;//[0,0 + 1 - 1] == [0,0]
			int begin2 = i + gap; int end2 = i + (2 * gap) - 1;//[1,0 + 2 - 1] == [1,1]  这里就是11归
			int index = i;

			if (begin2 > end)
				break;

			if (end2 > end)
				end2 = end ;

			while (begin1 <= end1 && begin2 <= end2)
			{
				if (a[begin1] < a[begin2])
					tmp[index++] = a[begin1++];
				if (a[begin2] < a[begin1])
					tmp[index++] = a[begin2++];
			}

			while (begin1 <= end1)
			{
				tmp[index++] = a[begin1++];
			}
			while (begin2 <= end2)
			{
				tmp[index++] = a[begin2++];
			}
			memcpy(a + i, tmp + i, ((end2 - i) + 1) * sizeof(int));

		}
		gap *= 2;
	}
	free(tmp);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值