这一篇笔者要讲的是如何用栈来模拟递归,或者说替代递归的算法,现在我们假如要算从三角形数的叠加,比如输入10 ,输出是55,输入是100 ,输出是5050,等等。
首先,我们建一个栈:
public class StackX {
private int maxsize;
private Params[] stackActivity;
private int top;
public StackX(int s){ //对栈中的成员变量进行初始化
maxsize = s;
stackActivity = new Params[maxsize];
top = -1;
}
public void Push(Params a){ //入栈操作
stackActivity[++top] = a;
}
public Params Pop(){ //出栈操作
return stackActivity[top--];
}
public Params peek(){ //获取栈顶元素
return stackActivity[top];
}
}
栈的创建应该没什么大问题,主要是注意出入栈的时候顶部指针的变化就是了,然后我们还需要一个数据的包装类,只需要两个整型变量即可:
public class Params {
public int n ;
public int returnAddress;
public Params(int nn , int ra){
this.n = nn;
this.returnAddress = ra;
}
}
没啥好说的,然后是重点,如何进行模拟功能,先上代码吧,再一步步说明:
private static boolean step() {
switch (codePart) {
case 1:
theseParams = new Params(theNumber, 6);
theStackX.Push(theseParams);
codePart = 2;
break;
case 2:
theseParams = theStackX.peek();
if (theseParams.n == 1) {
theAnswer = 1;
codePart = 5;
}else {
codePart = 3;
}
break;
case 3:
Params newParams = new Params(theseParams.n - 1, 4);
theStackX.Push(newParams);
codePart = 2;
break;
case 4:
theseParams = theStackX.peek();
theAnswer = theAnswer + theseParams.n;
codePart = 5;
break;
case 5:
theseParams = theStackX.peek();
codePart = theseParams.returnAddress;
theStackX.Pop();
break;
case 6:
return true;
default:
break;
}
return false;
}
大家看着有点闷吧,整体来说就是将所给的元素压入栈中,再来一个个的出栈进行叠加,而叠加的结果会放在哪里呢,就是放在另一个内存空间,放在一个新的成员变量里面,我们举例说明比较好,比如我们传入一个整数5,第一次,case为2,则将数据5 与 标记 6 放入栈中,然后跳转到case为3,重复步骤case2,将所有的元素入栈后,就可以出栈了,而case2中的判断语句正是判断是否全部入栈(假设我们是从1开始加的),从而跳转到case5,在case5中执行出栈步骤,并且不断与case4循环,重复叠加,最后跳转出来。
这样说可能有点抽象,先给出全部代码,大家了解下为何要标识数:
public class StackTriangleApp {
static int theNumber;
static int theAnswer;
static StackX theStackX;
static int codePart;
static Params theseParams;
public static void main(String[] args) throws NumberFormatException, IOException {
System.out.print("Enter a number: ");
theNumber = getInt();
recTriangle();
System.out.println("Triangle= " + theAnswer);
}
private static void recTriangle() {
// TODO Auto-generated method stub
theStackX = new StackX(1000);
codePart = 1;
while (step() == false) {
;
}
}
private static boolean step() {
switch (codePart) {
case 1:
theseParams = new Params(theNumber, 6);
theStackX.Push(theseParams);
codePart = 2;
break;
case 2:
theseParams = theStackX.peek();
if (theseParams.n == 1) {
theAnswer = 1;
codePart = 5;
}else {
codePart = 3;
}
break;
case 3:
Params newParams = new Params(theseParams.n - 1, 4);
theStackX.Push(newParams);
codePart = 2;
break;
case 4:
theseParams = theStackX.peek();
theAnswer = theAnswer + theseParams.n;
codePart = 5;
break;
case 5:
theseParams = theStackX.peek();
codePart = theseParams.returnAddress;
theStackX.Pop();
break;
case 6:
return true;
default:
break;
}
return false;
}
private static int getInt() throws NumberFormatException, IOException {
int a = Integer.parseInt(getString());
return a;
}
private static String getString() throws IOException {
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader buf = new BufferedReader(inputStreamReader);
String str = buf.readLine();
return str;
}
}
笔者来画个图形象说明下这里面是如何出栈的吧:
画的有点丑,无妨了,大概就是这样,有什么疑问可以在评论说,笔者会参与讨论。