C语言实现归并排序

归并排序的核心思想:

如果有两个已经有序的数组

我们可以创建一个新的数组,然后比较大小,将两个有序数组的数据一个一个的拿下来放到新数组中。这样完成之后就是一个有序的数组。

再把值赋给原数组即可完成排序。

关键点:前提是两个有序数组

接下来实现代码框架

void _merge_sort(int* arr,int*tmp,int left,int right)
{

	if (left >= right)//递归终止条件
	{
		return;
	}
	int mid = (left + right) / 2;
	_merge_sort(arr,tmp, left, mid);//要排序的前提是mid左边的已经有序,因此继续递归
	_merge_sort(arr,tmp, mid+1, right);//要排序的前提是mid右边已经有序,因此继续递归

    //上面是递归版归并排序的思想核心。

	//实现两个有序数组结合新生成一个有序数组

	int a1 = left;
	int a2 = mid + 1;
	int i = left;
	while (a1 <= mid&&a2 <= right)
	{

		if (arr[a1] < arr[a2])
		{
			tmp[i] = arr[a1];
			a1++;
		}
		else
		{
			tmp[i] = arr[a2];
			a2++;
		}
		i++;
	}
	while (a1 <= mid)
	{

		tmp[i] = arr[a1];
		i++;
		a1++;
	}
	while (a2 <= right)
	{

		tmp[i] = arr[a2];
		i++;
		a2++;
	}

	for ( i = left; i <=right; i++)
	{
		arr[i] = tmp[i];
	}


}

解释:上面代码关键部分是思想核心。

我们知道,如果一个数组如果只有一个数,那么它是有序的。

那么我们就可以排序有两个数的数组(因为对半分开,两边都是有序的)

因此我们只要递归到两个数的数组即可开始排序

这样,每回退一层,两侧的数都是有序的。

从而实现排序

如果上述可以理解。

可以看下归并排序的非递归版本

模拟思路,注意边界条件即可

下面只展示代码。有疑问可以私信

void none_merge_sort(int*arr,int sz)
{
	int * tmp = (int *)malloc(sizeof(int)*sz);
	
	
	int left = 0;
	int right = sz - 1;

	int n = 1;
	while (n <sz)
	{
		for (int i = 0; i < sz; i+=2*n)
		{

			int begin1 = i;
			int end1 = i + n - 1;
			int begin2 = i + n;
			int end2 = i + 2 * n - 1;
			int j = begin1;
			//限定条件
			if (end1 >= sz)
			{
				end1 = sz - 1;
			}
			if (begin2 >= sz)
			{
				begin2 = sz - 1;
			}
			if (end2 >= sz)
			{
				end2 = sz - 1;
			}
			while (begin1 <= end1&&begin2 <= end2)
			{

				if (arr[begin1] < arr[begin2])
				{
					tmp[j] = arr[begin1];
					begin1++;
				}
				else
				{
					tmp[j] = arr[begin2];
					begin2++;
				}
				j++;
			}
			while (begin1 <= end1)
			{

				tmp[j] = arr[begin1];
				j++;
				begin1++;
			}
			while (begin2 <= end2)
			{

				tmp[j] = arr[begin2];
				j++;
				begin2++;
			}


		}
		for (int k = 0; k < sz; k++)
		{
			arr[k] = tmp[k];
		}
		n *= 2;


	}

	free(tmp);
	tmp = NULL;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值