一.认识栈

栈(stack)

  • LIFO(last in first out)表示就是后进入的元素, 第一个弹出栈空间. 类似于自动餐托盘, 最后放上的托盘, 往往先把拿出去使用.
  • 其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。
  • 向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;
  • 从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

生活中类似于栈的结构的事情有很多,这里不一一列举,这里只举一个简单的栗子🌰:大家都吃过自助餐吧,自助餐的托盘就是一个栈结构,每次客人只能拿最顶上的盘子,而厨师只能往最顶上放餐盘,生动形象。

image.png

这张图完美的演绎了栈结构

程序中什么是使用栈实现的呢?

  1. 我们知道函数之间和相互调用: A调用B, B中又调用C, C中又调用D.
  2. 那样在执行的过程中, 会先将A压入栈, A没有执行完, 所有不会弹出栈.
  3. 在A执行的过程中调用了B, 会将B压入到栈, 这个时候B在栈顶, A在栈底.
  4. 如果这个时候B可以执行完, 那么B会弹出栈. 但是B有执行完吗? 没有, 它调用了C.
  5. 所以C会压栈, 并且在栈顶. 而C调用了D, D会压入到栈顶.
  6. 所以当前的栈顺序是: 栈顶A->B->C->D栈顶
  7. D执行完, 弹出栈. C/B/A依次弹出栈.

    二.栈结构实现(js版)

    我们先来创建一个栈的类, 用于封装栈相关的操作
  1. // 封住 栈 先进先出
  2. function Stack() {
  3. this.items = []
  4. // 方法
  5. // 1 添加一个新的元素
  6. Stack.prototype.push = (element) => {
  7. this.items.push(element)
  8. }
  9. // 2 从栈中取出元素
  10. Stack.prototype.pop = () => {
  11. return this.items.pop()
  12. }
  13. // 3 查看栈顶元素
  14. Stack.prototype.peek = () => {
  15. return this.items[this.item.length - 1]
  16. }
  17. // 4 判断栈是否为空
  18. Stack.prototype.isEmpty = () => {
  19. return this.items.length === 0
  20. }
  21. // 5 查看栈的元素个数
  22. Stack.prototype.size = () => {
  23. return this.items.length
  24. }
  25. // 6 toString方法
  26. Stack.prototype.toString = () => {
  27. var resultString = ''
  28. for (let i = 0; i < this.items.length; i++) {
  29. resultString += this.items[i]
  30. }
  31. return resultString
  32. }
  33. }
  34. var stack = new Stack()

栈的操作

  • push(element): 添加一个新元素到栈顶位置.
  • pop():移除栈顶的元素,同时返回被移除的元素。
  • peek():返回栈顶的元素,不对栈做任何修改(这个方法不会移除栈顶的元素,仅仅返回它)。
  • isEmpty():如果栈里没有任何元素就返回true,否则返回false
  • clear():移除栈里的所有元素。
  • size():返回栈里的元素个数。这个方法和数组的length属性很类似。