久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

分治法(一)

 桑枯海 2013-10-03

這篇文章將討論:

1)  分治策略的思想和理論

2)  幾個分治策略的例子:合并排序,,快速排序,,折半查找,二叉遍歷樹及其相關(guān)特性,。

說明:這幾個例子在前面都寫過了,,這里又拿出來,從算法設(shè)計的策略的角度把它們放在一起來比較,,看看分治是如何實現(xiàn)滴,。
由于內(nèi)容太多,我將再花一篇文章來寫4個之前沒有寫過的分治算法:1,,大整數(shù)乘法   2,,矩陣乘法的分治策略   3,最近點(diǎn)對  4,,凸包問題,,請見下一篇。

好了,,切入正題,。

---------------------------------------------------------------------------------------------------------------------------------------------------


分治算法是按照下列方案來工作的:

1)將問題的實例劃分為幾個較小的實例,最好具有相等的規(guī)模(事實上,,一般來說就是這樣來分的,,而且分為2個實例的居多,注意是遞歸的分?。,?!

2)對這些較小的實例求解(一般使用遞歸的方法,但在問題規(guī)模足夠小的時候也可以采用采用另一個算法(停止遞歸)

3)如果有必要的話,,合并這些較小問題的解,,以得到原始問題的解(事實上,一個分治算法的精華就在于合并解的過程

不要忽視這三句話?。,。∷窃S多分治算法經(jīng)驗的總結(jié),,有助于在分析問題中考慮如何去使用分治算法,提請注意括號里我的注釋?。,。?br>
形象的表示一下,,截張圖:




大多數(shù)都是規(guī)模為n的問題,,被劃分為2個規(guī)模為n/2的問題,更一般的情況下,,從理論上分析一下:

一個規(guī)模為n的實例可以劃分為b個規(guī)模為n/b的實例,,其中a個實例是需要求解的,為了簡化分析,,我們假設(shè)n是b的冪(每次都可以整的劃分),,對算法的運(yùn)行時間,下面的遞推關(guān)系式是顯然的:



其中,,a,,b的含義已經(jīng)說過了,f(n)表示將求解得到的a個子問題的解合并起來所需要的時間復(fù)雜度,。

如何根據(jù)a,,b以及f的階來確定這個算法的時間復(fù)雜度呢?有下列主定理:(證明參見算法導(dǎo)論)




看起來似乎是有一點(diǎn)復(fù)雜,,證明又比較復(fù)雜,,這樣的式子又不好記??吹竭@個我也覺得茫然,。好吧,根據(jù)自己的理解,,我來做一點(diǎn)解析,,挖掘一下這個式子:

1)b,a,,f(n)的含義,,這個要弄清楚,,要不然恐怕你是無法記住這個結(jié)論的。

2)這個式子是一個通用的數(shù)學(xué)表達(dá)式,,在計算機(jī)的常用算法策略中,,它太概括了,我們往往用到的只是它范圍很小的一部分,。

分析1:a和b的關(guān)系,,其實a絕大多數(shù)時候都是等于b的吧(因為規(guī)模n劃分為了b個子規(guī)模,需要處理的是a個,,參見a,,b的含義),a,,b的含義告訴我們a <= b(當(dāng)這是最基本要滿足的條件),。常常要么是 a==b(分成的子規(guī)模都要處理,然后去合并),,要么是a==1(實際上這是減治的思想,,分成了b個子規(guī)模,但最終卻可以排除其他的,,只在其中一個子規(guī)模中去處理),。一般來說就是這樣,所以a,,b并不是隨意的,。


分析2:其實b要么為2(幾乎所有情況)要么為3(極少數(shù)情況)吧,這個分治思想里面就說啦,,一般來說都是分為2個規(guī)模相等的子規(guī)模(當(dāng)然誰都想分的越多越好,,這樣算法就更快,但是現(xiàn)實是問題往往沒有那么高效的算法,,找到一個3的分治就已經(jīng)很不錯了)


分析3:由上面2條可知,,a,b的值幾乎就那么幾個(當(dāng)然我說的是幾乎所有書上可以看到的常見算法案例),,所以不用那么擔(dān)心,。


分析4:f(n)是線性的的情況很多(即d=1的情況是最多的)。再來看看a和b^d比較大小的關(guān)系說明了什么f(n)代表的是合并的復(fù)雜度,,1<=a <= b,定性的分析,,可以知道:

第一種情況:a < b^d

因為1<=a <= b,所以只要d>1,不管a,b是什么(不管怎么劃分規(guī)模,,也不關(guān)需要處理幾個規(guī)模),,總是第一種情況,時間復(fù)雜度是n^d,。
如果d=1呢,,只要a < b(處理的比劃分的少),,那么還是第一種情況,時間復(fù)雜度也是n^d = n

