zoukankan      html  css  js  c++  java
  • 快速排序(quick_sort)

    快速排序大体分为三个步骤:

    1.确定分界点 q[(l+r) >> 1] 或者 q[(l+r+1) >> 1] ,两者得看情况而定,不能用 q[l] 或者 q[r] 了 因为会超时。

    2.调整区间范围,让小于等于x的放在左边,大于等于x的数放在右边。

    3.递归处理左右两端。

    模板代码:

    void quick_sort(int q[], int l, int r)
    {
        if(l >= r) return;
        
        int x = q[(l+r) >> 1], i = l-1, j = r+1; //i为左边指针 j为右边指针 确定分界点
        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);
    }
    

    另外一种

    void quick_sort(int q[], int l, int r)
    {
        if(l >= r) return;
        
        int x = q[l+r+1 >> 1], i = l-1, j = r+1;  //下面i左指针这里就不能用(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, i-1);
        quick_sort(q, i, r);
    }
    

    总的来说就是如果x取得是中间两个数得下界 (l+r) >> 1 ,那么下边递归得时候就得是用右指针即 j与j+1 ,如果x取得是中间两个数得上界 (l+r+1) >> 1 ,那么下边递归得时候就得用左指针即 i-1与i ,不然会MLE,即超内存,就是进入了死循环。

    错误代码

    void quick_sort(int q[], int l, int r)
    {
        if(l >= r) return;
        
        int x = q[l+r >> 1], i = l-1, j = r+1;  //下面i左指针这里就不能用(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, i-1);
        quick_sort(q, i, r);
    }
    

    用一个样例来说:假如 n=2 ,样例为 1 2 ,最初 i = -1 , j = 2 , x = 1 ,然后进行完 while 循环后, i与j都等于0 ,知识左边区间递归的是0--1,然后根据if(l >= r) return;直接返回结束,然后递归右边区间0--1,这是问题就来了,x仍然是1,继续重复上一个过程,就进入了死循环,所以导致MLE,所以把程序改写成q[(l+r+1) >> 1]即可通过。

    代码

    #include<iostream>
    using namespace std;
    
    const int N = 100010;
    int n;
    int q[N];
    
    void quick_sort(int q[], int l, int r)
    {
        if(l >= r) return;
        
        int x = q[(l+r) >> 1], i = l-1, j = 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);
    }
    
    int main()
    {
        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]);
        
        system("pause");
        return 0;
    }
    
  • 相关阅读:
    /usr/bin/ld: 找不到 /usr/lib64/libatomic.so.1.0.0
    linux Version mismatch error. This is libtool 2.4.6 Debian-2.4.6-2
    java播放语音文件
    java冒泡排序
    java递归求和
    常见芯片标号说明
    keil5 新建 stm32项目 步骤
    st-link 升级固件时报错“is not in the DFU mode”
    数码管 段选位选
    C51 定时器
  • 原文地址:https://www.cnblogs.com/ZhengLijie/p/13399493.html
Copyright © 2011-2022 走看看