您的位置:首页 > 其它

第七章 快速排序

2015-08-24 15:50 267 查看
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 快速排序分析











习题解答
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: