什么是堆栈
- 堆栈是一种特殊的线性表,它遵循后进先出(LIFO)原则,即后进入的元素先出。
- 就像是洗盘子,洗的放在最上,用的先拿最上的。
什么是斐波那契数列
- 斐波那契数列的前两个数是0和1,之后每个数都是前两个数的和。
- 除了f(0)=0, f(1)=1,其他数都是f(n)=f(n-1)+f(n-2)。
- 0~10的斐波那契数列:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 。
代码实现斐波那契
function fib(n) {
if (n <= 1) {
return n;
} else {
return fib(n - 1) + fib(n - 2)
}
}
为什么使用递归实现斐波那契
- 通常情况下,直接使用堆栈来实现斐波那契数列并不是最优选择,因为斐波那契数列的计算更适用于递归算法。
- 通过使用堆栈来模拟递归过程,同时计算大
n时避免了传统递归可能导致的栈溢出问题。
堆栈实现斐波那契
function fib(n) {
if (n < 0) throw new Error("输入正确的长度!!");
const stack = [{n, a: 0, b: 1}];
while (stack.length > 0) {
const {n: currentN, a, b} = stack.pop();
if (currentN === 0) {
return a;
} else {
stack.push({n: currentN - 2, a, b});
stack.push({n: currentN - 1, a: b, b: a + b});
}
}
}
为什么先压入(n-2)再压入(n-1)
- 为了保证计算顺序,按照斐波那契数列的定义,f(n)=f(n-1)+f(n-2),先压入f(n-2)因为他不依赖f(n),因为有初始值a和b,再压入f(n-1)(此时f(n-1)=b,f(n)=a+b)。
- 再每一次计算时,位置n再逐渐减小,而a替换为b,b再替换为a+b,逐渐累加的过程。
- 所以当位置起始为5时,
- 压入(n-2)此时n=3,a=0,b=1
- 压入(n-1)此时n=4,a=0,b=0+1
- 取出(n-1)此时n=4,a=0,b=1
- 压入(n-2)此时n=2,a=0,b=1
- 压入(n-1)此时n=3,a=1,b=0+1
- 取出(n-1)此时n=3,a=1,b=1
- 压入(n-2)此时n=1,a=1,b=1
- 压入(n-1)此时n=2,a=1,b=1+1
- 取出(n-1)此时n=2,a=1,b=2
- 压入(n-2)此时n=0,a=1,b=2
- 压入(n-1)此时n=1,a=2,b=1+2
- 取出(n-1)此时n=1,a=2,b=3
- 压入(n-2)此时n=-1,a=2,b=3
- 压入(n-1)此时n=0,a=3,b=2+3
- 取出(n-1)此时n=0,a=3,b=5
- 因为n==0,所以返回a=3,即f(5)=3。
- 如图所示
恐有疏漏,如有发现,敬请指正,十分感谢!