从应用场景看栈

在 JavaScript 中,数组就是一个最简单的栈了,在尾部操作的poppush也对应着出入栈的操作。so ?

栈只是种抽象概念,用链表 or 其它方式实现它均可。应用之解决问题正是它存在的原因

场景一:递归

从前山上有座庙,庙里有个老和尚和小和尚,老和尚给小和尚讲故事:“从前山上有座庙......”

有名的斐波那契数列,手动地计算相当困难,即便有计算器在手。而在编程语言中,使用递归可以很好地解决这个难题:

function F(n) {
  return F(n-1) + F(n-2);
}
复制代码

重点来了,计算机如何实现递归?这是一个很笼统的概念,因为等于这个加那个,那个再加这个...... 知其所以然而不知其然。应用栈的结构,我们可以把未知的结果推入栈内,在弹出的时候逐个计算。 如下图

代码解释:

function recursion() {
  // 调用栈
  const stack = [];

  // 解析时
  // 推入栈
  // 一般来说,栈有大小限制,如果自己写了个无限递归的函数,那调用栈一直增加,最后溢出
  for (let i = n; i > 0; i--) {
    stack.push(F(i));
  }

  // 执行时
  // 后入先出,弹出
  for (let i = 3; i <= n; i++) {
    F(n-2) = stack.pop();
    F(n-1) = stack.pop();

    F(n) = F(n-1) + F(n-2)
    
    // 计算完成后再推入栈内
    stack.push(F(n))
  }

  // 执行完成,栈内剩下最终结果,弹出并返回
  if (n) return stack.pop()
}
复制代码

场景二:四则运算

数学老师:“先乘除,后加减,有括号先算括号。”

分析下计算机四则运算的步骤:

  1. 定义运算符功能
  2. 优先级:乘除 >> 加减
  3. 有括号优先计算括号

示例:(1 + 2) x 3 - 4 ÷ 5

括号内优先计算,立马得出结果,咋一想还蛮符合队列的规则,先入先出嘛。但在有多个括号的情况下,优先计算最里面的括号,这样就只能推入栈中慢慢计算了。

但是怎么优雅地推入栈内计算,有个伟大的科学家解决了这个难题,波兰逻辑学家想到了一种不需要括号的后缀表达式,称之为逆波兰

示例后缀表达式:12+3*45/-

后缀表达式计算过程:

转化后的计算简直不要太简单,来看看又是如何利用栈来转的:

最后

直接从《大话数据结构》搬过来的砖。。。不过这本书真的比清华版数据结构易懂多了,正在啃的同学安利下

转载于:https://juejin.im/post/5c9dcee46fb9a070cf6be6e8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值