1、遞歸簡述
遞歸作爲編程裏最爲重要的編程方法之一,其對於解決某些複雜的問題十分有效,並且相對於迭代,其過程在直觀上更容易理解。而且不像迭代自己需要維護許多變量,遞歸也更容易實現。
2、遞歸的基本思想
遞歸並不是簡單的自己調用自己,也不是簡單的交互調用。遞歸在於把問題分解成規模更小、具有與原來問題相同解法的問題,如二分查找以及求集合的子集問題。這些都是不斷的把問題規模變小,新問題與原問題有着相同的解法。但是並不是所有所有可以分解的子問題都能使用遞歸來求解。一般來說使用遞歸求解問題需要滿足以下的條件:
- 可以把要解決的問題轉化爲一個子問題,而這個子問題的解決方法仍與原來的解決方法相同,只是問題的規模變小了。
- 原問題可以通過子問題解決而組合解決。
- 存在一種簡單的情境,是問題在簡單情境下退出。
例如斐波拉契數列問題,一個數列滿足 1,1,2,3,5….. 的形式,即當前項爲前兩項之和的形式,那麼則稱這個數列爲斐波拉契數列。假設現在要求第 n 項數列的值。
則 f(n) 我們可以通過求的 f(n-1),f(n-2) 所得,原問題可以轉化爲兩個子問題,滿足條件一。
假設我們現在得到 f(n-1)、f(n-2)。f(n)=f(n-1)+f(n-2), 滿足條件二。
原問題可以通過子問題的解決而解決。而 f(1)=1,f(2)=1, 已知,即存在簡單情境使得遞歸退出,滿足條件三。所以此問題解法如下
int fib(n){
if(n==1)
return 1;
if(n==2)
return 1;
return fib(n-1)+fib(n-2);}
調用過程
通過上面的例子可以總結出遞歸問題的分析思路
- 分析問題看是否可以分解成子問題
- 子問題和原問題之間有何關係
- 是否有退出的簡單條件
在分析問題時我們可以採用自下而上,先分析簡單情況,然後看複雜情況是否可以由簡單情況組合形成,也可以自上而下,把複雜問題分解成子問題,在此過程中需要注意子問題是否有重疊。
3、經典的遞歸問題:
- 階乘問題
- 漢諾塔問題
- 斐波那契數列問題