zoukankan      html  css  js  c++  java
  • [模板]快速排序

    原题链接:acwing785.快速排序

    给定数组大小n和数组q[n],对数组进行排序。

    快速排序的原理:基于分治

    (1)确定分界点x:可以取x为q[l], q[l + r >> 1],q[r], 或者数组中间随机一个值(建议取q[l + r >> 1], 原因在后面说)。这里l和r是当前待排序数组的左右端点。

    (2)重新调整区间,使得调整后的区间,小于等于x的数都在x的左边,大于等于x的数都在x的右边(和x相等的数在左边、右边都可)。 调整区间的方法有两种,后面说。

    (3)递归处理分界点的左右两段,最后拼接起来的区间就是有序的了。

    调整区间的方法(一):

    (1)额外开两个数组a[], b[]

    (2)扫描数组q[l~r],如果当前的数q[i] <= x, 则把q[i]存入数组a. 即q[i] -> a[];
    如果当前的数q[i]>=x,则把q[i]存入数组b. 即q[i] -> b[i];

    (3)此时a[], b[]就分别是q[]的左半部分和右半部分了,把它们的值赋给q[]. 即a[] -> q[], b[] -> q[]。

    这种方法的优点是好理解。缺点也显而易见:空间开销大。

    调整区间的方法(二):

    有一种用双指针来调整区间的优雅的方法。

    (1)一开始,我们让两个指针i和j分别指向区间的两个端点l和r;

    (2)当q[i] < x时,i向右移动,若找到q[i] >= x,则i停下。 j向左移动,直到i和j相遇或者q[j] <= x;

    (3)若i和j未相遇,则i和j此时指向的元素都是错位的,交换这两个数的位置:swap(q[i], q[j]);

    (4) 重复上面的步骤,知道i和j相遇。

    这种划分区间方法的正确性证明:在任意时刻,左指针i左边的数都是小于等于x的,j右边的数都是大于等于x的,当i与j相遇时,
    相遇点左边的数都小于等于x,相遇点右边的数都大于等于x,故区间调整正确。

    这题代码如下:

    #include<iostream>
    using namespace std;
    const int N = 1e6 + 10;
    int q[N];
    
    void quick_sort(int q[], int l, int r) {
        if(l >= r) {                              //如果区间没有数,或者只有一个数,直接return
            return ;
        }
        int x = q[l + r >> 1], i = l - 1, j = r + 1;      //分界点x最好取中位数q[l + r >> 1],因为如果取边界q[l]或者q[r],且区间是升序或降序时,时间复杂度为O(n^2),在这题会超时
        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);                          //递归处理右半部分区间
    }
    
    int main() {
        int n;
        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;
    }
    
  • 相关阅读:
    Windows 8.1 序列化与反序列化
    window store app 附件读取
    Window 8.1 计时器功能及图片切换
    c#多层嵌套Json
    isNotNull与isNotEmpty的区别
    商务用语
    国家气象局三天天气WebService接口
    WebServise
    EF架构基础代码
    接口定义
  • 原文地址:https://www.cnblogs.com/linrj/p/13474463.html
Copyright © 2011-2022 走看看