排序
题目
解析
堆排
显然易见的O(nlogn)排序模板,但我们使用堆排,每次取出堆顶输出即可
这里讲一个O(n)建堆法:首先将n个数直接赋给堆中对应的下标,不维护堆性质,然后从n/2循环到1,down(i),最终可以形成堆,但它是O(n)的
虽然说没什么用,因为每次取出还是O(logn)的……
1672K/15MS
最优解!
code:
#include<cstdio>
using namespace std;
inline void swap(int &x,int &y){
x^=y^=x^=y;}
inline bool idigit(char x){
return (x<'0'|x>'9')?0:1;}
inline int read()
{
int num=0,f=1;
char c=0;
while(!idigit(c=getchar())){
if(c=='-')f=-1;}
while(idigit(c))num=(num<<1)+(num<<3)+(c&15),c=getchar();
return num*f;
}
inline void write(int x)
{
int F[20];
int tmp=x>0?x:-x;
if(x<0)putchar('-');
int cnt=0;
while(tmp>0){
F[cnt++]=tmp%10+'0';tmp/=10;}
while(cnt>0)putchar(F[--cnt]);
if(x==0)putchar('0');
putchar(' ');
}
int n,heap[100010],r,tot;
inline void down(int x)
{
while((x<<1)<=tot)
{
if((x<<1|1)<=tot&&heap[x<<1]>heap[x<<1|1])r=(x<<1|1);
else r=(x<<1);
if(heap[x]>heap[r])swap(heap[x],heap[r]),x=r;
else break;
}
}
int main()
{
n=read(),tot=n;
for(int i=1;i<=n;++i)heap[i]=read();
for(int i=(n>>1);i;--i)down(i);
while(tot)write(heap[1]),heap[1]=heap[tot--],down(1);
return 0;
}
快排
快排的实现基于分治思想,其特点是可以退化为n方常数小
具体实现参见代码
1780K/93MS
code:
#include<cstdio>
#include<iostream>
using namespace std;
int n,a[100001];
void srt(int l,int r)
{
int mid=a[l+r>>1],i=l,j=r;//日常位运算卡常
while(i<=j)
{
while(a[i]<mid)i++;
while(a[j]>mid)j--;//左右移
if(i<=j)
{
swap(a[i],a[j]);//交换
i++;
j--;
}
}
if(l<j)srt(l,j);
if(i<r)srt(i,r);//递归
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
srt(1,n);
for(int i=1;i<=n;i++)printf("%d ",a[i]);
return 0;
}
归并排
归并排需要一个额外的数组,当数组大小不为一时将数组分成两半递归归并排,并利用额外空间不断取出较小值,最后赋回去
2084K/109MS
code:
#include<cstdio>
#define rr register int
using namespace std;
int n,a[100010],b[100010];
inline void gb(int l,int r)
{
if(l==r)return;
rr mid=l+r>>1,p=l,j=mid+1,i=l;
gb(l,mid),gb(j,r);//递归排序
while(l<=mid&&j<=r)b[p++]=(a[j]>a[l])?a[l++]:a[j++];//选较小者取
while(l<=mid)b[p++]=a[l++];
while(j<=r)b[p++]=a[j++];//清空剩余
for(;i<=r;++i)a[i]=b[i];
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
gb(1,n);
for(int i=1;i<=n;++i)printf("%d ",a[i]);
return 0;
}