第二種情況:a =  b^d

因為1<=a <= b,所以如果a=b(劃分多少處理多少),那么d只能為1才能是這種情況,。-----常見的歸并排序都是這樣
而如果a < b,那b就只能<1才能是這種情況,,一般很少見。

第三種情況:a  >  b^d

非常少見,,我還木有見過這樣的算法,,一開始我認(rèn)為這種情況不可能,但在理論上它是存在的,。因為1<=a <= b,所以要滿足這個式子d必須<1 ,。

從這也可以看出這三個參數(shù)之間的關(guān)系,事實上是劃分的復(fù)雜度和合并的復(fù)雜度在爭搶復(fù)雜度的控制權(quán),。



說了這么多,,感覺越分析越復(fù)雜了嗎,其實不是,,把這些分析想清楚,對遞推式的理解就更進(jìn)一步了,,有了上述分析,,其實下面幾個常見的遞推式就包含了大多數(shù)的算法:

T(n)  =   a * T(n/b)  +  f(n)的常見式子:


1)  T(n)  =  2 * T(n/2) + O(n)      時間復(fù)雜度n*log(n)

一般來說分治算法就是這樣,分成2個子規(guī)模的問題,,需要處理的也是2個,,對這兩個子規(guī)模合并又是線性的
a = b = 2,    d = 1;        a == b^d 由主定理得n*log(n)

只要a=b,d=1,就都是這個復(fù)雜度


2)  T(n)  =  T(n/2) + O(n)        時間復(fù)雜度為n,線性的

a = 1,,b = 2,,d=1(分為2個子規(guī)模,但只對一個子規(guī)模處理,,合并也是線性的)

a < b^d,      時間復(fù)雜度是n^d = n

其實質(zhì)押a < b,d=1,都是這個,。


感覺對一個定理解讀了這么多,確實讓它變得更加復(fù)雜了,,但如果你做了上述思考,,相信對這個式子認(rèn)識也更加深刻了一點(diǎn)。當(dāng)然,,如果你覺得直接記住上面這個公式就可以了,,可以無視以上解讀。


----------------------------------------------------------------------------------------------------------------------------------------------------


4.1  合并排序

數(shù)據(jù)結(jié)構(gòu)里面寫過了,,再從分治實現(xiàn)策略的角度想一想:



合并排序遞歸的將規(guī)模n分為2個子規(guī)模,,對2個子規(guī)模分別排好序后(劃分并處理),再來合并這2個子規(guī)模為有序(合并解),。

其遞推關(guān)系式是這樣的:


合并解的過程是線性的,,即:



由主定理得,,時間復(fù)雜度是n * logn的。


幾道習(xí)題的思考:

7,,合并排序穩(wěn)定嗎,?yes

10,也可以不用遞歸的方法來實現(xiàn)合并排序,,合并排序是采用遞歸從上往下構(gòu)造,,我們也可以合并2個相鄰序列從底向上構(gòu)造。這樣就需要不斷地申請一個大的數(shù)組,,把當(dāng)前相鄰的2個部分合并起來,,直到整個合并。


--------------------------------------------------------------------------------------------------------------------------------------------------

4.2  快速排序

前面數(shù)據(jù)結(jié)構(gòu)里寫過了,,從分治實現(xiàn)策略的解讀來看看:

歸并排序是按照元素在數(shù)組里的位置來對它們進(jìn)行劃分的,,而快速排序是按照元素的值對它們進(jìn)行劃分。



遞推關(guān)系式:



根據(jù)主定理得知,,時間復(fù)雜度和歸并排序一樣,。

1)其關(guān)鍵在于尋找分裂位置!?。,。。?strong>2個指針左右掃描,,交換,。注意這種方法)

2)學(xué)會快排采用的分區(qū)這種思想。


幾道習(xí)題的思考:

3,,快排穩(wěn)定嗎,? ---- no

8,將一個亂序數(shù)組排成所有負(fù)數(shù)在正數(shù)之前,。-----借用快排2個指針左右掃描交換的思想,,線性時間內(nèi)完成

9,荷蘭國旗問題------分區(qū)思想

---------------------------------------------------------------------------------------------------------------------------------------------------


4.3  折半查找

前面數(shù)據(jù)結(jié)構(gòu)寫過了,,從分治策略的角度看看:

對有序數(shù)組采用折半查找:遞歸和非遞歸實現(xiàn)都比較簡單,。

分治的遞推式:



根據(jù)主定理,它的復(fù)雜度是logn,。

實際上分治算法一般是分成了幾個子規(guī)模就對這幾個子規(guī)模處理然后合并結(jié)果,,然而折半查找分成了2個子規(guī)模,每次卻總能排除一個子規(guī)模,,只對一個子規(guī)模進(jìn)行處理,,準(zhǔn)確的說,它是一種減治策略,?;蛘哒f可以把它看做是分治算法的退化,。


