Mathematical Analysis of Algorithms中有关选择第t大的数的算法分析

本文详细分析了Donald.E.Knuth在Mathematical Analysis of Algorithms中提出的寻找数组中第t大的数的算法,通过递归和Partition操作,避免完全排序,讨论了时间复杂度为O(nlogn)的证明过程。
摘要由CSDN通过智能技术生成
开头废话

这个问题是Donald.E.Knuth在他发表的论文Mathematical Analysis of Algorithms中提到的,这里对他的算法分析过程给出了更详细的解释。

问题描述:

给定一个数组a[1,2,…,n],用尽量少的比较次数找出数组中第t大的数。(假定这n个数两两不同)。

算法描述:

对于这个问题,可以很容易想到对应的算法。一个 O ( n log ⁡ n ) O(n\log n) O(nlogn) 的排序算法总能解决问题(然鹅今天我们并不对数组进行完全的排序)。
参照快速排序中的Partition操作,将元素a[i]放到某个位置 k k k,使得排在它前面的元素都比它大(但不一定按照从大到小的次序排列),后面的元素都比它小。再根据a[i]的位置 k k k t t t的大小关系,缩小查找范围再对子问题求解。
对于每一次Partition操作,会有这样的3种情况:
(1).若 k = t k=t k=t,算法结束。
(2).若 k > t k>t k>t,则对a[i]~a[k-1]递归地求解
(3).若 k < t k<t k<t,则对a[k+1]~a[j]递归地求解

时间复杂度分析

在这个问题的求解过程中,产生子问题的规模不断缩小。其中影响子问题的变量有 n n n(数组的长度)和 t t t(待查找的t)。Knuth记 C n , t C_{n,t} Cn,t为在 n n n个元素的数组中选择第 t t t大的数所需的平均比较次数,这里有一个前提,我们假设数组的排列是随机的,每一次Partition找到第1,第2,…,第n大的数概率均为 1 n \frac 1 n n1

于是我们可以得到这样的式子:
C 1 , 1 = 0 C n , t = n − 1 + 1 n ( A n , t + B n , t + 0 ) \begin {aligned} C_{1,1}&=0\\ C_{n,t}&=n-1+\frac 1n (A_{n,t}+B_{n,t}+0) \end {aligned} C1,1Cn,t=0=n1+n1(An,t+Bn,t+0)其中 A n , t A_{n,t} An,t B n , t B_{n,t} Bn,t的定义如下: A n , t = C n − 1 , t − 1 + C n − 2 , t − 2 + ⋯ + C n − t + 1 , 1 B n , t = C t , t + C t + 1 , t + ⋯ + C n − 1 , t \begin {aligned} A_{n,t}&=C_{n-1,t-1}+C_{n-2,t-2}+\cdots+C_{n-t+1,1}\\ B_{n,t}&=C_{t,t}+C_{t+1,t}+\cdots+C_{n-1,t} \end {aligned} An,tBn,t=Cn1,t1+Cn2,t2++Cnt+1,1=Ct,t+Ct+1,t++Cn1,t这里 A n , t A_{n,t} An,t对应的是递归过程中所有 k < t k<t k<t的情况。对于这些情况,我们从数组的第 k + 1 k+1 k+1项开始向后的部分进行求解,如果把这部分看作一个新的数组,那么原始数组中第 t t t大的数,在新的数组中是第 t − k t-k tk大的,也就是说这部分子问题是查找长度为 n − k n-k nk的数组中第 t − k t-k tk大的元素,其中 1 ≤ k ≤ n . 1\leq k \leq n. 1kn.

类似的, B n , t B_{n,t} Bn,t对应所有 k > t k>t k>t的情况,将数组第一项到第 k − 1 k-1 k1项取出,看作一个新的数组,原始数组中第 t t t大的数,在这新的数组中仍然是第 t t t大,所以这部分的子问题是在长度为 k − 1 k-1 k1的数组中选择第 t t t大的数,其中 t + 1 ≤ k ≤ n . t+1\leq k \leq n. t+1kn.

