快速排序实现

Posted 不求上进的咸鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速排序实现相关的知识,希望对你有一定的参考价值。

#include<cstdio>

#include<iostream>

#include<algorithm>

using namespace std;

const int N = 1e6;

int arr[N];

int q_sort(int l,int r)

{

    int i = l+1;    //i从l+1开始从左往右找大于arr[l]的元素(这么来说,当i停止寻找时,如若没越界,arr[i]恰好大于arr[l],如果越界了(i>=j),那么交换的恰好是位置为r的元素);

    int j = r;      //j从r开始从右往左找小于等于arr[l]的元素(从这里可以看出为什么快速排序不稳定了),那么可以得出跳出循环时j恰好是右半部分的最后一个即arr[j]<=arr[l];

    while(i<j)     //这里保证i<j

    {

        //之所以下面保证i<=j 是保证最后i>j

        // 举个例子 5 4 3

        //arr[l] = 5; l = 0; i = 1;j = 2; r = 2;

        //那么循环跳出时 恰好i==j==2;

        //那么交换后为 4 5 3;

        //考虑这么一种情况 就是恰好左部分<=arr[l]<右部分

        //那么i停止时恰好是在右部分的第一个元素的位置

        //而j停止时恰好时在左部分的最后一个元素的位置

        //即是j==i-1

        //那么返回的位置就是j/i-1;

        while(arr[i]<=arr[l]&&i<=j)

            ++i;

        while(arr[j]>arr[l]&&j>=i)

            --j;

        if(i<j)    //i<j 那么意味着arr[i]>arr[j]

            swap(arr[i],arr[j]);

    }

    swap(arr[i-1],arr[l]);//其实j==i-1;

    return i-1;

}

void divide(int l,int r)

{

    if(l<r)

    {

        int mid = q_sort(l,r);

        divide(l,mid-1);

        divide(mid+1,r);

    }

}

int main()

{

    int n;

    scanf("%d",&n);

    for(int i=0;i<n;++i)

    {

        scanf("%d",arr+i);

    }

    bool flag1 = false;

    bool flag2 = false;

    for(int i=1;i<n;++i)

    {

        if(arr[i]<arr[i-1])//如果数组满足a[i-1]<=a[i] 说明正序(从小到大)

        {

            flag1 = true;

            break;

        }

    }

    for(int i=n-2;~i;--i)

    {

        if(arr[i]<arr[i+1])//如果数组满足a[i]>=a[i+1] 说明逆序(从大到小)

        {

            flag2 = true;

            break;

        }

    }

    if(flag1||flag2)

        divide(0,n-1);

    else if(flag2)

    {

        int mid = n>>1;

        for(int i=0;i<=mid;++i)

            swap(arr[i],arr[n-1-i]);

    }

//    divide(0,n-1);

    for(int i=0;i<n;++i)

        printf("%d ",arr[i]);

    return 0;

}

/*

7

6 5 7 4 3 2 1

*/

When does the worst case of Quicksort occur?

The answer depends on strategy for choosing pivot. In early versions of Quick Sort where leftmost (or rightmost) element is chosen as pivot, the worst occurs in following cases.

1) Array is already sorted in same order.
2) Array is already sorted in reverse order.
3) All elements are same (special case of case 1 and 2)

Since these cases are very common use cases, the problem was easily solved by choosing either a random index for the pivot, choosing the middle index of the partition or (especially for longer partitions) choosing the median of the first, middle and last element of the partition for the pivot. With these modifications, the worst case of Quick sort has less chances to occur, but worst case can still occur if the input array is such that the maximum (or minimum) element is always chosen as pivot.

References:
http://en.wikipedia.org/wiki/Quicksort

不求上进的咸鱼


以上是关于快速排序实现的主要内容,如果未能解决你的问题,请参考以下文章

用C语言编程实现快速排序算法

深度解析(十六)快速排序

java编程实现随机数组的快速排序

排序算法入门之快速排序(java实现)

算法排序3:优化版快速排序非递归实现快速排序

算法排序3:优化版快速排序非递归实现快速排序