一个包含 n n n 个元素的集合中的第 i i i 个 顺序统计量指集合中的第 i i i 小的元素。 最小值是第 1 1 1 个顺序统计量( i = 1 i= 1 i=1), 最大值是第 n n n 个顺序统计量( i = n i = n i=n)。
9.1节将讨论从集合中找出最小值和最大值的问题。9.2节将分析一个实用的算法,它在元素互异的条件下可以达到 O ( n ) \Omicron(n) O(n) 的期望运行时间。9.3节将给出一个更具有理论意义的算法,最坏情况下的运行时间为 O ( n ) \Omicron(n) O(n) 。
9.1 最小值和最大值
MINIMUM(A)
min = A[1]
for i = 2 to A.length
if min > A[i]
min = A[i]
return min
MAXIMUM(A)
max = A[1]
for i = 2 to A.length
if max < A[i]
max = A[i]
return max
MINIMUM
和MAXIMUM
都要进行
n
−
1
n-1
n−1 次比较。
同时找到最大和最小值
-
分别独立地找到最小值和最大值,这各需要 n − 1 n-1 n−1 次比较,共需 2 n − 2 2n-2 2n−2 次比较。
-
事实上,只需要最多 3 ⌊ n / 2 ⌋ 3 \lfloor n/2 \rfloor 3⌊n/2⌋ 次比较就可以同时找到最小值和最大值。首先,将一对输入元素相互进行比较,然后把较小的与当前最小值比较,把较大的与当前最大值进行比较。这样,每两个元素共需比较3次。
如果 n n n 是奇数,那么总共进行 3 ⌊ n / 2 ⌋ 3 \lfloor n/2 \rfloor 3⌊n/2⌋ 次比较。如果 n n n 是偶数,则是先进行一次初始比较,然后进行 3 ( n − 2 ) / 2 3(n-2)/2 3(n−2)/2 次比较,共 3 n / 2 − 2 3n/2-2 3n/2−2 次比较。因此,无论哪种情况,总的比较次数最多为 3 ⌊ n / 2 ⌋ 3 \lfloor n/2 \rfloor 3⌊n/2⌋。
9.2 期望为线性时间的选择算法
需要先了解快速排序和随机化快速排序。
RANDOMIZED-SELECT以快速排序为模型。与快速排序不同的是,快速排序会递归处理划分的两边,而RANDOMIZED-SELECT只处理划分的一边。快速排序的期望运行时间为 Θ ( n log n ) \Theta(n \log n) Θ(nlogn),而RANDOMIZED-SELECT的期望运行时间为 Θ ( n ) \Theta(n) Θ(n)。
RANDOMIZED-SELECT(A, p, r, i)
if p == r
return A[p] // 1 ≤ i ≤ r - p + 1 when p == r means that i = 1
q = RANDOMIZED-PARTITION(A, p, r)
k = q - p + 1
if i == k
return A[q] // the pivot value is the answer
elseif i < k
return RANDOMIZED-SELECT(A, p, q - 1, i)
else return RANDOMIZED-SELECT(A, q + 1, r, i - k)