归并排序
没有几个写归并排序的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
}
作者: liuzitong
出处:http://www.cnblogs.com/lztzs/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。