归并排序

归并排序

日常膜拜dalao:财神万岁!!!!!!!!!!!!!!!!!
日常凌晨三点水博客。。写这些入门的休息一会,主要是为了传以前写的一些东西。。
话说这个归并排序是对新手最不友好的一种排序方式之一。。(还有快速排序)

言归正传

什么是归并排序?

归并排序是一种效率较高的排序方法,它分为拆分和合并两大部分,先拆后合。
拆分,就是将一堆无序的数拆成单个,方便合并。
合并,就是将拆分好的数按照排序规则再拼凑起来。
详细解释请看下图:

拆分:

1
2
3
4
5
6
7
8
5 6 3 1 2 8 4 7
5 6 3 1
5 6
2 8 4 7
3 1
2 8
4 7

合并:

1
2
3
4
5
6
7
8
5 6
1 3
2 8
4 7
1 3 5 6
2 4 7 8
1 2 3 4 5 6 7 8

看完这两幅图你应该明白了,归并排序原来就是将一堆数字分开,再合成有序的数列
其实,这就是分治的思想,将大问题化小问题,将每个最小的问题处理好,合并起来大问题也就处理好了~
古人云:大事化小,小事化了

代码

在明白了归并排序的基本思想后,我们来看代码:
(解释都在代码里面了,我好懒qwq)

#include<iostream>//归并排序,先拆后合 
#include<cstring>
int a[1500]; 
using namespace std;
void hebing(int *a,int l,int mid,int r)//合并,从a数组的下标l到r中间为m的部分合并
{
	int b[1500];//临时存放合并结果的数组,否则a数组会乱
	memset(b,0,sizeof(int)) ;//清零b数组
	int k=0;
	int i=l;int j=mid;
	while(i<mid&&j<=r)//当mid的左右两端都剩数字时,任意一边放完了都会退出
	{
		if(a[i]<=a[j])//小的往前放
			b[k++]=a[i++];
		else
			b[k++]=a[j++];
	}
	while(j<=r) b[k++]=a[j++];//注意这一句和下面一句一次只合并会有其中一个执行
	while(i<mid) b[k++]=a[i++];//把剩下的没放完的一边也扔进b里面
	for(int i=l;i<=r;i++) a[i]=b[i-l];//把b还给a
}

void guibing(int *a,int start,int end){//拆分 (原谅我可怜的英语)
//(注意这是个递归)
	if(start==end) return;//拆到最小不能再拆
	int mid=(start+end)/2;
	guibing(a,start,mid);//拆左边
	guibing(a,mid+1,end);//拆右边
	hebing(a,start,mid+1,end);//合并
}
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	guibing(a,1,n);
	for(int i=1;i<=n;i++)
		cout<<a[i]<<" ";
	return 0;
 } 

推荐题目

洛谷p1908逆序对
洛谷p1309瑞士轮
怎么样是不是超级简单
本文若有不道处欢迎评论,
感谢各位神犇对本蒟蒻的支持!qwq

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值