第 9 章 中位數和順序統計量

  在一個由n個元素組成的集合中,第i個順序統計量是該集合中第i小的元素。例如,在一個元素集合中,最小值是第 1 個順序統計量,最大值是第n個順序統計量(i=n)。用非形式化的描述來說,一個中位數是它所屬集合的“中點元素”。當n爲奇數時,中位數是唯一的,位與i=(n+1)/2.當n爲偶數時,存在兩個中位數,分別位與i=n/2和i=n/2+1.因此,如果不考慮n的奇偶性,中位數總是出現在i=⌊(n+1)/2⌋處(下中位數)和i=⌈(n+2)/2⌉處(上中位數)。本書中所用的中位數都是指下中位數。
  本章將討論從一個有n個互異的元素構成的集合中選擇第i個順序統計量的問題。假設集合中的元素都是互異的,將這一問題形式化定義爲如下的選擇問題
  輸入:一個包含n個(互異的)的數的集合A和一個整數i,1<= i <= n.
  輸出:元素x∈A,且A中恰好有i-1個其他小於小於它。
  我們可以利用堆排序和歸併排序在O(nlgn)時間內解決這個問題,本章介紹一些更快的方法。

9.1 最小值和最大值

下面的程序中,我們假設該集合存放在數組A中,且A.length=n
MINIMUM(A)

min = A[1]
for i = 2 to A.length
    if min > A[i]
        min = A[i]
return min

爲了確定最小值,必須要做n-1次比較。因此從所執行的比較次數來看,算法MINMUM是最優的。
同時找到最小值和最大值
分別獨立地找出最小值和最大值,共需2n-2次比較
事實上,我們只需要最多3⌊n/2⌋次比較就可以同時找到最小值和最大值。具體方法是記錄已知的最小值和最大值,對輸入元素成對地進行處理。首先將一對輸入元素相互比較,然後把較小的與當前最小值比較,較大的與當前最大值比較。這樣對每兩個元素共需3次比較。
如果n是奇數,就把最小值和最大值的初始值都設爲第一個元素的值,然後成對處理餘下的元素。如果n是偶數,就對前兩個做一次比較,然後成對處理。

9.2 期望爲線性時間的選擇算法

  一般選擇問題看起來要比找最小值這樣的問題更難,但是這兩個問題的漸近運行時間都是θ(n)。本節介紹一種解決選擇問題的分治算法。RANDOMIZED-SELECT算法以快速排序算法爲模型,將輸入數組進行遞歸劃分,與快速排序不同的是,快速排序會遞歸處理劃分的兩邊,而RANDOMIZED-SELECT只處理劃分的一邊。這一差異會在性能分析中體現出來:快速排序的期望運行時間是θ(nlgn),而RANDOMIZED-SELECT的期望運行時間爲θ(n)。這裏,假設輸入數據都是互異的。
  RANDOMIZED-SELECT利用了7.3節介紹的RANDOMIZED-PARTITION過程。與RANDOMIZED-QUICKSORT一樣,它的部分行爲是由隨機數生成器的輸出決定的,所以RANDOMIZED-SELECT也是一個隨機算法。以下是僞代碼,它返回數組A[p..r]中第i小的的元素。
RANDOMIZED-SELECT(A, p, r, i)

if p == r
    return A[p]
q = RANDOMIZED-PARTITION(A, p, r)
k = q-p+1
if i == k
    return A[q]
else if i < k
    return RANDOMIZED-SELECT(A, p, q-1, i)
else return RANDOMIZED-SELECT(A, q+1, r, i-k)

  RANDOMIZED-SELECT的最壞情況運行時間爲θn2) ,期望運行時間爲O(n)。得出結論:假設所有元素都是互異的,在期望運行時間內,可以找到任一順序統計量,特別是中位數。

9.3 最壞情況爲線性時間的選擇算法

  像RANDOMIZED-SELECT一樣,SELCT算法通過對輸入數組的遞歸劃分找出所需元素,但是,在該算法中能夠保證得到對數組的一個好的劃分。SELECT使用的也是快速排序算法的確定性劃分算法PARTITION。但做了修改,把劃分的主元也作爲輸入參數。
  通過執行下列步驟,算法SELECT可以確定一個有n>1個不同元素的輸入數組中第i小的元素。(如果n=1,則返回它的唯一輸入數值作爲第i小的元素)。
  

  1. 將輸入數組的n個元素劃分爲⌊n/5⌋,每組5個元素,且至多隻有一組由剩下的n mod 5 個元素組成。
  2. 尋找這⌈n/5⌉組中每一組的中位數:首先對每組元素進行插入排序,然後確定每組有序元素的中位數。
  3. 對第 2 步中找出的⌈n/5⌉箇中位數,遞歸調用SELECT以找出其中位數x(如果有偶數箇中位數,爲了方便,約定x是較小的中位數)
  4. 利用修改的PARTITION版本,按中位數的中位數x對輸入數組進行劃分。讓k比劃分的低區中的元素數目多1,因此,x是第k小的元素,並且有n-k個元素在劃分的高區。
  5. 如果i=k,則返回x.如果i < k,則在低區遞歸調用SELECT來找出第i小的元素,如果i>k,則在高區遞歸查找第i-k小的元素。
    推論得到算法遞歸式:
    T(n){O(1),T(n/5)+T(7n/10+6)+O(n),n<140 n 140

    這個運行時間是線性的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章