快速排序(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;
}
posted @ 2020-07-04 15:02  Xxaj5  阅读(396)  评论(0编辑  收藏  举报