演算法(二) 分治法

2021-09-08 18:13:28 字數 2179 閱讀 8332

分治法的適⽤條件:

• 該問題的規模縮⼩到⼀定程度就可以容易地解決。

• 該問題可以分解為若⼲個規模較⼩的相同問題:遞迴思想的應⽤

• 該問題所分解出的各個⼦問題是相互獨⽴的,即⼦問題之間不包含公共的⼦問題。

• 利⽤該問題分解出的⼦問題的解可以合併為該問題的解。

案例---快排:

(1)過程

• divide (partition)

– 對元素進⾏重排以得到這樣⼀個劃分

• 在某個位置s前⾯的所有元素都⼩於等於a[s]

• 在位置s後⾯的所有元素都⼤於等於a[s]

• conquer: ⼀個劃分確定後, a[s]的位置便確定,再對兩個⼦陣列遞迴地劃分

• combine: 原地排序in-place sort,⽆需合併

(2)演算法分析

最好情況:所有劃分均產⽣規模相等的兩個⼦陣列

tbest(n) = 2tbest(n/2) + o(n), (t(1) = 0)= o(nlogn)

最壞情況下:劃分所產⽣的兩個⼦陣列分別包含n-1個元素和0個元素(待排序的陣列已排好序!) 

tworst(n) = tworst(n-1) + o(n),(t(1) = 0)= o(n2)

平均情況:假設劃分可能在任意位置s出現的概率均為1/n,則平均「⽐較」時間t(n)的遞迴關係式為:

(3) 選擇好的劃分基準,產⽣好的劃分:

找到劃分基準(近似中位數) : 「中位數的中位數」

1. 將n個元素劃分成⎡n/5⎤個組,每組5個元素(除了最後⼀組可能不是5個元素); o(1)

2. ⽤任意⼀種排序演算法將每組中的5個元素排好序,並取出每組的中位數,共⎡n/5⎤個; o(n)

3. 遞迴找出這⎡n/5⎤個中位數的中位數,作為劃分基準; t( ⎡n/5⎤ )

• divide

– 按近似中位數對輸⼊陣列進⾏partition; o(n)

• conquer

if k = s, return s // s為劃分的位置

if p < k < s, 遞迴選擇a[p…s-1]中第k⼩元素

if s < k < r, 遞迴選擇a[s+1…r]中第k-(s-p+1)⼩元素

棋盤覆蓋:

在⼀個2k×2k棋盤中,恰有⼀個⽅格與其他⽅格不同,稱該⽅格為⼀特殊⽅格,且稱該棋盤為⼀特殊棋盤。在棋盤覆蓋問題中,要⽤圖⽰的4種不同形態的l型⾻牌覆蓋給定的特殊棋盤上除特殊⽅格以外的所有⽅格,且任何2個l型⾻牌不得重疊覆蓋。

(1)該問題有解----數學歸納法

– 當n=1時( 2×2棋盤),該問題有解;

– 假設當n=k時( 2k×2k棋盤),該問題有解;

– 那麼當n=k+1時( 2k+1×2k+1棋盤),將棋盤劃分為4個

2k×2k⼦棋盤,特殊⽅格位於4個⼦棋盤之⼀中,⽽其餘3個⼦棋盤中⽆特殊⽅格。

– 如何將這3個⽆特殊⽅格的⼦棋盤轉化為特殊棋盤?

• ⽤⼀個l型⾻牌覆蓋這3個較⼩棋盤的會合處,將原問題轉換為4個n=k時的⼦問題,因為n=k時有解,所以n=k+1時也有解。

• 當k=0時( 1×1棋盤),即特殊⽅格,⾻牌數為0;

• 當k>0時,

- divide:將2k×2k棋盤分割為4個2k-1×2k-1 ⼦棋盤。特殊⽅格位於4個較⼩⼦棋盤之⼀中,⽽其餘3個⼦棋盤中⽆特殊⽅格。

- 在遞迴之前要將原問題轉化為4個較⼩規模的相同⼦問題。

- ⽤⼀個l型⾻牌覆蓋這3個⼦棋盤的會合處

- conquer:遞迴地使⽤這種分割,直⾄棋盤縮⼩到1×1。

- combine:⽆

演算法(二) 分治法

分治法的適 條件 該問題的規模縮 到 定程度就可以容易地解決。該問題可以分解為若 個規模較 的相同問題 遞迴思想的應 該問題所分解出的各個 問題是相互獨 的,即 問題之間不包含公共的 問題。利 該問題分解出的 問題的解可以合併為該問題的解。案例 快排 1 過程 divide partition 對元...

排序 二分治

關於二分治的排序,我們用到的是遞迴思想,直至陣列只含有乙個元素的時候,再利用合併的思想,根據預先設計好的排列方式進行 的優化過程。對於合併的過程,首先應該計算陣列被分開兩端的分別長度,然後再定義兩個陣列,分別用於儲存前後兩個部分的元素,對於元素的進入,要進行所謂的正確方法,書上定義了乙個末值標記點,...

02分治演算法 01二分查詢

分治演算法的思想就是分而治之,通過將原問題分解為與原問題相似的小問題,小問題再分解為規模更小的問題.最終變成乙個個簡單易解的問題。二分查詢就是一種簡單的分治演算法。問題 給定乙個排序的整數陣列 公升序 和乙個要查詢的整數target 用o logn 的時間查詢到target第一次出現的下標 從0開始...