當前位置:外匯行情大全網 - 期貨行情 - 怎樣才能深刻理解遞歸和回溯?

怎樣才能深刻理解遞歸和回溯?

遞歸是壹種算法結構,回溯是壹種算法思想。壹種遞歸是在壹個函數中調用函數本身來解決問題,回溯是通過不同的嘗試來生成問題的解,這有點類似於窮舉,但與窮舉不同的是,回溯會“剪枝”,也就是不需要為錯誤的結果枚舉下壹個答案,比如1,2,3,4,5的有序序列。我選了1,然後選了2,然後發現選3的時候和大於預期,所以4和5肯定不行,這是對搜索過程的壹個優化。

回顧性分析是跟蹤決策的特點之壹。指對原有決策機制、決策內容、主客觀環境等的分析。從出發點、原因、問題性質、錯誤程度等。導致決策失誤的按順序進行調查。

【算法分析】

為了描述壹個問題的狀態,我們必須使用它以前的狀態,為了描述以前的狀態,我們也必須使用它以前的狀態...這種自己定義自己的方法叫做遞歸定義。例如,將函數f(n)定義為:

f(n)= n * f(n-1)(n & gt;0)

f(n)=1 (n=0)

那麽當0時,f(n)必須由f(n-1)定義,f(n-1-1)必須由f(n-1)定義...當n=0時,F (n) = 65438。

從上面的例子中,我們可以看到遞歸定義有兩個元素:

(1)遞歸邊界條件。也就是所描述的問題的最簡單的情況,它本身不再使用遞歸定義。

和上面的例子壹樣,當n=0時,f(n)=1,不用f(n-1)來定義。

(2)遞歸定義:將問題轉化為邊界條件的規則。遞歸定義必須讓問題越來越簡單。

比如f(n)由f(n-1)定義,它越來越接近f(0),也就是邊界條件。最簡單的情況是f(0)=1。

遞歸算法往往效率低下,耗時耗內存。不過遞歸也有它的好處,可以讓壹個有遞歸關系、結構復雜的程序簡介變得簡潔,增加可讀性。特別是在很難找到從邊界到解的全過程的情況下,如果將問題推得更遠,結果仍然保持原問題的關系,那麽用遞歸算法編程更合適。

遞歸分為:1。直接遞歸,遞歸過程P直接調用自己;2.間接遞歸,即P包含另壹個進程D,D調用P .

遞歸算法適用於如下壹般場合:

1.數據是遞歸定義的。

比如Peibonachi序列的定義:f(n)= f(n-1)+f(n-2);f(0)= 1;f(1)=2。

相應的遞歸程序是:

函數fib(n:整數) :整數;

開始

如果n = 0,則fib:= 1 {遞歸邊界}

否則,如果n = 1,則fib := 2

else fib:= fib(n-2)+fib(n-1){ recursive }

結束;

這類遞歸問題可以轉化為遞歸算法,用遞歸邊界作為遞歸邊界條件。

2.數據之間的關系(即數據結構)是遞歸定義的,如樹遍歷、圖搜索等。

3.問題用遞歸算法解決,如回溯法。

從問題的某種可能性出發,搜索從這種情況下可以達到的所有可能性,當這條路走到盡頭的時候。

回到起點,從另壹種可能出發,繼續搜索。這種不斷“回溯”尋找解決方案的方法被稱為

“回溯法”。

[參考程序]

下面給出壹個用回溯法求所有路徑的算法框架。筆記已經寫得很清楚了,請仔細理解。

const max depth =;

type statetype =;{狀態類型定義}

operator type =;{運算符類型定義}

Node =記錄{節點類型}

state:state type;{狀態字段}

operator:operator type {運算符字段}

結束;

{註:節點的數據類型可以根據試題需要進行簡化}

定義變量

堆棧:數組[1..max depth];{保存當前路徑}

合計:整數;{路徑數}

程序make(l:整數);

Var i:整數;

開始

如果堆棧[L-1]是目標節點,那麽。

開始

合計:=合計+1;{路徑數+1}

打印當前路徑[1..l-1];

出口

結束;

對於i := 1到解樹次數do

開始

生成堆棧[l]。操作員;

堆棧[l]。運算符作用於堆棧[l-1]。狀態以生成新的狀態堆棧[l]。狀態;

If stack[l]。狀態滿足約束條件則make(k+1);

{如果不滿足約束條件,將通過for循環更改運算符擴展。}

{遞歸返回那裏時,系統會自動恢復調用前的堆棧指針和操作符,然後通過for循環改變壹個操作符擴展。}

{註意:如果在擴展stack[l]時使用了全局變量。狀態,您應該插入幾個語句來恢復。

堆棧[l-1].狀態時的值。

結束;

{沒有更多可用的運算符,正在回溯}

結束;

開始

總計:= 0;{初始化為0的路徑數}

初始化處理;

make(l);

打印路徑總數

結束。

  • 上一篇:汕頭什麽銀行貸款最容易,手續不太復雜?
  • 下一篇:長盛中證100基金安全嗎
  • copyright 2024外匯行情大全網