【题解】【模板】快速排序

luogu P1177 【模板】快速排序

题目描述

利用快速排序算法将读入的NN个数从小到大排序后输出。
快速排序是信息学竞赛的必备算法之一。对于快速排序不是很了解的同学可以自行上网查询相关资料,掌握后独立完成。(C++C++选手请不要试图使用STL,虽然你可以使用sort一遍过,但是你并没有掌握快速排序算法的精髓。)

输入输出格式
输入格式:

第1行为一个正整数N,第2行包含N个空格隔开的正整数a[i],为你需要进行排序的数,数据保证了A[i] 不超过10000000001000000000。

输出格式:

将给定的NN个数从小到大输出,数之间空格隔开,行末换行且无空格。

输入输出样例
输入样例#1:

5
4 2 4 5 1

输出样例#1:

1 2 4 4 5

说明

对于20%的数据,有N≤1000;
对于100%的数据,有N≤100000。

看到这道题:https://www.luogu.org/problemnew/show/P1177
其实sort函数直接轻松AC掉的2333
但是,这里我用较难一点的思路做的:
40分代码:二叉搜索树:

#include<bits/stdc++.h>
using namespace std;
struct node{
    int v;
    node *l,*r;
    node(){v=0;l=r=NULL;}
};
void insert(node *h,int x){
    if(x<h->v){
        if(h->l==NULL){
            node *p=new node;
            p->v=x;
            h->l=p;
        }else insert(h->l,x);
    }else{
        if(h->r==NULL){
            node *p=new node;
            p->v=x;
            h->r=p;
        }else insert(h->r,x);
    }
}
void out(node *h){
    if(h!=NULL){
        out(h->l);
        printf("%d ",h->v);
        out(h->r);
    }
}
int main(){
    int i,j,k,m,n;
    cin>>n;
    node *root=new node;
    cin>>k; root->v=k;
    for(i=2;i<=n;i++){
        scanf("%d",&k);
        insert(root,k);
    }
    out(root);
    return 0;
}

但是,这个代码并不能AC,TLE了3个点,为什么呢?
下载了错误数据后,我发现了错误:数据大部分都是有序的,所以,二叉搜索树就显得非常慢了,所以,这里我们要用到二叉平衡树。
二叉平衡树(已AC):

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
struct node{
    int x,w;	
    struct node *h,*r,*l;
    node(){
        x=0;w=0;h=r=l=NULL;
    }
};
node *root;
void zrg(node *u,node *v){
    node *t=u->h;
    u->l=v->r;if(v->r!=NULL)v->r->h=u;
    u->h=v;v->r=u;
    v->h=t;
    if(t!=NULL){	
        if(t->l==u)t->l=v;
        else t->r=v;
    }else root=v;
}
void zlg(node *u,node *v){
    node *t=u->h;
    u->r=v->l;if(v->l!=NULL)v->l->h=u;
    v->l=u;u->h=v;
    v->h=t;
    if(t!=NULL){	
        if(t->l==u)t->l=v;
        else t->r=v;
    }else root=v;
}
void out(node *u){
    if(u!=NULL){
        out(u->l);
        printf("%d ",u->x);
        out(u->r);
    }
}
void insert(node *u,node *v){
    if(u==NULL)return;
    if(v->x>u->x){
        if(u->r==NULL){
            u->r=v;v->h=u;
            while(v->h!=NULL && v->w<v->h->w){
                if(v==v->h->r)zlg(v->h,v);
                else zrg(v->h,v);
            }			
        }else insert(u->r,v);			
    }else{
        if(u->l==NULL){
            u->l=v;v->h=u;
            while(v->h!=NULL && v->w<v->h->w){
                if(v==v->h->r)zlg(v->h,v);
                else zrg(v->h,v);
            }			
        }else insert(u->l,v);	
    }
}

int main(){
    int i,j,k,m,n,t;
    node *p,*q;
    cin>>n;	
    cin>>k;
    srand(3433);
    root=new node;
    root->x=k;root->w=rand();
    for(i=2;i<=n;i++){
        cin>>k;
        q=new node;
        q->x=k;q->w=rand();		
        insert(root,q);			
    }	
    out(root);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42875611/article/details/82989894