1. 程式人生 > >【題解】【模板】快速排序

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

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