Problem 2: Select the tth Largest(Knuth 论文第二题研讨)

Problem 2: Select the t t tth Largest (Knuth 论文第二题研讨)

1.问题背景

对给定的 n n n个数 x [ 1 ] , x [ 2 ] , ⋯   , x [ n ] x[1],x[2],\cdots,x[n] x[1],x[2],,x[n],保证这 n n n个数互不相等,找到第 t t t大的数。 Hoare给出了这样一个通过反复比较来达成目标的一个算法:考虑快速排序中的思想,选择其中的任意一个元素 y y y,将它与其它 n − 1 n-1 n1个数依次比较,随后将其放到第 k k k个位置,保证右边的数都比它小,左边的数都比它大,这样 y y y就保证了是第 k k k大的元素。(这里的左大右小和快速排序是相反的,但是可以方便表述。)

如果 k = t k=t k=t,就找到了第 t t t大的元素;

如果 k > t k>t k>t,则用同样的方法在 x [ 1 ] , ⋯   , x [ k − 1 ] x[1],\cdots,x[k-1] x[1],,x[k1]中找第 t t t大的元素;

如果 k < t k<t k<t,则用同样的方法在 x [ k + 1 ] , ⋯   , x [ n ] x[k+1],\cdots, x[n] x[k+1],,x[n]中找第 ( t − k ) (t-k) (tk)大的元素。

2.代码
int find(x, i, j, t){
    int key = x[i];
	k = Partition(x, i, j, key)- i + 1;
    if(k == t) return a[k];
    else if(k > t) return find(x, i, k - 1, t);
    else return find(x, k + 1, j, t - k);
}
3.复杂度分析

C ( n , t ) C(n,t) C(n,t)表示在 n n n个数中找第 t t t大的数的比较次数。那么最基本的有
C ( 1 , 1 ) = 0 C(1,1)=0 C(1,1)=0

寻找递推式:

k = 1 k=1 k=1, C ( n , t ) = n − 1 + C ( n − 1 , t − 1 ) C(n,t)=n-1+C(n-1,t-1) C(n,t)=n1+C(n1,t1)

k = 2 , C ( n , t ) = n − 1 + C ( n − 2 , t − 2 ) k=2,C(n,t)=n-1+C(n-2,t-2) k=2,C(n,t)=n1+C(n2,t2)

⋯ \cdots

k = t , C ( n , t ) = n − 1 k=t,C(n,t)=n-1 k=t,C(n,t)=n1

k = t + 1 , C ( n , t ) = n − 1 + C ( t , t ) k=t+1,C(n,t)=n-1+C(t,t) k=t+1,C(n,t)=n1+C(t,t)

⋯ \cdots

k = n , C ( n , t ) = n − 1 + C ( n − 1 , t ) k=n,C(n,t)=n-1+C(n-1,t) k=n,C(n,t)=n1+C(n1,t)

由于 k k k在每个位置出现的概率相等,将上述 n n n个式子相加求平均值即可得到
C ( n , t ) = n − 1 + 1 n ( A ( n , t ) + B ( n , t ) ) C(n,t)=n-1+\dfrac{1}{n}(A(n,t)+B(n,t)) C(n,t)=n1+n1(A(n,t)+B(n,t))
其中:
A ( n , t ) = C ( n − 1 , t − 1 ) + ⋯ + C ( n − t + 1 , 1 ) B ( n , t ) = C ( t , t ) + C ( t + 1 , t ) + ⋯ + C ( n − 1 , t ) A(n,t)=C(n-1,t-1)+\cdots+C(n-t+1,1)\\ B(n,t)=C(t,t)+C(t+1,t)+\cdots+C(n-1,t) A(n,t)=C(n1,t1)++C(nt+1,1)B(n,t)=C(t,t)+C(t+1,t)++C(n1,t)
首先通过观察得到
A ( n + 1 , t + 1 ) = A ( n , t ) + C ( n , t ) B ( n + 1 , t + 1 ) = B ( n , t ) + C ( n , t ) A(n+1,t+1)=A(n,t)+C(n,t)\\ B(n+1,t+1)=B(n,t)+C(n,t) A(n+1,t+1)=A(n,t)+C(n,t)B(n+1,t+1)=B(n,t)+C(n,t)
由上述式子,计算
( n + 1 ) C ( n + 1 , t + 1 ) − n C ( n , t + 1 ) − n C ( n , t ) + ( n − 1 ) C ( n − 1 , t ) ( 带 入 上 述 等 式 ) = 2 + C ( n , t ) − 2 C ( n − 1 , t ) + C ( n , t + 1 ) (n+1)C(n+1,t+1)-nC(n,t+1)-nC(n,t)+(n-1)C(n-1,t)(带入上述等式)\\ =2+C(n,t)-2C(n-1,t)+C(n,t+1) (n+1)C(n+1,t+1)nC(n,t+1)nC(n,t)+(n1)C(n1,t)=2+C(n,t)2C(n1,t)+C(n,t+1)
整理即得:
C ( n + 1 , t + 1 ) − C ( n , t + 1 ) − C ( n , t ) + C ( n − 1 , t ) = 2 n + 1 . ( ∗ ) C(n+1,t+1)-C(n,t+1)-C(n,t)+C(n-1,t)=\dfrac{2}{n+1}.\quad (*) C(n+1,t+1)C(n,t+1)C(n,t)+C(n1,t)=n+12.()

由于上式隐含了条件 n ≥ t + 1 n\ge t+1 nt+1,由对称性, t t t有隐藏范围 1 < t < n 1<t<n 1<t<n

