说明:斐波那契数列基于栈的非递归实现,是为了用栈来实现数列,而不是为了降低时间或空间复杂度。
/**
* 递归或基于栈的方式实现斐波那契数列。
*
* @author <a href="mailto:electricalqzhang@gmail.com">Pioneer4</a>
* @since 2022/2/10 22:00
*/
public class Fibonacci {
public static void main(String[] args) {
for (int i = 0; i < 6; i++) {
System.out.println(fib(i));
}
System.out.println("*******");
for (int i = 0; i < 6; i++) {
System.out.println(fibWithStack(i));
}
System.out.println("*******");
for (int i = 0; i < 6; i++) {
System.out.println(fibWithStack1(i));
}
}
/**
* 基于递归实现。
*
* @param n
* @return
*/
public static int fib(int n) {
if(n == 0 || n == 1) { return 1; }
return fib(n-1) + fib(n-2);
}
/**
* 基于栈,用非递归方式实现 Fibonacci。
* 引入临时变量 sum 来保存结果。
*
* @param n
* @return
*/
public static int fibWithStack(int n) {
Stack<FibNode> stack = new Stack<>();
stack.push(new FibNode(n, Direction.DOWN));
int sum = 0;
do {
FibNode fNode = stack.pop();
if (fNode.dir == Direction.DOWN) {
if (fNode.value == 0 || fNode.value == 1) {
stack.push(new FibNode(1, Direction.UP));
continue;
}
stack.push(new FibNode(fNode.value-1, Direction.DOWN));
stack.push(new FibNode(fNode.value-2, Direction.DOWN));
} else {
sum = sum + fNode.value;
}
} while (stack.size() > 0);
return sum;
}
/**
* 基于栈,用非递归方式实现 Fibonacci。
* 无需引入临时变量 sum 来保存结果,结果存在栈中。
*
* @param n
* @return
*/
public static int fibWithStack1(int n) {
Stack<FibNode> stack = new Stack<>();
stack.push(new FibNode(n, Direction.DOWN));
do {
FibNode fNode = stack.pop();
if (fNode.dir == Direction.DOWN) {
if (fNode.value == 0 || fNode.value == 1) {
stack.push(new FibNode(1, Direction.UP));
continue;
}
stack.push(new FibNode(fNode.value-1, Direction.DOWN));
stack.push(new FibNode(fNode.value-2, Direction.DOWN));
} else {
FibNode fNodeSec = stack.pop();
// 如果第2个节点是 DOWN,则把第1个 UP 节点和第2个DOWN节点交换次序;
// 如果第2个节点为 UP,则把第1个 UP 节点和第2个 UP 节点相加,生成新的 UP 节点,并放入栈中;
if (fNodeSec.dir == Direction.DOWN) {
stack.push(new FibNode(fNode.value, Direction.UP));
stack.push(fNodeSec);
} else {
stack.push(new FibNode(fNode.value+fNodeSec.value, Direction.UP));
}
}
} while (stack.size() > 1);
return stack.pop().value;
}
static class FibNode {
// 数据
int value;
// 栈计算标识
Direction dir;
public FibNode(int value, Direction dir) {
this.value = value;
this.dir = dir;
}
}
enum Direction {
DOWN, UP;
}
}