--------------------------------------------------------------------------------------------------------------------------------------------------


4.4  二叉樹遍歷及相關(guān)特性


  很多算法也在前面寫過了,還是從分治策略的角度再來看看它的一些特性:


  二叉樹的定義本身(參見一般的數(shù)據(jù)結(jié)構(gòu)書),,把一顆二叉樹遞歸的定義為了左右子樹構(gòu)成的樹,。這意味著,分治法是典型可以用于解決二叉樹相關(guān)問題的策略,。

  來看看可以做些什么:


  1)計算二叉樹的高度

  
  注意初始條件是判斷是否為空集返回一個 -1,,后面有一個習(xí)題說是否可以寫成返回0,然后else里面不加1,。這是不行的?。∵@樣沒有考慮單節(jié)點(diǎn)的情況,。

  它的遞推關(guān)系式:

  

  你能由這個遞歸關(guān)系給出它的時間復(fù)雜度嗎,?想想~

  事實上,可以簡化它為A(n)  =  2 *  A(n / 2) +  1  -------把左右的處理當(dāng)做一個數(shù)量級,,不會影響復(fù)雜度,,根據(jù)主定理,它是O(n)的,。

  來看看怎么證明它吧----》

  參見第  2)點(diǎn)


  2)應(yīng)當(dāng)指出,,加法并不是上述算法中執(zhí)行最多的次數(shù),每得到一個左子樹和右子樹,,才執(zhí)行一次加法(先求max,再執(zhí)行+1),,而比較次數(shù)(指檢查樹是否為空,,即if語句)顯然不止一次(要判斷根節(jié)點(diǎn)是否為空,還要判斷左右子樹是否為空),。

  這里引入內(nèi)部節(jié)點(diǎn)和外部結(jié)點(diǎn)的概念(定義略)來分析問題?。。,。?br>
  

  顯然對于每個內(nèi)部節(jié)點(diǎn)都要計算一次加法,,對于內(nèi)部節(jié)點(diǎn)和外部結(jié)點(diǎn),都要執(zhí)行一次比較(判斷是否為空),。

  可以證明,,有n個結(jié)點(diǎn)的二叉樹的外部結(jié)點(diǎn)個數(shù)為  x = n + 1;(如上圖,,用數(shù)學(xué)歸納法或者圖論相關(guān)知識都很好證明,,證明略)

  根據(jù)上述分析,對一個n個頂點(diǎn)的二叉樹求高度,,
  加法的操作次數(shù)為內(nèi)頂點(diǎn)個數(shù):n
  比較判斷是否為空的操作次數(shù)為內(nèi)部點(diǎn)加外部點(diǎn)的個數(shù):n + (n + 1) = 2n + 1,;

  無論怎么說,,該算法是線性的!


  3)其他一些如三種經(jīng)典的遍歷算法,,都可以遞歸的來定義,,這些都是數(shù)據(jù)結(jié)構(gòu)課程的標(biāo)準(zhǔn)組成部分,前面已寫,,不再詳述,。

  最后指出一點(diǎn),并不是所有的二叉樹算法都要遍歷左右子樹,,例如二叉查找樹的插入查找刪除只需要遍歷一棵(每次總能排除一棵),,這種策略應(yīng)該歸于減可變規(guī)模的策略(參見下一章減治策略)。


幾道習(xí)題的思考:

1)設(shè)計一個分治算法來計算二叉樹的層數(shù),。-----------遞歸的返回左右子樹層數(shù)較大值+1,,注意空樹和單節(jié)點(diǎn)時的情況


最后,擴(kuò)展一下本節(jié)最開始的計算二叉樹高度的算法:

一道騰訊面試題:怎么求二叉樹上最遠(yuǎn)的2個節(jié)點(diǎn)的距離,?-------左子樹高度+右子樹高度+2,,注意特殊情況(只有一邊右子樹)就行了。


--------------------------------------------------------------------------------------------------------------------------------------------------


總結(jié):

1)分治的思想:一般遞歸來實現(xiàn),,劃分子問題,,合并子問題的解。

2)主定理,,要很熟悉,,常見的遞推式應(yīng)該一眼判斷其復(fù)雜度。

3)合并排序,,快速排序,,折半查找,二叉遍歷樹相關(guān)特性,,這些都是數(shù)據(jù)結(jié)構(gòu)的經(jīng)典內(nèi)容,,之前也都寫過了,代碼參見前面的相關(guān)文章,。

這里再次復(fù)習(xí),,從不同的視角來看它們都是如何用用到了分治的策略。這些內(nèi)容應(yīng)當(dāng)非常熟練,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多