对边界进行检查:考虑 t = 1 t=1 t=1 t = n t=n t=n的情况
C ( n , 1 ) = n − 1 + 1 n ( C ( 1 , 1 ) + C ( 2 , 1 ) + ⋯ + C ( n − 1 , 1 ) ) ( 1 ) C ( n + 1 , 1 ) = n + 1 n + 1 ( C ( 1 , 1 ) + C ( 2 , 1 ) + ⋯ + C ( n , 1 ) ) ( 2 ) ( 2 ) ∗ ( n + 1 ) − ( 1 ) ∗ n : C ( n + 1 , 1 ) − C ( n , 1 ) = 2 − 2 n + 1 C(n,1)=n-1+\dfrac{1}{n}(C(1,1)+C(2,1)+\cdots+C(n-1,1))\quad (1)\\ C(n+1,1)=n+\dfrac{1}{n+1}(C(1,1)+C(2,1)+\cdots+C(n,1))\quad (2)\\ (2)*(n+1)-(1)*n:\\ C(n+1,1)-C(n,1)=2-\dfrac{2}{n+1} C(n,1)=n1+n1(C(1,1)+C(2,1)++C(n1,1))(1)C(n+1,1)=n+n+11(C(1,1)+C(2,1)++C(n,1))(2)(2)(n+1)(1)n:C(n+1,1)C(n,1)=2n+12
因此累加即得
C ( n , 1 ) = 2 n − 2 H ( n ) , H ( n ) = 1 + 1 2 + ⋯ + 1 n C(n,1)=2n-2H(n), H(n)=1+\dfrac{1}{2}+\cdots+\dfrac{1}{n} C(n,1)=2n2H(n),H(n)=1+21++n1
由对称性同理可得 C ( n , n ) = C ( n , 1 ) = 2 n − H ( n ) C(n,n)=C(n,1)=2n-H(n) C(n,n)=C(n,1)=2nH(n)

再考虑 ( ∗ ) (*) ()式,将这个式子看作是关于 n n n的等式,依次将 n n n递减至 t + 1 t+1 t+1,观察:
C ( n + 1 , t + 1 ) − C ( n , t + 1 ) − C ( n , t ) + C ( n − 1 , t ) = 2 n + 1 . C ( n , t + 1 ) − C ( n − 1 , t + 1 ) − C ( n − 1 , t ) + C ( n − 2 , t ) = 2 n . C ( n − 1 , t + 1 ) − C ( n − 2 , t + 1 ) − C ( n − 2 , t ) + C ( n − 3 , t ) = 2 n − 1 . ⋯ C ( t + 2 , t + 1 ) − C ( t + 1 , t + 1 ) − C ( t + 1 , t ) + C ( t , t ) = 2 t + 2 C(n+1,t+1)-C(n,t+1)-C(n,t)+C(n-1,t)=\dfrac{2}{n+1}.\\ C(n,t+1)-C(n-1,t+1)-C(n-1,t)+C(n-2,t)=\dfrac{2}{n}.\\ C(n-1,t+1)-C(n-2,t+1)-C(n-2,t)+C(n-3,t)=\dfrac{2}{n-1}.\\ \cdots\\ C(t+2,t+1)-C(t+1,t+1)-C(t+1,t)+C(t,t)=\dfrac{2}{t+2} C(n+1,t+1)C(n,t+1)C(n,t)+C(n1,t)=n+12.C(n,t+1)C(n1,t+1)C(n1,t)+C(n2,t)=n2.C(n1,t+1)C(n2,t+1)C(n2,t)+C(n3,t)=n12.C(t+2,t+1)C(t+1,t+1)C(t+1,t)+C(t,t)=t+22
将上述所有等式相加即得:
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)&=\dfrac{2}{n+1}+\dfrac{2}{n}+\cdots+\dfrac{2}{t+2}+C(t+1,t+1)-C(t,t)\\ &=2(H(n+1)-H(t+1))+2-\dfrac{2}{t+1} \end{aligned} C(n+1,t+1)C(n,t)=n+12+n2++t+22+C(t+1,t+1)C(t,t)=2(H(n+1)H(t+1))+2t+12

由这个迭代式即可求出
C ( n , t ) = 2 ∑ 2 ≤ k ≤ t ( H ( n − t + k ) − H ( k ) + 1 − 1 k ) + C ( n + 1 − t , 1 ) = 2 ( ( n + 1 ) H ( n ) − ( n + 3 − t ) H ( n + 1 − t ) − ( t + 2 ) H ( t ) + 3 + n ) \begin{aligned} C(n,t)&=2\sum_{2\le k\le t}(H(n-t+k)-H(k)+1-\dfrac{1}{k})+C(n+1-t,1)\\ &=2((n+1)H(n)-(n+3-t)H(n+1-t)-(t+2)H(t)+3+n) \end{aligned} C(n,t)=22kt(H(nt+k)H(k)+1k1)+C(n+1t,1)=2((n+1)H(n)(n+3t)H(n+1t)(t+2)H(t)+3+n)
注意这一步要使用调和级数函数的一个求和公式:
∑ k = 1 n H ( k ) = ( n + 1 ) H ( n ) − n \sum_{k=1}^{n} H(k)=(n+1)H(n)-n k=1nH(k)=(n+1)H(n)n

因此,对于给定的 t t t, 这个比较次数是 O ( n ) O(n) O(n)的,比排序算法的 O ( n l o g n ) O(nlogn) O(nlogn)要快。

原论文:Mathematical Analysis of Algorithms, Donald Knuth
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值