Fork me on GitHub

算法导论读书笔记(9)

选择问题

在一个由 n 个元素组成的集合中,第 i顺序统计量 (order statistic)是该集合中第 i 小的元素。例如,在一组元素所组成的集合中, 最小值 是第 1 个顺序统计量( i = 1 ), 最大值 是第 n 个顺序统计量( i = n )。而 中位数 (median)是它所在集合的“中点元素”。像这样从一个由 n 个不同数值构成的集合中选择其第 i 个顺序统计量的问题,可以形式化地定义为 选择问题 (selection problem):

输入: 一个包含 n 个(不同的)数的集合 A 和一个数 i ,1 <= i <= n
输出: 元素 xA ,它恰好大于 A 中其他的 i - 1个元素。

最小值和最大值

MINIMUM(A)
1 min = A[1]
2 for i = 2 to A.length
3     if min > A[i]
4         min = A[i]
5 return min
MAXIMUM(A)
1 max = A[1]
2 for i = 2 to A.length
3     if max < A[i]
4         max = A[i]
5 reutrn max

对于上面两个过程来说,只要比较 n - 1次就能找出最大值/最小值。

随机选择算法

一般选择问题看起来要比找最小值的简单选择问题更难,但两种问题的渐近运行时间却是相同的:都是 Θ ( n )。这里介绍一种解决选择问题的分治算法,即 RANDOMIZED-SELECT 算法。该算法利用了之前介绍的 RANDOMIZED-PARTITION 过程。

RANDOMIZED-SELECT(A, p, r, i)
1  if p == r
2      return A[p]
3  q = RANDOMIZED-PARTITION(A, p, r)
4  k = q - p + 1
5  if i == k    // the pivot value is the answer
6      return A[k]
7  elseif i < k
8      return RANDOMIZED-SELECT(A, p, q - 1, i)
9  else
10     return RANDOMIZED-SELECT(A, q + 1, r, i - k)

随机选择算法的最坏情况运行时间为 Θ ( n2 )。

最坏情况线性时间的选择

现在来看一个最坏情况运行时间为 Θ ( n )的选择算法 SELECT 。像 RANDOMIZED-SELECT 一样, SELECT 通过对输入数组的递归划分来找出所求元素。但是,该算法的基本思想是要保证对数组的划分是个好的划分。 SELECT 采用了取自快速排序的确定性划分算法 PARTITION ,并做了修改,把划分主元元素作为其参数。

算法 SELECT 通过执行下列步骤来确定一个有 n > 1个元素的输入数组中的第 i 小的元素。

  1. 将输入数组的 n 个元素划分成 FLOOR(n / 5) 组,每组5个元素,且至多只有一个组由剩下的 n mod 5个元素组成。
  2. 寻找 CEIL(n / 5) 个组中每一组的中位数。首先对每组中的元素(至多为5个)进行插入排序,然后从排序过的序列中选出中位数。
  3. 对第 2 步中找出的 CEIL(n / 5) 个中位数,递归调用 SELECT 以找出其中位数 x
  4. 利用修改过的 PARTITION 过程,按中位数的中位数 x 对输入数组进行划分。让 k 比划分低区的元素数目多1,所以 x 是第 k 小的元素,并且有 n - k 个元素在划分的高区。
  5. 如果 i = k ,则返回 x 。否则,如果 i < k ,则在低区递归调用 SELECT 以找出第 i 小的元素,如果 i > k ,则在高区找出第 i - k 个最小元素。
posted on 2014-04-12 18:54  sungoshawk  阅读(871)  评论(0编辑  收藏  举报