QuickSort 快速排序

问题

用Quick Sort对长度为nn的无序序列ss从小到大(升序)排序。

解法

在长度为nn的序列s=[x0,x1,,xn1]s = [x_0, x_1, \dots, x_{n-1}]选取最左边元素x0x_0作为pivotpivot,然后将剩余部分分为两个部分left=[x1,,xk]left = [x_1, \dots, x_k]right=[xk+1,,xn1]right = [x_{k+1}, \dots, x_{n-1}](其中1kn11 \le k \le n-1),满足leftleft所有元素都位于pivotpivot左边,小于等于pivotpivotrightright所有元素都位于pivotpivot右边,大于等于pivotpivot,而left,rightleft, right内部并不必须是有序的。如图:

s=[x0,,xn1]s = [x_0, \dots, x_{n-1}]中任意x<pivotx \lt pivot移动到其左边,任意x>pivotx \gt pivot移动到其右边。需要如下操作:

function Partition(s, low, high):
    let pivot = s[low]
    while low < high
        while low < high and s[high] >= pivot
            high--
        s[low] = s[high]
        while low < high and s[low] <= pivot
            low++
        s[high] = s[low]
    s[low] = pivot
    return low

(1) Partition函数第2行:令ss第一个元素s[low]s[low]作为pivotpivot

(2) Partition函数第3-9行:轮流从ss最右边选出第一个x<pivotx \lt pivot移动到其左边,从ss最左边选出第一个x>pivotx \gt pivot移动到其右边,直到lowhighlow \ge high

(3) Partition函数第10-11行:经过移动之后lowlow的位置即为最终pivotpivot的位置,将该位置返回给函数调用者;

上述操作的示例如图:

pivot=s[0]=45,low=0,high=n1pivot = s[0] = 45, low = 0, high = n-1。从highhigh向左搜索第一个s[high]=29<pivot=45s[high] = 29 \lt pivot = 45,令s[low]=s[high]s[low] = s[high]

再从lowlow开始向右搜索第一个s[low]=90>pivot=45s[low] = 90 \gt pivot = 45,令s[high]=s[low]s[high] = s[low]

再从highhigh向左搜索第一个s[high]=13<pivot=45s[high] = 13 \lt pivot = 45,令s[low]=s[high]s[low] = s[high]

上述操作直到lowhighlow \ge high停止,此时lowlow的位置即为pivotpivot的位置,令s[low]=pivots[low] = pivot就完成了本轮操作。

递归的对leftleftrightright进行该操作,即可完成整个数组排序:

function QuickSort(s, begin, end):
    if end <= begin+1
        return
    let mid = Partition(s, begin, end)
    QuickSort(s, begin, mid)
    QuickSort(s, mid+1, end)

复杂度

highlow=khigh - low = k,则Partition函数的输入规模为T(k)T(k),其时间复杂度为O(k)O(k)

QuickSort函数的初始输入规模为T(n)T(n),调用Partition的输入规模为T(n)T(n),每次递归后输入规模为上一层的T(n2)T(\frac{n}{2}),可得:

T(n)=2T(n2)+O(n)\begin{matrix} T(n) & = & 2 \cdot T(\frac{n}{2}) + O(n) \end{matrix}

类似MergeSort算法,该算法的时间复杂度为O(nlog2n)O(n \cdot log_2 n),因为所有操作都没有申请额外内存,是在原地完成,因此空间复杂度为O(1)O(1)

源码

QuickSort.h

QuickSort.cpp

测试

QuickSortTest.cpp

Last updated