算法导论-第9章-中位数和顺序统计量
一个包含 \(n\) 个元素的集合中的第 \(i\) 个顺序统计量指集合中的第 \(i\) 小的元素。最小值是第 \(1\) 个顺序统计量(\(i= 1\)),最大值是第 \(n\) 个顺序统计量(\(i = n\))。
9.1节将讨论从集合中找出最小值和最大值的问题。9.2节将分析一个实用的算法,它在元素互异的条件下可以达到 \(\Omicron(n)\) 的期望运行时间。9.3节将给出一个更具有理论意义的算法,最坏情况下的运行时间为 \(\Omicron(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\) 次比较,共需 \(2n-2\) 次比较。
-
事实上,只需要最多 \(3 \lfloor n/2 \rfloor\) 次比较就可以同时找到最小值和最大值。首先,将一对输入元素相互进行比较,然后把较小的与当前最小值比较,把较大的与当前最大值进行比较。这样,每两个元素共需比较3次。
如果 \(n\) 是奇数,那么总共进行 \(3 \lfloor n/2 \rfloor\) 次比较。如果 \(n\) 是偶数,则是先进行一次初始比较,然后进行 \(3(n-2)/2\) 次比较,共 \(3n/2-2\) 次比较。因此,无论哪种情况,总的比较次数最多为 \(3 \lfloor n/2 \rfloor\)。
9.2 期望为线性时间的选择算法
需要先了解快速排序和随机化快速排序。
RANDOMIZED-SELECT以快速排序为模型。与快速排序不同的是,快速排序会递归处理划分的两边,而RANDOMIZED-SELECT只处理划分的一边。快速排序的期望运行时间为 \(\Theta(n \log n)\),而RANDOMIZED-SELECT的期望运行时间为 \(\Theta(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)