遞歸算法——三行代碼的魅力

遞歸函數的運行過程類似於多個函數的嵌套調用,只是調用函數和被調用函數同一個函數的函數(類似於套娃)

在程序中可以看作:

  • 從主函數中先調用遞歸函數,進入第一層;
  • 在遞歸函數(第一層)中再調用遞歸函數,進入第二層;
  • 。。。。。。。;
  • 在遞歸函數(第n層)中再調用遞歸函數,進入第n+1層;

  • 當第n+1層有結果時,將結果再返回到第n層;

  • 然後一直再往下返回返回到第一層,結果返回到主函數中。

再比如生活中排隊的問題,當你不知道你前面排了幾個人的時候怎麼辦?

  1. 假設你是第n個人,那麼你問你前面排在第n-1位的人他是第幾個,當他還不知道時,他在問第(n-2)個,再問第(n-3)個。一個一個往前問。
  2. 一直問到某一個知道他排在第幾的人,比如問到了某個知道他是第10的位置,那麼他再把消息告訴第11個人,第11個人再告訴第12個人這樣一個一個再傳回來。這就是生活中一個類似遞歸地過程。

上面則第一個過程往前一個一個問的過程爲“遞”,一個一個傳回來的過程爲“歸”。

這個過程的代碼就可以寫爲

int find(int n){
      if(n==1)  return 1;
      return find(n-1) +1;
}

遞歸需要滿足的三個條件

  1. 一個複雜問題的問題可以分爲幾個子問題(上面自己再第幾個的問題變爲:前面的人在第幾排)
  2. 這個問題和子問題求解思路完全一樣(上面每個人的問題都是問前面的人在第幾排,思路一樣)
  3. 存在一個終止的條件(上面問題總有人知道自己是第幾排,若問題沒有終止方法,就變成無限循環了)

問題

假如此時有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");
}

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章