【苏瞳】C语言+归并排序

归并排序

我们先把数组分成两半部分,如果数组左半部分有序,右半部分也有序,那么我们就可以使用归并

例如下图

那么如何归并左右部分呢?(下面我们以升序为例子)

算法如下:

1.我们利用两个指针(bagin1,bagin2),分别指向左右部分的第一个元素。

2.比较arr[bagin1]  arr[bagin2] 的大小,把小的移动到临时数组里面,然后对应的指针++,然后循环起来直到其中一个数组移动完,循环结束。

3.如果两半部分的数组个数不相等,必然有一个没有移动完,我们需要检查是那个没有移动完,然后把没有移动完的数据直接拷贝到临时数组里面。(为什么能直接拷贝?因为已经部分有序,当循环结束时,有数没有移动完,那么这些数一定比移动完的数大)

4.把临时数组里面整体排序好的的数拷贝到原来数组中,归并完毕。

部分步骤如图:

..........................

那么有同学要说了,如果左右部分没有序怎么办?

这不是老套路了嘛,递归呗。

递归终止条件:当左右区间区间只有一个值或者没有值时,结束递归。

具体代码如下(如果有同学不理解递归,请自行画递归展开图,你会恍然大悟的):

#include<stdio.h>
#include<stdlib.h>

//归并排序
void Merge_Sort(int *arr,int left,int right,int *temp)
{
	if(left >= right) //left == right 区间只有一个值不需要归并了
	{
		return;
	}
	
	int mid=(left+right)>>1;
	//假设 [left,mid] [mid+1,right]有序,那我们就可以归并了
	Merge_Sort(arr,left,mid,temp);
	Merge_Sort(arr,mid+1,right,temp);
	
	int bagin1=left,end1=mid;//归并
	int bagin2=mid+1,end2=right;
	int index=left;
	while(bagin1<=end1 && bagin2<=end2)
	{
		if(arr[bagin1] < arr[bagin2])
		{
			temp[index++]=arr[bagin1++];
		}
		else
		{
		    temp[index++]=arr[bagin2++];
		}
	}
	
	//判断哪个区间没结束,就把那个区间直接放到temp中
	while(bagin1 <= end1)
	{
		temp[index++]=arr[bagin1++];
    }
	while(bagin2 <= end2)
	{
		temp[index++]=arr[bagin2++];
	}
	
	//拷贝回arr
	for(int i=left; i<=right; i++)
	{
		arr[i]=temp[i];
	}
	
}

void MergeSort(int *arr,int Size)
{
	int *temp=(int*)malloc(sizeof(int)*Size);
	
	Merge_Sort(arr,0,Size-1,temp);//创建一个子函数方便递归
	free(temp);
}


int main()
{
	int arr[]={5,2,1,4,3,6,9,8,7,0};
    MergeSort(arr,10);
	for(int i=0;i<10;i++)
	{
		printf("%d ",arr[i]);
	} 
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值