快速排序

算法描述: 快速排序是一种分治的排序算法。 1、取出一个分割点,使数组左边的元素不大于该分割点的值,数组右边的元素不小于该分割点的值; 2、将数组的左半部分排序; 3、将数组的右半部分排序;

算法实现: class Quick

{

public:

    static bool sort(int *a, int lo, int hi)

    {

        if(hi <= lo) return true;

        int p = partition(a, lo, hi);

        sort(a, lo, p – 1);

        sort(a, p + 1, hi);

        return true;

    }

    static int partition(int *a, int lo, int hi)

    {

        int i = lo, j = hi + 1;

        int v = a[lo];

        while(true)

        {

            /* 扫描左右,检查扫描是否结束并交换元素 */

            while(a[++i] < v)

            {

                if(i == hi) break;

            }

            while(v < a[–j])

            {

                if(j == lo) break;

            }

            if(i >= j) break;

            int temp = a[i];

            a[i] = a[j];

            a[j] = temp;

        }

        /* 将v = a[j]放入正确的位置 */

        a[lo] = a[j];

        a[j] = v;

        return j;

    } }; 上述实现中,我们选取了a[lo]作为切分元素。在切分的过程中,我们保证左指针i左侧的元素不大于切分元素,右指针j右侧的元素不小于切分元素。当两个指针相遇时,我们只需要将切分元素a[lo]和a[j]进行交换,然后返回j即可。

时间复杂度: 快速排序最好的情况是每次都正好能将数组对半分,在这种情况下快速排序所用的次数正好满足分治递归的f(n) = 2 * f(n/2) + n,“2 * f(n/2) ”表示将两个子数组排序的成本,n表示切分元素和当前数组比较的成本。 公式推导: f(n) = 2 * f(n/2) + n       = 4 * f(n/4) + 2 * n       = 8 * f(n/8) + 3 * n       …       = n + n * lg(n)

空间复杂度: 快速排序是原地排序,由于使用递归所以需要一个比较小的辅助栈(lg(n))。

稳定性: 快速排序是不稳定的,因为快速排序中不仅仅是相邻元素的交换。

适用情景: 快速排序可能是应用最广泛的算法,实现简单,速度快,不依赖输入情况,只用到一个很小的辅助栈(lg(n))。

点赞