确定性选择算法(Deterministic Select / BFPRT)的形式化描述
给定一个数组 A 和一个整数 k($1 \leq k \leq n$,n 为 A 中的元素个数),算法目标是求出 A 中第 k 小的数。该算法的核心思想是采用"中位数的中位数"作为划分依据,可以保证最坏情况下线性时间复杂度。定一个数组 A 和一个整数 k($1 \leq k \leq n$,n 为 A 中的元素个数),算法目标是求出 A 中第 k 小的数。该算法的核心思想是采用"中位数的中位数"作为划分依据,可以保证最坏情况下线性时间复杂度。定性选择算法(Deterministic Select / BFPRT)的形式化描述
给定一个数组 A 和一个整数 k(1 ≤ k ≤ n,n 为 A 中的元素个数),算法目标是求出 A 中第 k 小的数。该算法的核心思想是采用“中位数的中位数”作为划分依据,可以保证最坏情况下线性时间复杂度。
算法步骤描述
基本情况:
当数组 A 的规模 n 较小时(例如 $n \leq 5$),直接对 A 进行排序后返回第 k 小的元素。分组:
将 A 分为 $\lceil n/5 \rceil$ 个子数组,每个子数组最多包含 5 个元素(最后一组可能少于 5 个)。找出各组中位数:
对每个子数组进行排序,取排序后中间位置的元素作为该组的中位数,所有中位数构成新数组 M。选择枢轴:
递归地对 M 使用确定性选择算法,找出 M 的中位数作为枢轴 pivot。这个 pivot 能确保良好的划分效果。划分:
根据枢轴 pivot 将原数组 A 划分成三个部分:- $L = { x \in A | x < \text{pivot} }$
- $E = { x \in A | x = \text{pivot} }$
- $G = { x \in A | x > \text{pivot} }$
递归选择:
- 若 $k \leq |L|$,则目标元素位于 L 中,递归求解 SELECT(L, k)。
- 若 $k > |L| + |E|$,则目标元素位于 G 中,递归求解 SELECT(G, k - |L| - |E|)。
- 否则,pivot 即为第 k 小的元素,返回 pivot。
伪代码
txt
FUNCTION SELECT(A, k)
// 基本情况: 当数组较小时,直接排序返回第 k 小元素
IF length(A) <= 5 THEN
SORT(A)
RETURN A[k]
ENDIF
// 将 A 分为若干组,每组最多 5 个元素
DIVIDE A INTO ceil(n/5) GROUPS of 5 elements each
// 求每组的中位数,并构成数组 M
M = an empty list
FOR EACH group G in A DO
SORT(G)
m = the median of G
ADD m to M
ENDFOR
// 递归求 M 的中位数作为枢轴
pivot = SELECT(M, ceil(length(M)/2))
// 根据 pivot 对 A 进行 partition
L = { x in A | x smaller than pivot }
E = { x in A | x equal to pivot }
G = { x in A | x larger than pivot }
// 递归选出目标值
IF k <= length(L) THEN
RETURN SELECT(L, k)
ELSEIF k > length(L) + length(E) THEN
RETURN SELECT(G, k - length(L) - length(E))
ELSE
RETURN pivot
ENDIF
END FUNCTION该伪代码展示了确定性选择算法(BFPRT)的主要流程,其核心在于利用“中位数的中位数”保证每次划分后递归调用的规模能得到有效缩减,从而实现最坏情况下的线性时间复杂度。