栈的初步认识

120 阅读3分钟

栈也是一种 非常常见 的数据结构,并且在程序中的 应用非常广泛

数组

  1. 我们知道数组是一种线性结构,并且可以在数组的 任意位置 插入和删除数据
  2. 但是有时候,我们为了实现某些功能,必须对这种任意性 加以 限制
  3. 而 栈和队列 就是比较常见的 受限的线性结构,我们先来学习栈结构
  • 栈结构示意图 image.png
  • 先入后出,后入先进

栈( stack ),它是一种受限的线性表,后进先出(LIFO)

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

生活中的例子

  • 自助餐的托盘,最新放上去的,最先被客人拿走使用
  • 收到很多的邮件(实体的),从上往下依次处理这些邮件.(最新到的邮件,最先处理
  • 注意:不允许改变邮件的次序,比如从最小开始,或者处于最紧急的邮件,否则就不再是栈结构了。而是队列或者 优先级队列结构.

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

  • 学了这么久的编程,是否听说过,函数调用栈呢?
  • 我们知道函数之间和相互调用: A调用B,B中又调用,C中又调用D
  • 那样在执行的过程中,会先将A压入栈,A没有执行完,所有不会弹出栈
  • 在A执行的过程中调用了B,会将B压入到栈,这个时候B在栈顶,A在栈底.
  • 如果这个时候B可以执行完,那么B会弹出栈.但是B有执行完吗? 没有它调用了C.
  • 所以C会压栈,并且在栈顶.而C调用了D,D会压入到栈顶.
  • 所以当前的栈顺序是: 栈顶A->B->C->D顶
  • D执行完, 弹出栈.C/B/A依次弹出栈
  • 所以我们有函数调用栈的称呼,就来自于它们内部的实现机制.(通过栈来实现的)

image.png image.png

练习题

问:有六个元素6,5,4,3,2,1 的顺序进栈,问下列哪一个不是合法的出栈序列?( )

  • A.543612
  • B.453216
  • C.346521
  • D.234156
  • 注意:顺序入栈,5进下一个就是4,4进下一个就是3,3进下一个就是2

栈的常见操作

  • push:添加一个新的元素到栈顶
  • pop:移除一个元素同时返回移除元素组
  • peek:查看栈顶元素
  • isEmpty:如果栈没有任何元素就返回true反之false
  • size:返回栈里的元素个数
  • toString:将栈结构的内容以字符形式返回
<script>
      //封装栈
    function Stack() {
        this.arr = []
        //栈的添加
        Stack.prototype.push = function (ele) {
            this.arr.push(ele)
        }
        //栈的删除pop
        Stack.prototype.pop = function () {
            return this.arr.pop()   //返会的就是最后一个元素
        }
        //栈的查询
        Stack.prototype.peek = function () {
            return this.arr[this.arr.length - 1]
        }
        //栈的判空
        Stack.prototype.isFlag = function () {
            return this.arr.length == 0
        }
        //获取栈的元素的个数
        Stack.prototype.size = function () {
            return this.arr.length
        }
        //toString()方法
        Stack.prototype.toString = function () {
            var objstring = ''
            for (let i = 0; i < this.arr.length; i++) {
                objstring += this.arr[i] + ' '
            }
            return objstring
        }
    }
    let a = new Stack()
    a.push(20)
    a.push(30)
    a.push(60)
    alert(a)   //添加  20 30 60
    a.pop()  //删除最后一个进入栈的元素
    alert(a)   //  20 30
    alert(a.peek())   //返回栈的长度  2
    alert(a.isFlag())  //返回true或false  栈里有元素返回false,栈里没有元素返回true  这里返回false
    alert(a.size())         //返回栈的长度 2   
    console.log(a.toString());   //返回  20 30 60
</script>