1. 程式人生 > >java中遞迴演算法和漢諾塔

java中遞迴演算法和漢諾塔

java中,一個方法呼叫它自身,被稱為方法遞迴。方法遞迴中包含了一種隱藏式的迴圈。它會重複執行某段程式碼,而且不需要迴圈語句控制。

例如有如下數學題。已知一個數列:f(0) =1 、f(1)=4、f(n+2) =2*f(n+1) + f(n),其中n是大於0的整數,求f(10)的值。這題中函式中

帶有函式的計算,for迴圈不好寫程式碼,就可以使用遞迴方法來求。程式如下

上面方法fn體中,再次呼叫fn的方法,這就是方法的遞迴。

對於fn(10),即等於2*fn(9)+fn(8),其中fn(9)=2*fn(8)+fn(7),其中f(8)=2*fn(7)+f(6)······依次往裡面推導,最終會

計算到fn(2)等於2*fn(1)+f(0),而式中n=0和n=1就是遞迴的出口,這個式子可以算出來的,然後按計算的順序一步一步的返回,

最終會得到fn(10)的值。

對上面遞迴例子,當一個方法不斷的呼叫自身的時候,必須要在某個時候的返回值是確認的,而不是還在呼叫自身,否則遞迴成了死迴圈,

,沒有出口的迴圈。固設計遞迴的方法時,一定要設計好出口,像上式中if(n==0)返回的是個確認值。

在舉幾個經典事例:

A:斐波那契數列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...

如果設F(n)為該數列的第n項(n∈N*),求出第項的數:

F(n)=F(n-1)+F(n-2);(n>2)


方法的流程如下:


返回的順序是按呼叫方法的次序,並依次返回的。

B:求數的階乘。


C:求x的n次方(也可以呼叫math類的paw方法)


D:漢諾塔演算法:

古代有一個梵塔,塔內有三個座A、B、C,A座上有64個盤子,盤子大小不等,大的在下,小的在上。婆羅門的門徒想把這64個盤子從A座移到C座,但每次只能允許移動一個盤子,並且在移動過程中,3個座上的盤子始終保持大盤在下,小盤在上。在移動過程中可以利用B座。



漢諾塔中遞迴方法總體思想:

1. 先將A上面的n-1個盤子,移到B柱上

2. 然後把A上最大的一個盤子放到C上去(C相當於空)

3. 然後把B上面的n-1個盤子移到A上去

4.在吧B上的最大的盤中移動到C上去(C相當於空)。

以3階的漢諾塔為例子,執行上述方法

總:執行move(3,A,B,C)--

判斷條件3l==1?---執行else

執行move(3-1,A,C,B)---(將b,c柱子調換)--呼叫自身

判斷2==1?--執行else

執行move(2-1,A,B,C)--(將b,c柱子調換)--呼叫自身

判斷1==1?--執行if

輸出:從   A   移動盤中子  1  號到   C中,   【1】

level==1為遞迴出口,故返回到上一級;

繼續執行方法體中的語句--此時move中level是為2的,

System.out.println(從   A  移動盤子  2  號到  B)          【2】

執行move(2-1,2,1 ,,3 )--拿move(2,A,C,B)為 (1,C,A ,B)

判斷1==1?--執行if

輸出:從  C   移動盤子  1 號 到B;           【3】

返回到上一級

第一個遞迴方法呼叫完了,返回主方法體,繼續執行,此時level是為3的

Systrm.out.println(從 A  移動盤子  3號  到  C)--這裡的柱子還是(3,A,B,C)    【4】

執行move(3-1,2,1,3)--拿move(3,A,B  ,C)為move(2,B,A,C)

判斷2==1?--執行else

執行move(2-1,1,3,2)-拿move(2,B,A,C)為move(1,B,C,A)

判斷1==1?if

輸出:從 B 移動盤中 1號到  A                         【5】

level==1為遞迴出口,故返回上一級

執行方法體中的輸出,此時level為2,move(2,B ,A ,C)

System.out.println(從 B 移動盤子  2號 到 C)                             【6】

move(2-1,2 , 1 , 3)--拿move(2,B,A,C)為move(1,A,B,C)

判斷1==1?執行if

輸出:從A 移動盤中1號 到C                         【7】

返回到上一級

返回上一級;

方法全部執行完畢,結束方法。

要注意柱子的切換,每次執行方法都會變換。回到上一級就用同級的柱子順序。

總結:遞迴演算法來說,這個根就是那個出口,只要找到這個出口所在,那麼演算法自然而然就能水到渠成了。

可以先寫出前面幾種情況,推匯出公式和遞迴出口。