快速选择的平均时间复杂度
以快速排序算法的思路,在含有N个元素的无序列表中找到第k小元素的平均时间复杂度
快速选择
选择枢纽元,将原无序列表分为两组:小于枢纽元的在S1S_1S1组;大于枢纽元的在S2S_2S2组(假设无序列表中不存在重复元素)。令∣S1∣|S_1|∣S1∣为S1S_1S1中元素个数
- 当k<∣S1∣k<|S_1|k<∣S1∣时,第k小元素位于S1S_1S1组中,对S1S_1S1组递归执行快速选择
- 若k=∣S1∣+1k=|S_1|+1k=∣S1∣+1,此时第k小元素即是枢纽元,找到目标值
- 若k>∣S1∣+1k>|S_1|+1k>∣S1∣+1,第k小元素位于S2S_2S2组中,对S2S_2S2组递归执行快速选择
时间复杂度
k∈[1,N]k\in[1,N]k∈[1,N],且k为任意值的平均时间复杂度都是相等的,因此我们可以将问题转化为:以快速排序算法的思路,在含有N个元素的无序列表中找到第N小元素的平均时间复杂度
令T(N)为找到第N小元素的平均时间复杂度,为简化计算我们假设枢纽元的选择是在所有元素中随机等概率选取的,由此我们可以知道
- 有1/N的概率,选取到的枢纽元即是第N小元素,此时找到目标值
- 有(N-1)/N的概率,选取到的枢纽元不是第N小元素,设选取到的枢纽元为第i小元素,此时需要将N−iN-iN−i个大于枢纽元的元素递归执行快速选择。其中i是等概率的从[1,N-1]中选取的,因此需要将i所有取值的时间复杂度的均值作为平均时间复杂度
以上两种可能的任意一种都需要在选取枢纽元后对无序列表的N个元素进行分组,即需要执行N次操作
由此我们可得T(N)的递归表达式
T(N)={N,1/N的概率1/(N−1)∑i=1N−1T(N−i)+N,(N−1)/N的概率(1)
T(N)=\left\{\begin{array}{ll}
N, & 1/N的概率
\\
1/(N-1)\sum_{i=1}^{N-1} T(N-i) + N, & (N-1)/N的概率
\end{array}\right.
\tag 1
T(N)={N,1/(N−1)∑i=1N−1T(N−i)+N,1/N的概率(N−1)/N的概率(1)
我们不妨使用T(N)的期望值E(N)来替代T(N)以简化运算
E(N)=N/N+(N−1)/N×1/(N−1)∑i=1N−1E(N−i)+N−1=1/N∑i=1N−1E(N−i)+N∴T(N)=1/N∑i=1N−1T(N−i)+NNT(N)=∑i=1N−1T(N−i)+N2(2)
\begin{array}{ll}
E(N) & = N/N + (N-1)/N \times1/(N-1)\sum_{i=1}^{N-1}E(N-i) + N-1
\\
& = 1/N\sum_{i=1}^{N-1}E(N-i) + N
\\
\therefore T(N) & = 1/N\sum_{i=1}^{N-1}T(N-i) + N
\\
NT(N) & = \sum_{i=1}^{N-1}T(N-i) + N^2
\end{array}
\tag2
E(N)∴T(N)NT(N)=N/N+(N−1)/N×1/(N−1)∑i=1N−1E(N−i)+N−1=1/N∑i=1N−1E(N−i)+N=1/N∑i=1N−1T(N−i)+N=∑i=1N−1T(N−i)+N2(2)
当无序列表元素总数为N−1N-1N−1时,套用(2)可得
(N−1)T(N−1)=∑i=1N−2T(N−1−i)+(N−1)2(3)
\begin{array}{ll}
(N-1)T(N-1) & = \sum_{i=1}^{N-2}T(N-1-i) + (N-1)^2
\end{array}
\tag3
(N−1)T(N−1)=∑i=1N−2T(N−1−i)+(N−1)2(3)
(2)−(3)(2)-(3)(2)−(3)可得
NT(N)−(N−1)T(N−1)=T(N−1)+2N−1NT(N)=NT(N−1)+2N−1T(N)=T(N−1)+2−1/N(4)
\begin{array}{ll}
NT(N) - (N-1)T(N-1) & = T(N-1) + 2N - 1
\\
NT(N) & = NT(N-1) + 2N - 1
\\
T(N) & = T(N-1) + 2 - 1/N
\end{array}
\tag4
NT(N)−(N−1)T(N−1)NT(N)T(N)=T(N−1)+2N−1=NT(N−1)+2N−1=T(N−1)+2−1/N(4)
对(4)使用叠缩可得
T(N)=T(N−1)+2−1/NT(N−1)=T(N−2)+2−1/(N−1)T(N−2)=T(N−3)+2−1/(N−2)...T(2)=T(1)+2−1/2(5)
\begin{array}{ll}
T(N) & = T(N-1) + 2 - 1/N
\\
T(N-1) & = T(N-2) + 2 - 1/(N-1)
\\
T(N-2) & = T(N-3) + 2 - 1/(N-2)
\\
...
\\
T(2) & = T(1) + 2 - 1/2
\end{array}
\tag5
T(N)T(N−1)T(N−2)...T(2)=T(N−1)+2−1/N=T(N−2)+2−1/(N−1)=T(N−3)+2−1/(N−2)=T(1)+2−1/2(5)
(5)各项相加可得
T(N)=T(1)+2(N−1)+1−∑i=1N1/i(6)
\begin{array}{ll}
T(N) & = T(1) + 2(N-1) + 1 - \sum_{i=1}^N 1/i
\end{array}
\tag6
T(N)=T(1)+2(N−1)+1−∑i=1N1/i(6)
其中T(1)=1, ∑i=1N1/iT(1) = 1,\ \sum_{i=1}^N 1/iT(1)=1, ∑i=1N1/i 是调和级数,∑i=1N1/i≈lnN+γ\sum_{i=1}^N 1/i \approx lnN+\gamma∑i=1N1/i≈lnN+γ
∴T(N)=2N−lnN−γT(N)=O(N)(7)
\begin{array}{ll}
\therefore T(N) & = 2N - lnN - \gamma
\\
T(N) &= O(N)
\end{array}
\tag7
∴T(N)T(N)=2N−lnN−γ=O(N)(7)
因此快速选择的平均时间复杂度为O(N)
本文以快速排序算法思路,探讨在含N个元素无序列表中找第k小元素的平均时间复杂度。介绍快速选择方法,通过选择枢纽元分组递归查找。经推导得出快速选择的平均时间复杂度为O(N)。
4022

被折叠的 条评论
为什么被折叠?



