遞歸函數的定義:把一個直接調用自己或通過一系列的調用語句間接地調用自己的函數,稱做遞歸函數(遞歸函數必須有一個結束的條件,以免陷入無窮盡的遞歸中)。
迭代和遞歸的區別是:
(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;
}