快速排序及模板

快速排序及模板

1. 思想

    快速排序是基于分治法的思想。首先给定一组数,使用快速排序对其进行排序的话,过程如下:
    1.  确定分界点:q[l],q[(l+r)/2],q[r]或者随机都可以
    2.  调整区间:如果我们以x为分界点的话,之后我们将区间分为两半。注意,这两半未必长度相等。使得左区间里面的数都小于等于x,右区间里面的数都大于等于x。在调整区间的时候,x不一定只有一个,且既有可能位于左区间也有可能位于右区间。
    3.  递归处理左右两段,进而排序完成。

img

    上述过程中,最难的就是调整区间的部分。
    有一种暴力的做法可以调整区间。
    1.  先开两个额外数组ab
    2.  扫描整个数组q,使得小于等于x的放在a数组,大于x的放在b数组。
    3.  扫描过后,将a数组的内容放在q数组中,在将b数组的内容放在q数组中。这样就划分完成了。
    上述的做法,虽然使得空间复杂度提高,但是时间复杂度很良好。是O(n)
    还有一种比较优美的调整区间的做法。
    1.  初始化两个指针i和j,指向数组q的第一个和最后一个元素。
    2.  两个指针都往中间靠拢,规则就是:首先移动i,如果q[i] < x 那么就往中间走,直到q[i] >=x 为止。然后,再移动j,如果q[j] > x 那么就往中间走,直到q[j] <=x 为止。
    3.  当移动完i和j之后,如果i和j没有相遇或者交错,那么就交换q[i]q[j]。交换后,i和j都分别需要移动一格,之后再进行上述过程。如果i和j相遇或者交错,不需要交换q[i]q[j],代表划分区间完成。
    4.  我们以j为标准来划分区间,我们可以发现:l~j是左区间,里面的数都小于等于x。j+1~r是右区间,里面的数都大于等于x。
    需要注意的是,在任何情况下,i左边的数(不包括i),都小于等于x。j右边的数(不包括j),都大于等于x。
    上述的做法,没有开辟任何额外空间,空间复杂度很低,同时时间复杂度也很良好。是O(n)
    我们可以通过一个案例[31235],来完成上述过程。(略)

2. 模板

void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;             //如果区间里面只有一个数或者没有数,那么就不用排序了。

    int i = l - 1, j = r + 1, x = q[l + r >> 1];
    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j) swap(q[i], q[j]);
    }
    quick_sort(q, l, j), quick_sort(q, j + 1, r);          
}

3. 题目

    地址:https://www.acwing.com/problem/content/787/
#include <iostream>
#include <cstdio>

using namespace std;

void quick_sort(int q[],int l,int r){
    if(l>=r){
        return;
    }
    int i = l-1;
    int j = r+1;
    int x = q[(l+r) >> 1];
    while(i < j){
        do{i++;}while(q[i] < x);
        do{j--;}while(q[j] > x);
        if(i < j){
            int temp = q[i];
            q[i] = q[j];
            q[j] = temp;
        }
    }
    quick_sort(q,l,j);
    quick_sort(q,j+1,r);
}


int main(){
    int n;
    int q[100010];
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&q[i]);
    }
    quick_sort(q,0,n-1);
    for(int i=0;i<n;i++){
        printf("%d ",q[i]);
    }
    return 0;
}
    地址:https://www.acwing.com/problem/content/788/
#include <iostream>
#include <cstdio>

using namespace std;

void quick_sort(int q[],int l,int r){
    if(l >= r){
        return;
    }
    int i = l-1;
    int j = r+1;
    int x = q[(l+r)>>1];
    while(i < j){
        do{i++;}while(q[i] < x);
        do{j--;}while(q[j] > x);
        if(i < j){
            int temp = q[i];
            q[i] = q[j];
            q[j] = temp;
        }
    }
    quick_sort(q,l,j);
    quick_sort(q,j+1,r);
}


int main(){
    int n,k;
    int q[100010];
    scanf("%d %d",&n,&k);
    for(int i=0;i<n;i++){
        scanf("%d",&q[i]);
    }
    quick_sort(q,0,n-1);
    printf("%d",q[k-1]);
    return 0;
}
    作者:gao79138
    链接:https://www.acwing.com/
    来源:本博客中的截图、代码模板及题目地址均来自于Acwing。其余内容均为作者原创。
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
posted @   夏目^_^  阅读(65)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示