第二周(归并排序详解)

归并排序

简单理解思路

  • 运用分治的方法,先把数组不断拆分,之后再边排序边合并

时间复杂度

  • O(nlongn)

#include<stdio.h>
int i,j,a[10000],n;
void merge(int left,int middle,int right)
{
 	int b[10000],k;
 	i=left;//分治之后从小到大依次比较排序后返回到原数组中
 	j=middle+1;//定义右边的起始点
 	k=left;
	while(i<=middle&&j<=right)//循环直到左右两边有一边的数组输入完全
 	{
  		if(a[i]<a[j])//如果左边小于右边,就在新数组中存入左边的值
   			b[k++]=a[i++];
  		else
   			b[k++]=a[j++];
 	}
 	while(i<=middle)
  		b[k++]=a[i++];
 	while(j<=right)
  		b[k++]=a[j++];
 	for(i=left;i<=right;i++)
  		a[i]=b[i]; 
}
void mergesort(int left,int right)
{ 
 	if(left==right)
  		return;
 	int middle=(left+right)/2;
 	mergesort(left,middle);//不断拆分,直至最小
 	mergesort(middle+1,right);//不断拆分,直至最小
 	merge(left,middle,right);//开始合并排序
}
int main()
{
 	scanf("%d",&n);
 	for(i=1;i<=n;i++)
  		scanf("%d",&a[i]);
 	mergesort(1,n);
 	for(i=1;i<=n;i++)
  		printf("%d ",a[i]);
 	return 0; 
} 

个人易错点,这里是while不是if,if只能执行一次,一次之后就退出了,要记得是while!! 永远错在这里

while(i<=middle)
    b[k++]=a[i++];
while(j<=right)
    b[k++]=a[j++];

我还是想解释一下,尽管今早检测中我差点又忘记了我上周详细写过的快速幂的模板
好的,举个栗子
比如现在需要对5 4 8 9 1 2 6排序
然后首先将他们不断二分,然后分到最后变成单独的数字了
5    4   8   9   1   2   6
现在将他们进行归并,在归并中排序,这个意思就是像下面这样,
5和4哪个小呢?4小,对的 ,所以把4先放在新数组里,然后再放入5,
5    4   8   9   1   2   原数组a
4   5新数组b

然后在把这两个值放回原数组中使原数组a变为
4    5   8   9   1   2   


再排序第二组8和9,先放入8,然后放入9
4    5   8   9   1   2   原数组a
         8   9新数组b

然后在把这两个值放回原数组中使原数组a变为
4    5   8   9   1   2   


然后对4589进行放置,
4    5   8   9   1   2   原数组a
4   5    8   9新数组b

然后在把这两个值放回原数组中使原数组a变为
4    5   8   9   1   2   


再排序1和2,先放入1,然后放入2
4    5   8   9   1   2   原数组a
                 1   2新数组b

然后在把这两个值放回原数组中使原数组a变为
4    5   8   9   1   2   


最后将它们最后一次归并
4    5   8   9   1   2   
比较两边的数字,4和1,1小,所以在新数组里先放入1,然后判断4和2,2小,存入2
然后右边没有值了,将左边剩下部分依次输入,最后将新数组b中的值再返回赋给a
得到最终结果啦,数组a为
1   2   4    5   8   9   

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值