欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-03-24 12:41:30
...

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;
}