分治演算法解決一個最壞O(N)時間的選擇問題
分治演算法的一個基礎定理如下
定理1:若,則方程的解是
意思是,把原問題分解成若干子問題,若這些子問題的規模之和沒有原問題大,那麼再加上處理這些子問題的時間,演算法的時間界是
選擇問題:在N個數中抽取第k小的,有幾種解法:
1.可以用優先佇列得到一個或者的時間,若k是中位數那麼時間就是
2.可以使用快速選擇演算法,每次處理一個不到原問題的子問題和線性附加時間,平均時間,但是無法保證樞紐元的壞選擇,因此最壞時間是
3.先將元素排序,自然可以得到第k小的數字,時間是
以上幾種解法中,快速選擇演算法在實踐中應用最好,但是仍然無法達到最壞時間,根本原因是樞紐元的選擇無法保證定理1成立。一般樞紐元的選擇是三數中值法,但是若3個數都是最大元,那麼是壞選擇;可以增加使用的數字數量,用常數時間排序,得到中位數,由於按照定理1只能有常數附加時間,因此使用的數字個數最多可以達到
五分化中項的中項:改進樞紐元選擇如下:
1.把N個元素分成組,5個元素一組,剩餘不到5個的一組可以忽略
2.找出每組的中項,得到箇中項的表M
3.求出M的中項,將其作為樞紐元返回
定理2:使用五分化中項的中項進行樞紐元選擇,快速選擇演算法最壞時間
證明:
設,可以這樣假設不影響時間界的計算,如下圖:
其中,每一列是5個元素的一組,中間的格子是5個元素的中項,第三行就是所有中項,所有中項的中項用Mid表示,一共2k+1組,顯然有k組中,每組有3個元素比Mid大,一共3k個元素,Mid自己所在的組有2個比Mid大,一共3k+2個一定比Mid大的,比Mid小的數字數量同理,這樣每次處理的子問題大小最大可以達到0.7N,就是原問題的0.7倍。
到這裡得到了子問題最壞的大小,還有兩項附加工作要做:
1.在每個組中,在5個元素中選擇中項花費時間是常數,所有組就是時間
2.在0.2N箇中項中選擇中項,若用排序,那麼需要時間,顯然不行,因此需要對這些數字遞迴呼叫選擇演算法
綜上,一次遞迴呼叫,解決0.7N大小和0.2N大小的兩個子問題,加上O(N)線性時間,滿足定理1要求,得到一個的最壞時間