归并排序

归并排序其实是利用了分治思想
分:将数组不断从中间分成两半,将分出来的子数组继续分成两半(递归),直到数组中的元素只有一个为止(递归结束条件)
治:当数组被分成最小(只有一个元素)时,我们将最后一次被分出来的两个数组按从小到大(或者从大到小)的顺序合并成为一个数组,如此递归上去,最后得到一个有序的数组

首先我们先来说合并的思路:
函数名:void merge(int a[],int l[],int r[],int left,int right)
这里a是合并后的数组,l和r是两个子数组,从他们中向a中传数据
left参数和right参数表示左右数组的长度
int i = 0,j=0,k=0;定义三个参数用作l,r,a数组的指针
当左边数组指针没有到头,右边也没有到头的时候,比较i和j所指的数字的大小,谁小,就把谁往a里面传,传完后传入数组的指针和a数组都向右移动(这里i++表示先做传值,后加)

while(i< left&&j<right){
		if(l[i] < r[j] ) a[k++] = l[i++];
		else a[k++] = r[j++];
	}

如果有一边的指针已经到头了,那很显然,因为这两个数组都是有序的,所以我们只需要把没到头那个数组剩下的所有值直接传入a数组就好了

while(i<left){
		a[k++] = l[i++];
	}
	while(j<right){
		a[k++] = r[j++];
	}

现在合并完成了,接下来我们要梳理一下分数组的思路
函数:void mergeSort(int a[],int n)
其中参数a表示要分割的数组,n为该数组的长度(这个n的作用其实是为了让我们找到中间元素的下标)
因为我们要使用递归的思想 首先写上结束条件 if(n < 2) return; 这个很明显吧,就只有1个元素了还分个毛线…
接下来把中间元素的下标求出来int mid = n/2;
然后开两个数组,l和r,分别为左边的数组和右边的数组:
int l[mid],r[n-mid];
现在这两个数组都是空空如也~所以我们要把a数组中mid左边元素放入l,右边(包括自身)放入r

for(int i=0;i<mid;i++){
		l[i] = a[i];
	}
	for(int j=mid;j<n;j++){
		r[j-mid] = a[j];
	}

好嘞,这一次分组就完事了,然后对接下来分出来的左右数组再进行分组

mergeSort(l,mid);
	mergeSort(r,n-mid);

分完之后还要合并奥~

	merge(a,l,r,mid,n-mid);

整个代码就算完成啦

归并排序的时间复杂度是稳定的,一直都为O(logn)所以这个效率是要比快排高的(o(n^2)到o(logn)),所以我们可以使用归并提高一些效率

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值