归并排序

归并排序

1.归并的思想

虽然官方给的定义说归并是分治法,但是,我的理解是递归。

有句话说得好,人理解递推,神理解递归。

最短的三行代码也是最难的,因为牵扯到了回溯。

归并和快排都是分治,归并排序和快排不一样的是,快排只有向下的操作,而没有回溯。

还有就是,归并排序每次分割都是中点,而快排的分割是在左右指针相遇的地方。

话不多说,开始撸代码。。。

2.代码分析

(1)合并操作

​ 对于一个左边一半和右边一半分别有序的数组,合并成一个新的整体有序的数组,需要注意的是,这里需要一个和原数组一样大的辅助空间。

int Temp[MaxSize];	//辅助数组

//arr[left...mid] 有序  arr[mid+1...right]有序 
void Merge(int arr[],int left,int right)
{
	int mid=(left+right)/2;
	int i=left;		//指向原数组左半部分
	int j=mid+1;	//指向原数组右半部分
	int k=0; 		//用来指向辅助数组
    
	while(i<=mid&&j<=right)		//此时左右两半数组都没到顶
	{
		if(arr[i]<=arr[j])
			Temp[k++]=arr[i++];
		else
			Temp[k++]=arr[j++];
	}
	while(i<=mid)			//右半数组比完了,把剩余左半数组直接复制到Temp数组后面
		Temp[k++]=arr[i++];
	while(j<=right)			//同理
		Temp[k++]=arr[j++];
	k=0;		//此时Temp数组是一个完整有序的数组,指针指向Temp数组开始的地方
	for(int q=left;q<=right;q++)
		arr[q]=Temp[k++];	//把Temp数组从头到尾 复制 到 arr数组中
} 
(2)递归操作

学递归的时候,最最最最难理解的就是回溯了,短短的三行代码,智慧的凝结啊。

void Merge_Sort(int arr[],int left,int right)
{
	if(left==right)	//表示该区间就一个数了,不能向下递归了,这个子区间已经有序了,可以向上回溯了
		return ;
	int mid=(left+right)/2;
    
    //如果没有执行if里面 说明这个区间足够大,不能保证左右子区间 都分别有序
	Merge_Sort(arr,left,mid);		//进左子区间 
	Merge_Sort(arr,mid+1,right);	//进右子区间
    //执行完上面两个函数,说明此时左右两个子区间已经分别有序,符合Merge的前提条件,可以合并了,也就是所谓的回溯
	Merge(arr,left,right);			
}

最近压力有点大,很多东西要做,都不想做,解压的方法就是写代码。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值