Java資料結構-線性表之棧的應用-遞迴及其應用
阿新 • • 發佈:2019-01-25
遞迴函式的定義:把一個直接呼叫自己或通過一系列的呼叫語句間接地呼叫自己的函式,稱做遞迴函式(遞迴函式必須有一個結束的條件,以免陷入無窮盡的遞迴中)。
迭代和遞迴的區別是:
(1).迭代使用的是迴圈結構,遞迴使用的是選擇結構。
(2).遞迴能使程式的結構更清晰、更簡潔、更容易讓人理解,從而減少讀懂程式碼的時間。但是大量的遞迴呼叫會建立函式的副本,會耗費大量的時間和記憶體。
(3).迭代則不需要反覆呼叫函式和佔用額外的記憶體。因此我們應該視不同情況選擇不同的程式碼實現方式。
下面解釋一下怎麼使用棧實現遞迴:
在每次遞迴呼叫函式的時候,系統將函式的區域性變數、引數值以及返回地址等資訊壓入棧中。在呼叫結束後,位於棧頂的資訊(區域性變數、引數值以及返回地址)就會被彈出,系統繼續之前斷點後面的程式碼。
下面是棧的其他應用,比如:
漢諾塔問題
漢諾塔:
漢諾塔(又稱河內塔)問題是源於印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。
package example; public class Hanoi { /** * * @param n 盤子的數目 * @param origin 源座 * @param assist 輔助座 * @param destination 目的座 */ public void hanoi(int n, char origin, char assist, char destination) { if (n == 1) { move(origin, destination); } else { hanoi(n - 1, origin, destination, assist); move(origin, destination); hanoi(n - 1, assist, origin, destination); } } // Print the route of the movement private void move(char origin, char destination) { System.out.println("Direction:" + origin + "--->" + destination); } public static void main(String[] args) { Hanoi hanoi = new Hanoi(); hanoi.hanoi(6, 'A', 'B', 'C'); } }
n的階乘問題
問題看似很簡單,對於較小的數直接可以用簡單的乘法運算求出來,但是當需要求的n比較大的時候,這個時候計算機運算就會出現越界問題了,從而沒有辦法求出n的階乘。這裡最要的問題就是大數運算了,而對於這種問題採用陣列則可以很好的解決問題,如下是Java版的原始碼實現。
public static BigInteger factorial(int n){ int []a = new int[100]; int i,j; int p,h; //p儲存當前結果的位數,h為進位 a[0]=1; p=1; for(i=2;i<=n;i++) //迴圈與2,3,4.....n相乘 { for(j=0,h=0;j<p;j++) //讓a[]的每位與i相乘 { a[j]=a[j]*i+h; h=a[j]/10; a[j]=a[j]%10; } while(h>0) //如果h不為0 { a[j]=h%10; h=h/10; j++; } p=j; //將當前的位數賦給p } StringBuffer sb = new StringBuffer(); for(i=p-1;i>=0;i--) { sb.append(a[i]); } BigInteger bNum = new BigInteger(sb.toString()); return bNum; }