算法導論讀書筆記(9)
選擇問題
在一個由 n 個元素組成的集合中,第 i 個 順序統計量 (order statistic)是該集合中第 i 小的元素。例如,在一組元素所組成的集合中, 最小值 是第 1 個順序統計量( i = 1 ), 最大值 是第 n 個順序統計量( i = n )。而 中位數 (median)是它所在集合的「中點元素」。像這樣從一個由 n 個不一樣數值構成的集合中選擇其第 i 個順序統計量的問題,能夠形式化地定義爲 選擇問題 (selection problem):html
輸入: 一個包含 n 個(不一樣的)數的集合 A 和一個數 i ,1 <= i <= n 。
輸出: 元素 x ∈ A ,它剛好大於 A 中其餘的 i - 1個元素。
java
最小值和最大值
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
過程。sql
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
,並作了修改,把劃分主元元素做爲其參數。bash
算法 SELECT
經過執行下列步驟來肯定一個有 n > 1個元素的輸入數組中的第 i 小的元素。ide
- 將輸入數組的 n 個元素劃分紅
FLOOR(n / 5)
組,每組5個元素,且至多隻有一個組由剩下的 n mod 5個元素組成。 - 尋找
CEIL(n / 5)
個組中每一組的中位數。首先對每組中的元素(至多爲5個)進行插入排序,而後從排序過的序列中選出中位數。 - 對第 2 步中找出的
CEIL(n / 5)
箇中位數,遞歸調用SELECT
以找出其中位數 x 。 - 利用修改過的
PARTITION
過程,按中位數的中位數 x 對輸入數組進行劃分。讓 k 比劃分低區的元素數目多1,因此 x 是第 k 小的元素,而且有 n - k 個元素在劃分的高區。 - 若是 i = k ,則返回 x 。不然,若是 i < k ,則在低區遞歸調用
SELECT
以找出第 i 小的元素,若是 i > k ,則在高區找出第 i - k 個最小元素。