08 | 栈:如何实现浏览器的前进和后退功能?

712 阅读2分钟

如何理解“栈”?

  • 叠盘子\

    • 放:从下往上一个个的放\

    • 取:从上往下一个个的取

  • 栈特点

    • 后进先出,先进后出
    • 操作受限的线性表,数组和链表功能上完全可以代替栈 但是栈针对更特殊的场景,可以避免使用者的误用
  • 什么时候使用栈:在一端插入和删除数据,并且满足后进先出、先进后出的特性

\

如何实现一个“栈”?

  • 栈的操作:出栈和入栈

  • 栈的数据结构:数组(顺序栈) 链表(链式栈)  

    • 个人感觉链表更加适合栈 不需要移动大量元素,可以利用内存碎片,并且不需要支持随机访问
  • 时间复杂度:所有的操作时间复杂度都是o(1)

  • 实现动态扩容的顺序栈  

    • 使用 list 链表
    • 出栈时间复杂度是o(1)
    • 入栈时间复杂度最好o(1),最差是o(n) 使用均摊时间复杂度分析o(1) (1+1+1+1+1+....+n)/n=1

\

栈的应用

栈在函数调用中的应用

  • 操作系统给每个线程分配了一块独立的内存空间,用作存储函数的临时变量\

\

栈在表达式求值中的应用

  • 根据加减乘除进行四则运算(10以内)

  • 具体实现

    • 数据结构:两个栈,一个保存操作数,一个保存运算符

    • 从左开始遍历,遇到数压入操作数栈

    • 遇到运算符就与栈顶元素进行比较

      • 如果比运算符栈顶元素的优先级高,就将当前运算符压入栈
      • 如果比运算符栈顶元素的优先级低或者相同,从运算符栈中取栈顶运算符,并取出两个数,计算后压入栈顶

\

栈在括号匹配中的应用

  • 可以用于括号的匹配状态

  • 实现

    • 发现左括号压入栈
    • 发现右括号取出栈顶元素比较,相等继续,不相等则不匹配
    • 最后判断栈是否为空

浏览器中的应用

  • 实现

    • 用两个栈实现前进和后退
    • 首次访问页面压入栈x,点击后退出栈放入到y中  栈x为空则无后退
    • 点击前进从y中出栈 栈y为空则无前进

\

总结

  • 栈是一种操作受限的数据结构,只支持入栈和出栈操作\

  • 不管基于数组还是链表,入栈、出栈的时间复杂度都为 O(1)\

  • 动态栈在均摊时间复杂度后也是O(1)