分治策略與遞迴

2021-06-25 11:57:37 字數 2243 閱讀 7441

先看《資料結構與演算法分析》中對分治策略的解釋:把問題分成兩個大致相等的子問題,然後再遞迴地對他們進行求解,這是「分」。「治」階段將兩個子問題的解合併到一起並可能再做些少量的附加工作,最後得到整個問題的解。

由定義可以看出,分治需要進行兩步操作:"分"-->將問題恰當的劃分為需要迭代處理的兩個子問題,「治」-->將兩個子問題合併。關鍵的操作有三點:

1、如何劃分?即以怎樣的準則對整體進行劃分

2、如何遞迴?即設計怎樣的遞迴方式

3、如何合併?即用怎樣的方式將整個問題還原

劃分的準則和整個問題的還原方法千千萬,應該具體問題具體分析,而遞迴是存在一些設計準則的:

1、基準情形。即遞迴的終止條件,其必須不依賴遞迴就能解出。

2、不斷推進。每一次遞迴都必須使得求解情況向基準情形靠近。

3、設計法則。假設所有的遞迴呼叫都能夠執行,即不會出現這次遞迴成功,而下次失敗(沒有達到基準情形)的情況。從頭至尾都是進行同樣的操作,並且都不會出錯。

4、合成效益法則。求解同乙個問題的同乙個例項時,不要在不同的遞迴呼叫中作重複性的工作。意即在當前遞迴中計算出的資料,不應當在下次遞迴中在進行相同的計算。

即使有了上述準則,對遞迴還是難以理解。具體表現為:原理感覺理解的很清楚,但是很難用**來實現。目前還沒有發現什麼好的解決方法,只能寄希望於通過大量的實踐操作來理解

下面是書上的乙個例子,感覺很不錯,拿過來分析一下:

要求:給定乙個整型數序列,求出它的最大子列和(子列是連續的)。

分析:求最大子列和,常規的方法就是用兩層迴圈,遍歷所有的子列組合,找出其中的最大值,這樣的方法的執行時間為o(n^2),效率有些偏低,用「分治」策略來解決會有更高的效率。

分治策略分析:最大子列存在三種情況,如下圖所示

以center為基準線,則最大子列和有三種情形:基準線的左邊基準線的右邊包含基準線。以此類推

,左右兩邊有可以劃分為更小的以這種方式劃分的序列,直到基準情形出現——只有乙個值(left==right=center),這樣就形成了乙個遞迴的形式。最後還需要有乙個對三者的比較操作,從而將問題合併,找出最大子列和。下面是c語言的實現函式**:

//「分治「策略求解問題【子問題運用遞迴解決】

int maxsubsequencesum_2(int a, int left, int right)

center = (left+right)/2;

maxleftsum = maxsubsequencesum_2(a, left, center);//【遞迴得到左邊的最大子列和】

maxrightsum = maxsubsequencesum_2(a, center+1, right);//【遞迴得到右邊的最大子列和】

maxleftbordersum = 0; //【下面計算包含中間值的最大子列和】

leftbordersum = 0; //【可以看出分成了三個部分,兩部分用來迭代】

for(i=center; i>=left; i--) //【遞迴確實很難理解,多思考吧】

maxrightbordersum = 0;

rightbordersum = 0;

for(i=center+1; i<=right; i++)

if(maxleftsum >= maxrightsum)

else

}

其實對這個程式,我還是有一些疑惑的,當debug的時候,編譯器對遞迴的處理操作有些難以讓人理解。尤其是兩行遞迴**(maxleftsum和maxrightsum**)的後面,緊跟的是計算從基準線開始向兩邊行進的最大子列和,那麼左右兩邊不包括基準線的最大子列和是如何實現的呢?debug發現遞迴的處理操作相較於迴圈的邏輯不是那麼的清晰,甚至看起來有些複雜,然而它的執行時間反而是o(nlogn),這應該說是我還沒有真正理解遞迴的思想,邏輯不夠清晰,下來要好好的琢磨。

遞迴與分治策略

1 全排列問題 設r n 是要進行排列的n個元素。集合x中元素的全排列記為perm x 求r n 的全排列perm r n 用遞迴演算法求解 1 找出遞迴子結構性質 即原問題的解包含了子問題的解,且子問題的描述與原問題相同。這就可以用子問題的解來構造原問題的解。設r i r n 這是乙個子問題。設 ...

遞迴與分治策略

1.遞迴 直接或間接地呼叫自身的演算法稱為遞迴演算法。用函式自身給出定義的函式稱為遞迴函式。1 階乘函式 include using namespace std int main int factorial int n 2 fibonacci數列 include using namespace st...

遞迴與分治策略

輸出最長公共子串 lcs 二維陣列veca記錄的是兩個字串xi和yj的lcs長度 int lcs length const string str1,const string str2,vector veca,vector vecb for j 0 j str2.length j for i 1 i ...