本文利用楊輝三角來具體說明一個遞歸的實現,實現的條件,如果理解不對的地方還請指教。
一、楊輝三角說明
楊輝三角是二項式系數在三角形中的一種集合排列。下面引用wiki上的動態圖來展示一下。
相信大家看了這張圖應該就能明白楊輝三角了吧。下面在代碼中講解遞歸。、
二、代碼講解
#include<iostream> using namespace std; #define max 10 /*下面定義的這個數組本來是要遞歸一遍直接記錄在數組里面的,而不用每求一個再去遞歸,但是這道題不大使用,因為在if條件里面有一個return, 如果改的話,就直接計算了,可以不用遞歸了,所以這里算是強行用一波遞歸吧嘿嘿嘿*/ int print[max][max] = { 0 }; int digui(int row, int col) { if (col == 0 || row == col) { print[row][col] = 1; return 1; } else { return digui(row - 1, col - 1) + digui(row - 1, col);//這個的值就是前面的兩個數相加得來 } } void main() { for (int _row = 0; _row < max; _row++) { for (int _col = 0; _col <= _row; _col++) { printf("%5d", digui(_row, _col)); } printf("\n"); } }
首先,如果做的聽的遞歸的題目多了之后,就會發現,遞歸要滿足兩個條件:
一是,要有使遞歸進行下去的變量,在這里就是row和col(行和列);
二是,要有終止遞歸的條件,在這里就是當row和col相等或者col==1的時候。
遞歸在經典的問題中用到很多,下面寫幾個問題的偽程序:
斐波那契數列
13世紀意大利數學家斐波那契的《算盤書》中記載了典型的兔子產仔問題,其大意如下:
如果一對一個月大的兔子以后每一個月都可以生一對小兔子,而一對新生的兔子出生兩個月才可以生出小兔子。也就是,1月份出生,3月份開始產仔。那么假定一年內沒有產生兔子死亡事件,那么1年之后共有多少對兔子呢?
int Febonaci(int n) { int t1, t2; if (n > 0) { if (n == 1 || n == 2) return 1; else { t1 = Febonaci(n-1); t2 = Febonaci(n-2); return t1 + t2;//規律是第n個月的兔子數等於前一個月和前兩個月的兔子數之和; } } else { return 0; } }
漢諾塔
題意:把a上的num個輪盤通過b移動到c上,這num個羅盤大小均不相同,規則是:大羅盤必須在小輪盤上面。
/*這里的num是羅盤的數量,a是羅盤最初在的桿,b是借用實現轉移的桿,c是羅盤最終要移動到的桿*/ hanota(num,a, b, c) { if (num == 1) move(1,a, c); else { hanota(num - 1, a, c, b);//把num-1個羅盤移動到b上 move(num, a, c);//把最大的羅盤移動到c上 hanota(num - 1, b, a, c);//把num-1個羅盤移動到c上
} }
三、最后
最后說一下,遞歸的實現過程吧,我簡單說一下,然后給出一個詳細說明的鏈接。
首先應該知道函數時保存在棧中的,當調用函數調用一個被調用函數的時候,就將這個被調用函數壓入棧中,並且保存這個函數的“狀態“(包括實參等)最后入棧的是調用函數的返回地址,當這個函數執行的時候,調用函數的自變量又被壓入棧中。當前面的被調用函數有調用函數的時候,就會繼續壓棧。所以遞歸不能無限執行,會溢出。當這個函數執行完的時候,就會被彈出棧,接着執行下一個函數,這里的如何找到下一個函數,是通過一個地址指針。