Java——遞歸[第二次修訂版]

相信大家都聽過這麼一個故事:從前有座山,山上有座廟,廟裏有個老和尚在給一個小和尚講故事,故事是什麼呢?從前有座山,山上有座廟,廟裏有一個老和尚在給小和尚講故事,故事是什麼呢?從前有座山……

這個故事很長很長,有多長?這篇文章有多長就有多長。但是一整篇文章都在重複這個故事那這個博客還寫個啥玩意兒。所以不妨寫一個for循環?while循環或者do……while循環?但是循環到什麼時候截止呢?1024次?2048次?或者是4096次?好像都是無休止的進行下去的。

構成遞歸需具備的條件:

1. 子問題須與原始問題做同樣的事,且更爲簡單;

2. 不能無限制地調用本身,須有個出口,化簡爲非遞歸狀況處理。

對於第一點:子問題與原始問題做同樣的事。

舉例:6!

哦,就是這樣了。現在我們來仔細分析一下問題。求6!

數學上6!= 6 * 5 * 4 * 3 * 2 * 1 = 720;

程序上變成了這樣:

6 !

= 6 * get5()

= 6 * 5 * get4()

= 6 * 5 * 4 * get3()

=6 * 5 * 4 * 3 * get2()

=6 * 5 * 4 * 3 * 2 * get1()

= 6 * 5 * 4 * 3  * 2 *  1 

= 6 * 5 * 4 * 3  * 2

= 6 * 5 * 4 * 6

= 6 * 5 * 24

= 6 * 120

= 720

下面有兩種方式

1.最笨拙的方法如下

public static int get6() {
	return 6 * 5 * 4 * 3 * 2 * 1;
}
public static int get5() {
	return 5 * 4 * 3 * 2 * 1;
}
public static int get4() {
	return 4 * 3 * 2 * 1;
}
public static int get3() {
	return 3 * 2 * 1;
}
public static int get2() {
	return 2 * 1;
}
public static int get1() {
	return 1;
}

2.對上面方法的改進,但這是毫無意義的改進。但是我們需要從上往下來鋪墊思想。

public static int get6() {
	return 6 * get5();
}
public static int get5() {
	return 5 * get4();
}
public static int get4() {
	return 4 * get3();
}
public static int get3() {
	return 3 * get2();
}
public static int get2() {
	return 2 * get1();
}
public static int get1() {
	return 1;
}

這樣我們就會發現,方法每個方法都類似,除了最後的get1()方法直接返回了一個確定的值,其他都是不確定的,在棧中該方法是這樣的:

當執行到get1()時,該方法返回給get2方法一個1,然後彈棧,此時get2方法拿到get1()的返回值做計算之後,將得到的結果返回給get3(),以此下去……當方法get6()出棧之後,get6()方法將返回值返回給調用者,此時得到最終結果。

我們觀看每個方法的結構,每個方法都是返回一個數與另一個方法 的乘積,那此時就可以將其歸納爲一個方法。

public static int getFactorial(int x) {
	return x * getFactorial(x - 1);
}

但是,當執行到獲取1的階乘的時候卻返回的是一個確定的值,此時就需要在方法中作判斷操作,當傳進去的參數等於1時,返回確定的值。其他數值的時候皆返回自身與下一個數的階乘,例3:即return 3 * getFactorial(2)

public static int getFactorial(int x) {
	if (x == 1) {
		return 1;
	}else {
		return x * getFactorial(x - 1);
	}
}

以上就是對於java遞歸思想的簡單研究。

如果對上面的思想掌握了,可以看看下面這個題型。

該題型過於簡單,並且for循環這些是可以代替它的所以他不是典型的題型,且看另一個題型:

已知有一個數列:f(0) = 1,f(1) = 4,f(n + 2) = 2 * f(n + 1) + f(n),其中,n是大於0的整數,求f(10)的值。

那我們來分析一下題型:

f(10) = 2 * f(9) + f(8)

f(9) = 2 * f(8) + f(7)

f(8) = 2 * f(7) + f(6)

……

f(3) = 2 * f(2) + f(1)

f(2) = 2 * f(1) + f(0) 

f(2) = 2 * 4 + 1 = 9

f(3) = 2 * 9 + 4 = 22

f(4) = 2 * 22 + 9 = 53

……

f(10) = ?

當n = 0的時候返回1,當n = 1的時候返回4,……當n = 10 的時候返回,返回2 * f(9) + f(8)。

private static int getResult(int x) {
	if(x == 0) {
		return 1;
	}else if(x == 1) {
		return 4;
	}else{
		return 2 * getResult(x - 1) + getResult(x - 2);
	}
}

還有一個經典的題型,漢諾塔,歡迎大家研究研究,非常感謝。


好了,今天的博客就講到這兒,感謝大家的品讀。

大家好,我是輕言,我們下期,再會。


 

 

 

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