zoukankan      html  css  js  c++  java
  • 数据结构与算法之栈结构

    认识栈结构

    • 栈也是一种非常常见的数据结构,并且在程序中的应用非常广泛
    • 数组:
      • 我们知道数组是一种线性结构,并且可以在数组的任意位置插入和删除数据
      • 但是,有些时候,我们为了实现一些功能,必须对这种任意性加以限制
      • 栈和队列就是比较常见的受限的线性结构,我们先来学习栈结构
    • 栈结构:只能栈顶进,也只能栈顶出
    • 插入新元素为入栈/压栈 ,删除元素出栈/退栈

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

    • 函数调用栈:A调用B ,B调用C,C又调用D
    • 那样在执行过程中,会先将A压入栈,A没有执行完,所以不会弹出栈
    • 在A执行过程中,调用了B,会将B压入到栈,这个时候B在栈顶,A在栈底
    • 以此类推
    • 栈底A->B->C->D栈顶,D执行完,弹出栈,C/B/D依此弹出
    • 所以我们有函数调用栈的称呼,就来自于他们内部的实现机制(通过栈来实现)
      • 递归:如果递归无限次一直调用,就会出现栈溢出的情况,不断压入同一个函数,他前面的函数并不能及时的释放

    栈结构面试题:

    有六个元素6,5,4,3,2,1的顺序进栈,问下列哪一个不是合法的出栈顺序?()
    A.543612     B.453216   c.346521   D.234156
    
    //答案:选c
    解析:A答案:65进栈,5出栈,4进栈出栈,3进栈出栈,6出栈,21进栈,1出栈,2出栈
    	 BC答案依此类推
         六个元素不一定是连续进栈,只是进栈的顺序要这个顺序。
    

    栈结构封装以及常见操作(这里以数组的方式模拟)

    • 实现栈结构有两种比较常见的方式:
      • 基于数组实现
      • 基于链表实现
    • 什么是链表?
      • 也是一种数据结构,目前我们还没有学习,并且js中并没有自带链表结构
      • 后续,我们会自己实现链表结构,并且对比数组和链表的区别
        // method:方法,和某一个对象实例有联系
        // function: 函数 
        // 封装栈类
        function Stack() {
          // 栈中的属性
          this.items = [20,10,100]
    
          // 栈的相关操作
          // 1.将元素压入到栈
          Stack.prototype.push = function(element){  //给栈类添加原型方法
            this.items.push(element)
          }
          // 2.从栈中取出元素(数组的最后一个元素)
          Stack.prototype.pop = function(){  //给栈类添加原型方法
            return  this.items.pop()
          }
          // 3.查看一下栈顶元素(pop取出会将元素删除,而这里peek只查看)
          Stack.prototype.peek = function(){  
            return  this.items[this.items.length-1]
          }
          // 4.判断栈是否为空
          Stack.prototype.isEmpty = function(){
            return this.items.length ==0
          }
          // 5.获取栈中元素的个数
          Stack.prototype.size = function(){
            return this.items.length
          }
          // 6.toString方法
          Stack.prototype.toString = function(){
            //20  10  12 8  7
            let resultString =''
            for(let i=0 ; i<this.items.length ; i++){
              resultString += this.items[i]+''
            }
            return resultString
          } 
        }
    
        //栈的使用
        var s = new Stack()
        s.push(77)
        console.log(s)
        
        s.pop()
        s.pop()
        console.log(s)
        
        console.log(s.peek())
        console.log(s.isEmpty())
        console.log(s.size())
    

    栈_十进制转二进制

    十进制与二进制如何算?
    	十进制数:100
    计算:100/2  余数0
    计算:50/2   余数0
    计算:25/2   余数1
    计算:12/2   余数0
    计算:6/2    余数0
    计算:3/2    余数1
    计算:1/2    余数1
    	所以从下往上结合:二进制数为1100100
    
    封装函数,将一个十进制转换成二进制:
    和栈有什么关系?因为:我们的余数相当于不断压栈,但是确实从最后的栈顶开始取数
    代码实现:
    // 十进制转二进制
        function dec2bin(decNum) {
          //1.定义栈对象  (这里使用我们上面封装好的Stack栈类)
          var stack = new Stack()
    
          //2.循环操作 (不确定次数的情况下最好用while循环)
          while (decNum > 0) {
            //2.1 获取余数,并且放入栈中
            stack.push(decNum % 2)
    
            //2.2 获取整除后的结果,作为下一次运行的数字
            decNum = Math.floor(decNum / 2)
          }
    
          //从栈中取出0和1
          var binaryString = ''
          while (!stack.isEmpty()) {  //判断是否栈空
            binaryString += stack.pop()  
          }
          return binaryString
        }
        console.log(dec2bin(100))
    
    
  • 相关阅读:
    SpringBoot配置Druid数据源
    springboot自定义异常处理
    SpringBoot配置详解
    设计模式 | 模板方法模式(template method)
    设计模式 | 原型模式(prototype)
    设计模式 | 工厂方法模式(factory method)
    设计模式 | 代理模式(proxy)
    设计模式 | 装饰模式(decorator)
    设计模式 | 策略模式(strategy)
    设计模式 | 简单工厂模式(static factory method)
  • 原文地址:https://www.cnblogs.com/JCDXH/p/11905961.html
Copyright © 2011-2022 走看看