初次接觸java中的遞歸算法。本站提示廣大學習愛好者:(初次接觸java中的遞歸算法)文章只能為提供參考,不一定能成為您想要的結果。以下是初次接觸java中的遞歸算法正文
一道關於兔子繁衍的編程題:
有一對兔子,從出生後第3個月起每個月都生一對兔子,小兔子長到第三個月後每個月又生一對兔子,假如兔子都不死,問每個月的兔子總數為多少?
自己考慮了挺久,思路出現了問題,甚至連其中的規律都沒有搞清楚.查看網上的一些算法之後,發現一個之前沒有使用的思想:遞歸.目前對於遞歸的理解僅限於初級中的初級.
關於這道編程題,應該以這樣的思路來進行考慮:
每個月的兔子的來源是哪些?答:上個月的兔子的個數(不管是否具備繁殖能力) + 2個月前的兔子的個數 在第1和2個月的時候,只有最開始的一對兔子.
這樣想一想的話,就是用上個月的兔子個數 + 上上個月的兔子個數 ,就可以得到本月的兔子的個數.結果恰好是很著名的斐波那契數列.
1 public static int method(int month){ 2 if(month == 1 || month == 2){ 3 return 1; 4 }else{ 5 int num = method(month -1) + method(month -2); 6 return num; 7 } 8 }
思想就是結果= 上次程序的結果 + 上上次的程序的結果
後在網上查看有關遞歸的資料,看到另外兩個用遞歸思想解決的問題:爬樓梯問題和漢諾塔問題
爬樓梯問題
假設一個樓梯有 N 階台階,人每次最多可以跨 M 階,求總共的爬樓梯方案數。
分析:
台階數(走法) 方法數
1 1 1
2 11 2 2
3 111 12 21 3
4 1111 112 121 211 225
因此可知,這個問題和之前的兔子繁衍問題是一個道理.
1 public static int f(int n) { 2 if (n == 0) { 3 return 0; 4 } else if (n == 1) { 5 return 1; 6 } else if (n == 2) { 7 return 2; 8 } else { 9 10 return f(n - 1) + f(n - 2); 11 } 12 }
漢諾塔問題:
從左到右 A B C 柱 大盤子在下, 小盤子在上, 借助B柱將所有盤子從A柱移動到C柱,大盤子只能在小盤子下面.
這些問題我想起來比較吃力,但網上解析很多,幾乎涵蓋了我的所有的考慮了,因此,我在這裡只說以下較為簡單快捷的一種理解方式.
A,B,C三個針,假設有n個盤子,只需要分成三步,①將(n-1)個盤子從A移動到B,②將最大的盤子從A放到C,③將(n-1)個盤子從B移動到C
f(n) = (f(n-1)*2) + 1;
public static int method(int n){ if(n == 1){ return 0; }else if(n == 2){ return 1; }else{ return method(n-1)*2 + 1; } }
再舉個例子,使用遞歸的思想來打印9*9乘法表
正常若不使用迭代的話,可以這樣來實現代碼,使用兩層嵌套的for循環
1 public static void method_1(){ 2 for(int i = 1;i <= 9;i++){ 3 for(int j = 1;j <= i;j++){ 4 System.out.print(i + "*" + j + "=" + i*j + " "); 5 } 6 System.out.println(); 7 } 8 }
若使用遞歸的話,問題就變成了:打印上一次的結果並打印新的一行
1 public static void method_2(int i){ 2 if (i == 1) { 3 System.out.println("1*1=1 "); 4 } else { 5 method_2(i - 1); 6 for (int j = 1; j <= i; j++) { 7 System.out.print(j + "*" + i + "=" + j * i + " "); 8 } 9 System.out.println(); 10 } 11 }
關於遞歸的應用,大體上來說,就是需要發現並找到程序中的遞歸的情況,將問題簡化.