遞歸原理:大部分編譯器都是使用棧來實現遞歸的,當調用一個方法的時候編譯器會將參數和返回地址壓入棧中,然後把控制轉移給這個方法,當方法返回時,這些值退棧,參數小時。
下面是模擬的遞歸的過程:
package digui;
public class XiaoDigui{
static int theNumber;
static int theAnswer;
static StackX theStack;
static int codePart;
static Params theseParams;
public static void main(String[] args) {
theNumber = 3;
recTriangle();
System.out.println("Triangle = " + theAnswer);
}
/**
* 初始化信息
*/
public static void recTriangle(){
theStack = new StackX(10000);
codePart = 1;
while (step() == false){
;
}
}
public static boolean step(){
switch (codePart){
//初始的參數壓入棧中,返回地址爲步驟6.下一步爲步驟2
case 1:
theseParams = new Params(theNumber, 6);
theStack.push(theseParams);
codePart = 2;
break;
/**
* 判斷參數是否已經達到最小值1,如果達到則返回最小值並且跳轉步驟5,
* 反之則將參數N-1 以及返回位置4 壓入棧中。並且跳轉步驟3
*/
case 2:
theseParams = theStack.peek();
if (theseParams.n == 1){
theAnswer = 1;
codePart = 5;
}else{
codePart = 3;
}
break;
//將n-1的參數以及返回位置4壓入棧中,跳轉步驟2
case 3:
Params newParams = new Params(theseParams.n - 1, 4);
theStack.push(newParams);
codePart = 2;
break;
//將棧中的參數對象取出,將要獲取的值做疊加操作。跳轉步驟5
case 4:
theseParams = theStack.peek();
theAnswer = theAnswer + theseParams.n;
codePart = 5;
break;
//取出棧中首個參數對象賦予當前對象,然後銷燬取出的對象。跳轉步驟4
case 5:
theseParams = theStack.peek();
codePart = theseParams.returnAddress;
theStack.pop();
break;
//返回true 循環操作。
case 6:
return true;
}
return false;
}
}
/**
* 棧,用於存放參數對象的
*/
class StackX{
private int maxSize;
private Params[] stackArray;
private int top;
public StackX(int s){
maxSize = s;
stackArray = new Params[maxSize];
top = -1;
}
//入棧
public void push(Params p){
stackArray[++top] = p;
}
//銷燬對象
public Params pop(){
return stackArray[top--];
}
//取出參數對象
public Params peek(){
return stackArray[top];
}
}
/**
* 參數對象
*/
class Params {
public int n;
public int returnAddress;
public Params(int nn, int ra){
n = nn;
returnAddress = ra;
}
}