洛谷【P1177】【模板】快速排序

题目传送门:https://www.luogu.org/problemnew/show/P1177

快排是一种对于冒泡排序的优化。

对于区间\([l,r]\),我们选择一个键值\(k\),让比\(k\)小的值全部放在左半部分,比\(k\)大的值全部放在右半部分,,等于的不管。然后对于冒泡排序的\(n^2\)次比较,就被这样优化了不少。因为左半部分的值肯定会小于等于右半部分的值,所以我们可以省下很多比较次数。对于左半部分和右半部分我们再递归去处理就可以了。

时间复杂度:\(O(nlogn)\)

空间复杂度:\(O(n)\)

代码如下:

#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn=1e5+5;

int n;
int a[maxn];

int read() {
    int x=0,f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    return x*f;
}

void Qsort(int l,int r) {
    int i=l,j=r,mid=a[(l+r)>>1];//mid作为键值
    while(i<=j) {
        while(a[i]<mid)i++;//小于mid的值放在左半部分不用管
        while(a[j]>mid)j--;//大于mid的值放在右半部分不用管
        if(i<=j)swap(a[i++],a[j--]);//维护序列
    }//[l,i]始终小于等于mid,区间[j,r]始终大于等于mid
    if(l<j)Qsort(l,j);//递归处理
    if(i<r)Qsort(i,r);//递归处理
}

int main() {
    n=read();
    for(int i=1;i<=n;i++)
        a[i]=read();
    Qsort(1,n);
    for(int i=1;i<=n;i++)
        printf("%d ",a[i]);
    return 0;
}
posted @ 2018-09-14 10:59  AKMer  阅读(379)  评论(0编辑  收藏  举报