算法导论 第七章 快速排序

7.1 快速排序描述

用分治策略进行排序:

分解:将数组A[p:r]划分为两个子数组A[p:q-1] 和 A[q+1:r],使得A[p:q-1]中的元素都小于等于A[q],且 A[q+1:r]中的元素都大于等于A[q],其中计算q也是划分过程的一部分。

解决:通过递归调用快速排序对两个子数组进行排序。

合并:进行原址排序,不需要合并

def QUICKSORT(A, p, r):
    if p < r:
        q = PARTITION(A, p, r)
        QUICKSORT(A, p, q-1)
        QUICKSORT(A, q+1, r)

def PARTITION(A, p, r):
    x = A[r]
    i = p
    for j in range(p, r):
        if A[j] <= x:
            temp = A[i]
            A[i] = A[j]
            A[j] = temp
            i = i + 1

    temp = A[i]
    A[i] = A[r]
    A[r] = temp

    return i
PARTITION为快速排序的关键步骤,在位于j左边的所有元素,位置i左边的值小于等于x的值,位于i右边的大于等于x的值,循环不变式证明如下:

初始化:i的值为p,j的值也为p,循环不变式成立

保持:i < j, A[p:i]的值都小于等于x,A[i:j]的值都大于等于x,若A[j]>x则j增加1,若A[j] < x,则交换A[i] 与A[j],i,j都增加1,则A[p:i -1] < x, A[i+1:j] > x

终止:最后将x值与A[i]交换,A[i] > x,A[p:i]的值都小于等于x,A[i:j]的值都大于等于x,并返回x值所在的位置。


7.2 快速排序的性能
PARTITION的效率为theta(n),最好情况下一次PARTITION的执行将数组划分为1/2,则有T(n) = 2T(n/2) + theta(n)解之得其时间复杂度为theta(nlgn)与归并排序一样;在最坏情况下一次PARTITION将数组划分为n-1与0个,则有T(n) = T(n - 1) + T(0) + theta(n),解之得其时间复杂度为theta(n^2),与插入排序一样。对于一般的不平衡的划分,我们通常有以x为底的对数,当x < 1,logx(n) = theta(lg(n)) ,只要不是最坏情况,其复杂度总是(nlgn)。我们从平均情况对快速排序的算法进行观察,只要不是所有的情况都为最坏情况,则其算法复杂度接近于最好情况theta(nlg(n))。


7.3 快速排序的随机化版本

快速排序的平均性能依赖于输入的分布情况,若输入为平均分布则可以获得更良好的期望性能,在快速排序中引入随机抽样的随机化技术,只需要增加常数步骤便可以获得与平均分布一样的期望性能。

import random
def RANDOMIZED_PARTITION(A, p, r):
    i = random.randint(p, r)
    temp = A[i]
    A[i] = A[r]
    A[r] = temp
    return PARTITION(A, p, r)

def RANDOMIZED_QUICKSORT(A, p, r):
    if p < r:
        q = RANDOMIZED_PARTITION(A, p, r)
        RANDOMIZED_QUICKSORT(A, p, q-1)
        RANDOMIZED_QUICKSORT(A, q+1, r)


7.4 快速排序分析



习题解答


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值