quick sort

1. 思路

首先,将数组划分成2个子数组,可以取左点,右点,中间点,随机点。然后用2个指针去扫,将扫到的特定数据交换,然后再递归左边的子数组,右边的子数组。

不需要用到额外的存储空间,速度又快,所以是很优秀的排序,平均时间能达到nlogn,最差情况下能达到n平方。算法导论里面是已右端点来做划分的,但是在已排序的情况下,会tle ,所以在oj里面,用随机的或者中间点,比较保险。

2. 代码

luogu 书里面的代码:

void quicksort(int a[],int l,int r){
    int i = l,j =r ,flag = a[(l+r)/2];
    do{
        while (a[i]<flag)i++;
        while (a[j]> flag)j--;
        if (i<=j){
            swap(a[i],a[j]);
            i++,j--;
        }
    }while (i<=j);
    if (l<j)quicksort(a,l,j);
    if (i<r)quicksort(a,i,r);
}

acwing的代码:

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);
    //第三步:子问题合并.快排这一步不需要操作,但归并排序的核心在这一步骤
}

可以两个结合一下改成这样:

void quicksort(int a[],int l,int r){
    if (l>=r)return ;
    int i = l,j =r ,flag = a[(l+r)/2];
    do{
        while (a[i]<flag)i++;
        while (a[j]>flag)j--;
        if (i<=j){
            swap(a[i],a[j]);
            i++,j--;
        }
    }while (i<=j);
    quicksort(a,l,j);
    quicksort(a,i,r);
}

3. 相关oj

acw785

luogup1177

poj2388

原文地址:https://www.cnblogs.com/gqdw/p/14409939.html