【4】快排及随机化算法

快排(Quicksort)

  • 分治算法
  • 原地排序(就在原来的数据区域内进行重排,像插入排序,在原来的区域完成排序,归并排序额外的空间进行排序)

分治

  • 分,快速排序将数据划分为几份,所以快排通过选取一个关键数据,再根据它的大小把原数据分为两个子数组(第一个数组的元素都比这个主元素小,第一个数组的元素都比这个主元素大或相等)
  • 治,用递归处理两个子数组的排序
  • 合并,连接

【4】快排及随机化算法

(A,p,q)(A,p,q)

定义(A,p,q)(A,p,q)算法,表示从元素p到元素q的快速排序,输出结果为将小于主元素(位置p的元素)排在主元素之前,将大于等于主元素(位置p的元素)排在主元素之后。
【4】快排及随机化算法

(A,p,q)(A,p,q)例子

【4】快排及随机化算法

Pseudocode for quicksort

【4】快排及随机化算法

快排分析

  • 假设元素都不相同
  • 当有重复元素的时候也可以运行,但有更好的算法
  • 最坏情况分析
    • 每次主元素都是大于或者小于其他元素,T(n)=T(0)+T(n1)+Θ(n)=Θ(1)+T(n1)+Θ(n)=T(n1)+Θ(n)=Θ(n2)T(n)=T(0)+T(n-1)+\Theta(n)=\Theta(1)+T(n-1)+\Theta(n)=T(n-1)+\Theta(n)=\Theta(n^2) ,尽管最差情况下的快速排序算法和插入排序的算法复杂度是一样的,但是快排仍然是一个好算法,因为快排的平均算法复杂度小

最坏情况下的快排

【4】快排及随机化算法

最好情况下的快排

【4】快排及随机化算法

正常情况下的快排(以1:9为例)

T(n)T(n)的上下届都趋近于Θ(nlgn)\Theta(nlgn)
cnlog10n+Θ(n)T(n)cnlog10/9n+Θ(n)cnlog_{10}n+\Theta(n) \le T(n) \le cnlog_{10/9}n+\Theta(n)
【4】快排及随机化算法

正常情况下的快排(好坏情况交替发生)

现在我们考虑好坏情况交替发生的情况,

  • 好的情况:L(n)=2U(n/2)+Θ(n)L(n)=2U(n/2)+\Theta(n)
  • 坏的情况:U(n)=L(n1)+Θ(n)U(n)=L(n-1)+\Theta(n)
    U(n)U(n)L(n)L(n)替换,得L(n)=2(L(n/21)+Θ(n/2))+Θ(n)=2L(n/21)+Θ(n)=Θ(n)L(n)=2(L(n/2-1)+\Theta(n/2))+\Theta(n)=2L(n/2-1)+\Theta(n)=\Theta(n)

【4】快排及随机化算法

综上,随机选择主元——随机化快速排序。

随机化快速排序(Randomized quicksort)

简介

其运行时间不依赖于输入序列的顺序(与打乱输入同理)。算法的效率与输入顺序无关。原始的快速排序在输入顺序和逆序序列时很慢,在随机的序列表现很好。随机化快速排序随机选取主元素也能达到这种效果且无需对分布做任何假设(没有一种分布会引起最差的结果)
【4】快排及随机化算法

分析(数学高能预警)

T(n)T(n)为运行时间的随机变量,假设随机数(主元素)是独立的。
为了进行分析,k表示选取的主元素(0,1,n10,1,\dots n-1)。在我们选择一个特定分划的情况下当产生k:(nk1)k:(n-k-1)分划时,随机变量Xk=1X_k=1Xk=1X_k=1表示划分的结果是左边k个元素,右边(n-k-1)个元素)。
【4】快排及随机化算法
【4】快排及随机化算法

【4】快排及随机化算法

【4】快排及随机化算法
【4】快排及随机化算法

实战中

  • 随机化快排的期望E(T(n))=Θ(nlgn)E(T(n))=\Theta(nlgn)
  • 随机化快排通常比归并排序快两三倍(编程优化)
  • 在虚拟内存的缓存中性能比较好