括号内剩下的一项 0 0 0,对应的是 k = t k=t k=t的情况,因为此时算法结束,不需要再求解子问题,所以比较次数为 0. 0. 0.括号外的 n − 1 n-1 n1是一次Partition要进行的比较次数。

这样,括号内就等于所有可能规模子问题的比较次数的总和,将它乘以 1 n \frac 1n n1,就得到子问题比较次数的数学期望,即我们所求的平均情况下的预期比较次数。

通过观察我们可以得到以下的递推公式:
A n + 1 , t + 1 = C n − 1 , t − 1 + C n − 2 , t − 2 + ⋯ + C n − t + 1 , 1 + C n , t = A n , t + C n , t B n + 1 , t = C t , t + C t + 1 , t + ⋯ + C n − 1 , t + C n + 1 − 1 , t = B n , t + C n , t \begin {aligned} A_{n+1,t+1}&=C_{n-1,t-1}+C_{n-2,t-2}+\cdots+C_{n-t+1,1}+C_{n,t}=A_{n,t}+C_{n,t}\\ B_{n+1,t}&=C_{t,t}+C_{t+1,t}+\cdots+C_{n-1,t}+C_{n+1-1,t}=B_{n,t}+C_{n,t} \end{aligned} An+1,t+1Bn+1,t=Cn1,t1+Cn2,t2++Cnt+1,1+Cn,t=An,t+Cn,t=Ct,t+Ct+1,t++Cn1,t+Cn+11,t=Bn,t+Cn,t由上述等式作差消法,可以得到:
( n + 1 ) C n + 1 , t + 1 − n C n , t + 1 − n C n , t + ( n − 1 ) C n − 1 , t = ( n + 1 ) n − n ( n − 1 ) − n ( n − 1 ) + ( n − 1 ) ( n − 2 ) + ( A n + 1 , t + 1 − A n , t ) − ( A n , t + 1 − A n − 1 , t ) + ( B n + 1 , t + 1 − B n , t + 1 ) − ( B n , t − B n − 1 , t ) = 2 + C n , t − C n − 1 , t + C n , t + 1 − C n − 1 , t (n+1)C_{n+1,t+1}-nC_{n,t+1}-nC_{n,t}+(n-1)C_{n-1,t}\\ =(n+1)n-n(n-1)-n(n-1)+(n-1)(n-2)\\+(A_{n+1,t+1}-A_{n,t})-(A_{n,t+1}-A_{n-1,t})+(B_{n+1,t+1}-B_{n,t+1})-(B_{n,t}-B_{n-1,t}) \\ =2+C_{n,t}-C_{n-1,t}+C_{n,t+1}-C_{n-1,t} (n+1)Cn+1,t+1nCn,t+1nCn,t+(n1)Cn1,t=(n+1)nn(n1)n(n1)+(n1)(n2)+(An+1,t+1An,t)(An,t+1An1,t)+(Bn+1,t+1Bn,t+1)(Bn,tBn1,t)=2+Cn,tCn1,t+Cn,t+1Cn1,t合并同类项即可得到:
( n + 1 ) C n + 1 , t + 1 − ( n + 1 ) C n , t + 1 − ( n + 1 ) C n , t + ( n + 1 ) C n − 1 , t = 2 ⇓ C n + 1 , t + 1 − C n , t + 1 − C n , t + C n − 1 , t = 2 n + 1 (n+1)C_{n+1,t+1}-(n+1)C_{n,t+1}-(n+1)C_{n,t}+(n+1)C_{n-1,t}=2\\\Downarrow\\ C_{n+1,t+1}-C_{n,t+1}-C_{n,t}+C_{n-1,t}=\frac{2}{n+1} (n+1)Cn+1,t+1(n+1)Cn,t+1(n+1)Cn,t+(n+1)Cn1,t=2Cn+1,t+1Cn,t+1Cn,t+Cn1,t=n+12
接下来我们考察边界条件,当 t = 1 t=1 t=1时,由以上的式子我们可以得到下述方程组:
{ C n , 1 = n − 1 + 1 n ( C 1 , 1 + C 2 , 1 + ⋯ + C n − 1 , 1 ) B n , 1 = C 1 , 1 + C 2 , 1 + ⋯ + C n − 1 , 1 B n + 1 , 1 = B n , 1 + C n , 1 C n , 1 = n − 1 + 1 n ( B n , 1 ) C n + 1 , 1 = n + 1 n + 1 ( B n + 1 , 1 ) \left\{ \begin{array}{l} C_{n,1}= n-1+\frac{1}{n}(C_{1,1}+C_{2,1}+\cdots +C_{n-1,1})\\ B_{n,1}=C_{1,1}+C_{2,1}+\cdots+C_{n-1,1}\\ B_{n+1,1}=B_{n,1}+C_{n,1}\\ C_{n,1}=n-1+\frac{1}{n}(B_{n,1})\\ C_{n+1,1}=n+\frac{1}{n+1}(B_{n+1,1}) \end{array} \right. Cn,1=n1+n1(C1,1+C2,1++Cn1,1)Bn,1=C1,1+C2,1++Cn1,1Bn+1,1=Bn,1+Cn,1Cn,1=n1+n1(Bn,1)Cn+1,1=n+n+11(Bn+1,1)消去方程组中包含 B B B的项,可以得到:
( n + 1 ) C n + 1 , 1 − n C n , 1 = ( n + 1 ) n − n ( n − 1 ) + C n , 1 C n + 1 , 1 − C n , 1 = 2 − 2 n + 1 ( ∗ ) \begin{aligned} (n+1)C_{n+1,1}-nC_{n,1} &= (n+1)n-n(n-1)+C_{n,1}\\ C_{n+1,1}-C_{n,1}&=2-\frac{2}{n+1} \quad\quad(*) \end{aligned} (n+1)Cn+1,1nCn,1Cn+1,1Cn,1=(n+1)nn(n1)+Cn,1=2n+12()接下来求解 C n , 1 C_{n,1} Cn,1:
列出方程组:
{ C 1 , 1 = 0 C 2 , 1 − C 1 , 1 = 2 − 2 2 C 3 , 1 − C 2 , 1 = 2 − 2 3 ⋯ C n , 1 − C n − 1 , 1 = 2 − 2 n \left\{ \begin{array}{c} \begin{aligned} C_{1,1}&=0\\ C_{2,1}-C_{1,1}&=2-\frac22\\ C_{3,1}-C_{2,1}&=2-\frac23\\ \cdots\\ C_{n,1}-C_{n-1,1}&=2-\frac2n\\ \end{aligned} \end{array} \right.\\ C1,1C2,1C1,1C3,1C2,1Cn,1Cn1,1=0=222=232=2n2将以上 n n n个方程求和,最终左边只剩下 C n , 1 C_{n,1} Cn,1,得到如下式子:
C n , 1 = 2 ( n − 1 ) − 2 ∑ k = 2 n 1 k ⇓ C n , 1 = 2 n − 2 ∑ k = 1 n 1 k = 2 n − 2 H n \begin{aligned} C_{n,1}&=2(n-1)-2\sum_{k=2}^n \frac1k\\ \quad\Downarrow \\ C_{n,1}&=2n-2\sum_{k=1}^n\frac1k=2n-2H_n \end{aligned} Cn,1Cn,1=2(n1)2k=2nk1=2n2k=1nk1=2n2Hn这里的 H n H_n Hn表示调和级数的前 n n n项部分和。
由于问题具有的对称性(这部分可自行证明), C n , n = C n , 1 = 2 n − 2 H n C_{n,n}=C_{n,1}=2n-2H_n Cn,n=Cn,1=2n2Hn,将此式记作 ( Δ ) (\Delta) (Δ)
( ∗ ) (*) ()式,可以列出以下方程组:
{ ( C n + 1 , t + 1 − C n , t ) − ( C n , t + 1 − C n − 1 , t ) = 2 n + 1 ( C n , t + 1 − C n − 1 , t ) − ( C n − 1 , t + 1 − C n − 2 , t ) = 2 n ⋯ ( C t + 2 , t + 1 − C t + 1 , t ) − ( C t + 1 , t + 1 − C t , t ) = 2 t + 2 \left\{ \begin{array}{l} (C_{n+1,t+1}-C_{n,t})-(C_{n,t+1}-C_{n-1,t})=\frac2{n+1}\\ (C_{n,t+1}-C_{n-1,t})-(C_{n-1,t+1}-C_{n-2,t})=\frac2{n}\\ \quad\quad\quad\quad\quad\quad\quad\quad\cdots\\ (C_{t+2,t+1}-C_{t+1,t})-(C_{t+1,t+1}-C_{t,t})=\frac2{t+2}\\ \end{array} \right.\\ (Cn+1,t+1Cn,t)(Cn,t+1Cn1,t)=n+12(Cn,t+1Cn1,t)(Cn1,t+1Cn2,t)=n2(Ct+2,t+1Ct+1,t)(Ct+1,t+1Ct,t)=t+22再次对这 n − t n-t nt个方程累加,并联立 ( Δ ) (\Delta) (Δ)式,可以得到:
C n + 1 , t + 1 − C n , t = 2 n + 1 + 2 n + ⋯ + 2 t + 2 + C t + 1 , t + 1 − C t , t = 2 ( H n + 1 − H t + 1 ) + 2 − 2 t + 1 \begin{aligned} C_{n+1,t+1}-C_{n,t}&=\frac{2}{n+1}+\frac{2}{n}+\cdots+\frac{2}{t+2}+C_{t+1,t+1}-C_{t,t}\\ &=2(H_{n+1}-H_{t+1})+2-\frac{2}{t+1} \end{aligned} Cn+1,t+1Cn,t=n+12+n2++t+22+Ct+1,t+1Ct,t=2(Hn+1Ht+1)+2t+12依次写出 C n , t − C n − 1 , t − 1 C_{n,t}-C_{n-1,t-1} Cn,tCn1,t1 C 2 , 2 − C 1 , 1 C_{2,2}-C_{1,1} C2,2C1,1 n − 1 n-1 n1个方程并再次累加(过程略去),可以推出:
C n , t = 2 ∑ 2 ≤ k ≤ t ( H n − t + k − H k + 1 − 1 k ) + C n + 1 − t , 1 C_{n,t}=2\sum_{2\leq k\leq t}(H_{n-t+k}-H_{k}+1-\frac1k)+C_{n+1-t,1} Cn,t=22kt(Hnt+kHk+1k1)+Cn+1t,1
化简后:
C n , t = 2 ( ( n + 1 ) H n − ( n + 3 − t ) H n + 1 − t − ( t + 2 ) H t + n + 3 ) , ( 1 ≤ t ≤ n ) C_{n,t}=2((n+1)H_n-(n+3-t)H_{n+1-t}-(t+2)H_t+n+3),\quad(1\leq t\leq n) Cn,t=2((n+1)Hn(n+3t)Hn+1t(t+2)Ht+n+3),(1tn)
由于 t t t n n n同阶,且平均情况下 t t t的数学期望 E ( t ) = 2 n E(t)=\frac 2n E(t)=n2,又 H n = Θ ( log ⁡ n ) H_n=\Theta(\log n) Hn=Θ(logn) ,所以:
C n , t = O ( n log ⁡ n ) C_{n,t}=O(n\log n) Cn,t=O(nlogn)至此,时间复杂度的证明结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值