数据结构-栈

786 阅读3分钟

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

stack.png

(2)定义

  • 后进者先出,先进者后出,简称 后进先出(LIFO),这就是典型的栈结构。
  • 新添加的或待删除的元素都保存在栈的末尾,称作栈顶,另一端就叫栈底
  • 在栈里,新元素都靠近栈顶,旧元素都接近栈底。
  • 从栈的操作特性来看,是一种 操作受限的线性表,只允许在一端插入和删除数据。
  • 不包含任何元素的栈称为空栈。

(3)对比数组

  • 数组
    • 我们知道数组是一种线性结构,并且可以在数组的任意位置插入和删除数据
    • 但是有时候,我们为了实现某些功能,必须对这种任意性加以限制
    • 而栈和队列就是比较常见的受限的线性结构。

(4)特点:先进后出【重要】

  • 其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对的,把另一端称为栈底。
  • 向一个栈插入新元素又称为进栈、入栈或者压栈,他是把新元素放到栈顶元素的上面,使之称为新的栈顶元素。
  • 从一个栈删除元素又称为出栈或退栈,他是把栈顶元素删除掉,使其相邻的元素称为新的栈顶元素。

(5)栈的操作

  • push :入栈(因为栈的特点,是先进后出,所以相对于数组是尾加 即push)
  • pop:出栈(因为栈的特点,是先进后出,所以相对于数组是尾删 即pop)
  • peek: 返回栈顶元素,不对栈做任何修改
  • isEmpty:如果栈里没有任何元素就返回true,否则返回false
  • size:返回栈里的元素个数。这个方法和数组的length属性很类似
  • toString:将栈结构的内容以字符串的形式返回。
<script>
    //封装上述方法:
    function Stack(){
        this.items = []
        //入栈
        Stack.prototype.push = function(element){
            this.items.push(element)
        }
        //出栈
        Stack.prototype.pop = function(){
            return this.items.pop()
        }
        //peek查看栈顶元素
        Stack.prototype.peek = function(){
            return this.items[this.items.length-1]
        }
        //检查栈是否为空
        Stack.prototype.isEmpty = function(){
             return this.items.length == 0
        }
        //栈内元素个数
        Stack.prototype.size = function(){
             return this.items.length
        }
        //转为字符串
       Stack.prototype.toString = function(){
             return this.items.join('')
        }
    }
	
	
    // var stack = new Stack();
    // stack.push(1)
    // stack.push(2)
    // console.log(stack)
    
</script>    

(6)应用

  • 栈也被用在编程语言的编译器和内存中保存变量、方法调用等,比如函数的调用栈。
  • 在现实中:
    • 餐厅洗盘子,最先洗完的盘子,放在最底下,一摞一摞的摆放。
    • 批改作业,最后交的本子,放在最上面,最先交的,最后批改完(大多数操作)。

(7)练习题:

   一列字母,AB、C、D、E、F 顺序进栈,下列哪个是错误出栈()

    A:CDEFBA

    B:CDABEF

    C:BAFEDC

    D:EDFCBA

(8)面试题:将100转为2进制

    //步骤:
    100/2  = 50  ...0
    50/2  = 25   ...0
    25/2 = 12    ...1
    12/2 = 6     ...0
    6/2 = 3      ...0
    3/2 = 1      ...1
    1/2 = 0      ...1

    结果为:  1100100

具体实现:

    //方法:(需要结合上述封装的方法)
    <script>
        function trans2(num){
            var stack = new Stack();
            //循环
            while(num>0){
                //入栈
                stack.push(num%2)
                // 把整除的结果作为下一个被除数
                num =  Math.floor(num/2)
            }
            //出栈
            var resturnNum = ''
            //如果栈尾空,就结束出栈
            while(!stack.isEmpty()){
                resturnNum += stack.pop()

            }
          return resturnNum

       }

       console.log(trans2(100))   // 1100100
    </script>

上述练习题的答案是:B

解释: 栈的结构是先进后出的特点,也就是按照:第一个进栈,最后一个出栈的顺序。 B选项(CDABEF): 先进入ABC --> 出C --> 进D --> 出D --> 出B --> 出A (只能先出B然后才是A)--> 进E --> 出E --> 进F --> 出F