归并排序

没有几个写归并排序的dalao?

我翻了好几页,就看到一位dalao写了归并排序,而且没有任何说明和注释
,也有可能是我眼睛不好使,望各位dalao和管理见谅

本来要写逆序对这个题,然后来这里先联系一下归

归并排序利用的是分治思想

假如有两个已经排好序的序列,你怎么合并他们?

举个例子吧,我们搞两个指针l和r,初始时令他们=各自序列第一个数的位置

1 4 10

2 11 15

那么a[l] 就等于1,a[r]就等于2

(1)首先a[l] < a[r]

我们将a[l]加入另一个待选数列t[] = {1};
然后l++

(2)现在a[l] > a[r]

把a[r]加入t[] = {1,2}
然后r++

(3)然后a[l] < a[r]

a[l] 加入t[] = {1,2,4}
l++

(4)a[l] < a[r]

a[l] 加入t[] = {1,2,4,10}
,然后l++

我们现在发现l > 第一个数组的长度,代表第一个数组的最大值也不如a[r] 及a[r]之后的数大,所以把剩下数全加进去

最终t[] = {1,2,4,10,11,15}

那么我们怎么得到两个有序的数列呢?

我们发现,如果一个数列只有一个数,那么它是有序的,这样我们就可以递归解决问题,递归到1就返回,因为已经排好了

以上就是龟排的过程

#include<bits/stdc++.h>
//万能头
using namespace std;

inline int read(){int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();return s*w;}
//快读
int p[400001],t[400001];//p是需要排序的数列
//t的作用在上面已经说了,相当于一个临时数组

int k;

void gb(int x,int y){
	if(x == y) return;//如果只有一个数,那么它是有序的
	int mid = (x + y) >> 1; //从中间分开
	gb(x,mid);//递归左半边
	gb(mid + 1,y);//右半边
	int l = x,r = mid + 1,tot = 0;//第一个区间的指针是l,第二个是r,tot是计算t[]中有多少数
	for(int i = x;i <= y;++i){
		if(p[l] > p[r]){//这就是上述排序过程
			t[++tot] = p[l++];
			if(l > mid) break;//指针超过范围退出
		}
		else{
			t[++tot]  = p[r++];
			if(r > y) break;
		}
	}
	if(l > mid){//左边超范围把右边加上
		for(int i = r;i <= y;++i) t[++tot] = p[i];
	}
	if(r > y){//同理
		for(int i = l;i <= y;++i) t[++tot] = p[i];
	}
	for(int i = x;i <= y;++i){//把临时数组的值赋给真实的数组
		p[i] = t[i - x + 1];
	}
}

int main(int argc, char const *argv[])
{
	int n;
	cin>>n;
	for(int i = 1;i <= n;++i){
		p[i] = read();
	}
	gb(1,n);
	for(int i = n;i >= 1;--i){
		cout<<p[i]<<" ";
	}
	cout<<endl;
    int AC = 0;
	return AC;//返回AC
}
posted @ 2019-08-14 21:56  liuzitong本体  阅读(129)  评论(0编辑  收藏  举报