算法导论 — 7.3 快速排序的随机化版本

本文深入探讨了快速排序算法在面对非随机输入时的效率问题,特别是在输入数据基本有序的情况下。通过引入随机性,随机化版本的快速排序能有效提升算法在特定应用场景下的平均时间复杂度,达到Θ(nlgn)。同时,文章分析了随机化算法的期望运行时间,而非最坏运行时间的原因,并详细解释了在不同情况下,随机数生成器被调用的次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

笔记

7.2节提到,快速排序的平均情况时间复杂度为Θ(nlgn)Θ(n{\rm lg}n)Θ(nlgn)。然而实际应用中,输入数据有可能并不是完全随机排列的。比如,练习7.2-4描述的应用,需要排序的绝大多数输入数组都已经是基本有序的,在这种应用中,快速排序的效率总是十分低下。
  为了避免在某些应用中,由于输入数据并不是完全随机排列的,它们可能具备或大致上具备某种规律性,从而导致快速排序总是效率低下,可以通过在算法中引入随机性,使得快速排序算法在这些应用中也能得到较好的期望性能。即每次调用PARTITION(A, p, r)时,随机选择一个元素作为划分主元,而不是固定选择A[r]A[r]A[r]
  在这里插入图片描述
  对于上文提到的输入数组总是基本有序的情况,随机化版本的快速排序算法也可以得到较好的平均时间复杂度。

练习

7.3-1 为什么我们分析随机化算法的期望运行时间,而不是其最坏运行时间呢?
  
  对于相同的输入,随机化算法每次运行的时间都各不相同。因此即使对于相同的输入,我们也可以认为算法的运行时间是一个随机变量。而对于一个随机变量,我们通常关注它的期望值。
  我们根本无法预测随机化算法在什么时候会出现最坏情况运行时间,因此分析最坏运时间意义不大。

7.3-2 在RANDOMIZED-QUICKSORT的运行过程中,在最坏情况下,随机数生成器RANDOM被调用了多少次?在最好情况下呢?以ΘΘΘ符号的形式给出你的答案。
  
  在RANDOMIZED-QUICKSORT的最坏情况下,对于一个包含nnn个元素的数组,划分得到的两个子数组的大小分别为n−1n-1n1000。其中,大小为n−1n-1n1的子数组会进一步划分。因此,划分过程一共被调用了n−1n-1n1次,那么随机数生成器也一共被调用了n−1n-1n1次,即Θ(n)Θ(n)Θ(n)
  在RANDOMIZED-QUICKSORT的最好情况下,每次划分都是完全平衡的划分,即划分得到的222个子数组的规模分别为⌊(n−1)/2⌋⌊(n-1)/2⌋(n1)/2⌈(n−1)/2⌉⌈(n-1)/2⌉(n1)/2。于是可以得到调用划分过程的次数,也即调用随机数生成器的次数的递归式为
  在这里插入图片描述
  有经验的读者应该一眼能看出这个递归不等式的解为T(n)=Ω(n)T(n) = Ω(n)T(n)=Ω(n)。如果要严格证明,我们需要用代入法去验证这个递归不等式。应用代入法时应当假设T(n)≥cn−dT(n) ≥ cn-dT(n)cnd,其中c>0c > 0c>0并且d>0d > 0d>0
  我们先考察初始情况,初始情况为n=0n = 0n=0n=1n = 1n=1。当n=0n = 0n=0时,有T(0)=0T(0) = 0T(0)=0,即空的子数组是不需要进行划分的。根据我们对T(n)T(n)T(n)的假设,有T(0)=0≥−dT(0) = 0 ≥ -dT(0)=0d,这个不等式显而易见是成立的 (因为我们已经假设了d>0d > 0d>0)。
  当n=1n = 1n=1时,有T(1)=0T(1) = 0T(1)=0,即单个元素的子数组也是不需要进行划分的。根据我们对T(n)T(n)T(n)的假设,有T(1)=0≥c−dT(1) = 0 ≥ c-dT(1)=0cd,显然当d≥cd ≥ cdc时,这个不等式是成立的。即只要满足不等式d≥c{\color {red} d ≥ c}dc,那么T(n)≥cn−dT(n) ≥ cn-dT(n)cndn=1n = 1n=1一定成立。
  下面进入数学归纳过程。假设T(n)≥cn−dT(n) ≥ cn-dT(n)cnd0,1,…,n−10, 1, …, n-10,1,,n1都成立。于是有
  在这里插入图片描述
  为了让T(n)≥cn−dT(n) ≥ cn-dT(n)cnd成立,我们令cn−2c−2d+1≥cn−dcn-2c-2d+1≥cn-dcn2c2d+1cnd,可以得到d≤1−2cd ≤ 1-2cd12c。这说明只要满足不等式d≤1−2c{\color {red} d ≤ 1-2c}d12c,就可以使得T(n)≥cn−dT(n) ≥ cn-dT(n)cnd成立。
  综合初始情况和归纳过程,可以得到只要满足不等式0&lt;c≤d≤1−2c{\color {red} 0 &lt; c ≤ d ≤ 1-2c}0<cd12c,就可以使得T(n)≥cn−dT(n) ≥ cn-dT(n)cnd对所有nnn的取值都成立。比如我们可以取c=1/3c = 1/3c=1/3并且d=1/3d = 1/3d=1/3,此时不等式0&lt;c≤d≤1−2c0 &lt; c ≤ d ≤ 1-2c0<cd12c是成立的,于是可以断言
  在这里插入图片描述
  以上只得到了T(n)T(n)T(n)的下限。而T(n)T(n)T(n)的上限是显而易见的,即T(n)≤nT(n) ≤ nT(n)n,因为数组一共有nnn个元素,每个元素至多被选为划分主元一次。综上所述,T(n)=Θ(n)T(n) = Θ(n)T(n)=Θ(n)。即在RANDOMIZED-QUICKSORT的最好情况下,随机数生成器被调用的次数也为Θ(n)Θ(n)Θ(n)
  这里再多提一下,为什么初始情况要考察n=0n = 0n=0n=1n = 1n=1两项?首先我们要证明的不等式T(n)≥cn−dT(n) ≥ cn-dT(n)cndnnn的取值范围是n≥0n ≥ 0n0,因此初始情况必须包含n=0n = 0n=0。而递归不等式T(n)≥2T(⌊(n−1)/2⌋)+1T(n)≥2T(⌊(n-1)/2⌋)+1T(n)2T((n1)/2)+1nnn的取值范围是n≥2n ≥ 2n2,因为将n=1n = 1n=1代入这个不等式得到T(1)≥2T(0)+1=1T(1) ≥ 2T(0) + 1 = 1T(1)2T(0)+1=1,这显然是不成立的 (因为T(1)T(1)T(1)等于000)。所以进入数学归纳过程必须将n=1n = 1n=1排除在外,而应当从n=2n = 2n=2开始归纳,故n=1n = 1n=1就被列入初始情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值