從前有座山,山上有座廟,廟裏有個老和尚,老和尚在給小和尚講故事,故事講的是從前有座山,山上有座廟,廟裏有個老和尚,老和尚在給小和尚講故事,故事講的是從前有座山,山上有座廟,廟裏有個老和尚,老和尚在給小和尚講故事,故事講的是從前有座山,山上有座廟,廟裏有個老和尚,老和尚在給小和尚講故事,故事講的是從前有座山,山上有座廟,廟裏有個老和尚,老和尚在給小和尚講故事,故事講的是......java
這個例子,若是用java程序來演示,會是這個樣子:編程
public class Hello { public static void main(String[] args) { sayStory(); } static void sayStory(){ System.out.println("從前有座山,山上有座廟,廟裏有個老和尚,老和尚在給小和尚講故事,故事講的是"); sayStory(); } }
程序運行結果:ide
故事在一直講下去。函數
看一下java代碼中,在方法sayStory()中又調用了sayStory()。code
遞歸,英文爲Recursion, 在計算機科學中,遞歸指得是在函數的定義中使用函數自身。
遞歸,包含了兩個意思:遞 和 歸。遞是隻傳遞下去,歸是指歸來,也就是說,遞歸有去也有回。
那麼,上面的講故事的程序,算遞歸程序嗎?
在方法sayStory()中又調用了sayStory(),符合遞歸的一個條件,即傳遞,可是,這個程序,沒有歸來,因此,程序會一直運行下去,直到資源耗盡,程序出錯:blog
所以,這不是個完整的遞歸程序。
遞歸要素
首先,遞歸必需要申明一個函數,且在函數中調用自身。
另外,遞歸要有明確的終止條件,遞歸就是有去有回,必然有一個明確的重點,到達這個終點後,就再也不往下遞,而是開始往回歸來。遞歸
遞歸的核心思想,就是把規模大的問題轉化爲規模小的類似的子問題來解決。在函數實現時,由於解決大問題的方法和解決小問題的方法每每是同一個方法,因此就產生了函數調用它自身的狀況,這也正是遞歸的定義所在。
考慮一下,遞歸的數學模型,很像數學概括法。數學概括法適用於將解決的原問題轉化爲解決它的子問題,而它的子問題又變成子問題的子問題。概括法解決數學問題通常分爲下面3個步驟:
1:步進表達式:問題演算成子問題的表達式
2:結束條件:何時能夠再也不使用步進表達式
3:求解表達式:在結束條件下可以直接計算返回值的表達式 資源
好比,斐波那契數列,使用數學概括法,3個步驟爲:
1: 推導出計算表達式: F(n)=F(n-1)+F(n-2) (n≥3)
2:結束條件:n=1,n=2時
3:求解表達式: F(1)=F(2)=1原型
明確了遞歸的數學模型後,咱們就要看,若是經過編程來實現遞歸。通常的,有兩種編程模型:數學
模型一: 先處理問題,而後再往下傳遞
遞歸函數(大規模){
if (end_condition){ // 遞歸終止條件 end; }else{ solve; // 處理問題 遞歸函數(小規模); // 分解問題規模,傳遞下去 } }
模型二: 在歸來的過程當中處理問題
遞歸函數(大規模){
if (end_condition){ // 遞歸終止條件 end; }else{ 遞歸函數(小規模); //分解問題規模,傳遞下去 solve; // 歸來,處理問題 } }
下面,演示一下,使用遞歸的編程模型,解決斐波那契數列問題。
首先,須要什麼一個函數,問題規模爲n,問題的結果爲一個整數。
則函數能夠聲明爲:int fib(int n)
而後,肯定終止條件: n=1,n=2時
3:求解表達式:
F(n)=F(n-1)+F(n-2) (n≥3)
F(1)=1,F(2)=1
則代碼以下:
階乘n!的數學定義: n!=1234…..(n-1)n,並規定 1!=1。
所以,2!=21=2(1!),3!=3(21)=3(2!),
4!=4(321)=4(3!)
5!=5(4321)=54!
根據規律,能夠推斷出: n!=n*(n-1)!,這就是階乘的遞歸公式。
而且能夠明確遞歸的終止條件n=1,終止時的值爲1。
下面,想一下,如何用java程序來實現呢?
遞歸函數原型,能夠什麼爲:int factorial(int n);
則函數的遞歸調用表達式爲: factorial(n)=n* factorial(n-1)
具體代碼以下:
public class Hello { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("請輸入n:"); int n = sc.nextInt(); int f = factorial(n); System.out.println("結果是:" + f); } static int factorial(int n) { if (n == 1) return 1; else return n * factorial(n - 1); } }
更多案例,請看下一章節。