遞歸函數的運行過程類似於多個函數的嵌套調用,只是調用函數和被調用函數同一個函數的函數(類似於套娃)
在程序中可以看作:
- 從主函數中先調用遞歸函數,進入第一層;
- 在遞歸函數(第一層)中再調用遞歸函數,進入第二層;
- 。。。。。。。;
- 在遞歸函數(第n層)中再調用遞歸函數,進入第n+1層;
當第n+1層有結果時,將結果再返回到第n層;
然後一直再往下返回返回到第一層,結果返回到主函數中。
再比如生活中排隊的問題,當你不知道你前面排了幾個人的時候怎麼辦?
- 假設你是第n個人,那麼你問你前面排在第n-1位的人他是第幾個,當他還不知道時,他在問第(n-2)個,再問第(n-3)個。一個一個往前問。
- 一直問到某一個知道他排在第幾的人,比如問到了某個知道他是第10的位置,那麼他再把消息告訴第11個人,第11個人再告訴第12個人這樣一個一個再傳回來。這就是生活中一個類似遞歸地過程。
上面則第一個過程往前一個一個問的過程爲“遞”,一個一個傳回來的過程爲“歸”。
這個過程的代碼就可以寫爲
int find(int n){
if(n==1) return 1;
return find(n-1) +1;
}
遞歸需要滿足的三個條件
- 一個複雜問題的問題可以分爲幾個子問題(上面自己再第幾個的問題變爲:前面的人在第幾排)
- 這個問題和子問題求解思路完全一樣(上面每個人的問題都是問前面的人在第幾排,思路一樣)
- 存在一個終止的條件(上面問題總有人知道自己是第幾排,若問題沒有終止方法,就變成無限循環了)
問題
假如此時有N階臺階,每一步可以走1步臺階或者2步臺階,求出走到第N階臺階的方法數。
方法:此時無論你處在那一階臺階上面,你可以走的只有兩種方法:1,走一步,2,走兩步
所以find(N)=find(N-1)+find(N-2);
再看終止條件,當在第二階臺階時,可以走1+1,或者2,有兩種方法;當在第一階臺階時,只能走1,這一種方法。
所以終止條件可以看作find(2)=2,find(1)=1;
如圖,每一階向下走的都兩種可能往下一步一步找(上圖的分叉),當碰到第一階和第二階時往上一步一步返回返回(即爲終止條件)。則上圖當5階時,方法即爲2+1+2+2+1=8種。
代碼
#include<iostream>
using namespace std;
int find(int n)
{
if (n == 1) return 1;
if (n == 2) return 2;
return find(n - 1) + find(n - 2);
}
int main()
{
int n;
cout << "樓梯階數爲:";
cin >> n;
int m=find(n);
cout << "有多少種情況:";
cout << m;
system("pause");
}