前端 数据结构 栈与队列

前端 数据结构 栈与队列

  • 栈是一个 后进先出 的数据结构

  • JavaScript 中没有栈这种数据结构,但是可以使用Array 实现栈的所有功能

  • 栈的常用操作

    • 入栈 push

    • 出栈 pop

    • 查看栈顶元素:stack[stack.length-1]

      // 声明一个栈
      const stack = [];
      
      // 入栈
      stack.push(1);
      stack.push(2);
      
      // 出栈
      const item1 = stack.pop();
      const item2 = stack.pop();
      
      //vscode  打断点 左侧查看运行stack 过程
      
  • leetCode 20题 有效的括号

    • 解题思路
      • 对于没有闭合的左括号而言,越靠后的左括号,对应得右括号越靠前。
      • 满足后进先出,考虑用栈。
    • 步骤
      • 新建一个栈
      • 遍历字符串,遇到左括号入栈,遇到和栈顶括号类型匹配的右括号就出栈,类型不匹配直接判定为不合法
      • 最后栈空了就合法,否则就不合法
    /**
    * @param { string }
    * @ return { boolean }
    **/
    var isValid = function(s) {
        if(s.length %2 === 1) {return false}
        const stack = [];
        for(let i=0,length = s.length; i<length; i++){
            let c = s[i]if(c==='(' || c==='{' || c==='['){
               stack.push(c);
            } else {
                const t = stack[stack.length-1];
                if( (t==='(' && c===')') ||
                    (t==='[' && c===']') ||
                    (t==='{' && c==='}') ){
                    stack.pop();
                }else {
                    return false;
                }
            }
        }
        return stack.length === 0
    }
    
  • 场景一:十进制转二进制

    • 比如:十进制数字35转二进制,35除2取余。
    • 后出来的余数反而要排在前面
    • 把余数依次入栈,然后再出栈,就可以实现余数倒序输出
  • 场景二:有效的括号

    • ()[]{}(()){} 字符串判断是否正确闭合
    • 越靠后的左括号,对应的右括号越靠前
    • 左括号入栈,右括号出栈,最后栈空了就是合法的。
  • 场景三: 函数调用堆栈

    • 最后调用的函数,是最先执行完的。

    • JS 解释器使用栈来控制函数的调用顺序

      function fun1(){
          fun2()
      }
      function fun2(){
          fun3()
      }
      function fun3(){
          console.log('33')
      }
      
      fun1()// 这里打断点  查看 callStack 进入函数内 看CALLSTACK 内元素的进栈出栈情况
      
      
      

队列

  • 一个先进先出的数据结构

  • JavaScript 中没有队列,单可以用 Array 实现队列的所有功能

    // 声明一个队列
    const queue =[];
    
    // 入队
    queue.push(1);
    queue.push(2);
    
    // 出队
    const item1 = queue.shift();
    const item2 = queue.shift();
    
  • 应用场景一:食堂打饭

  • 应用场景二:JS异步中的任务队列

    • JS 是单线程,无法同时处理异步中的并发任务。

    • 使用任务队列先后处理异步任务

      setTimeout( ()=>{
          console.log(1)
      },0);
      console.log(2);
      // 执行顺序是  1 2? 还是 2 1 
      

js 引擎会去js 任务队列取一个事件去执行

如果有异步操作,就丢给WebAPIs 去执行

WebAPIs 0ms执行完之后的回调函数又放在任务队列中,发现主任务还没有执行完
在这里插入图片描述

  • 应用场景三:计算最近请求次数 leetCode 993

    • 方法ping(int t),其中 t 表示以毫秒为单位的某个时间。返回从3000毫秒前到现在的ping 数。

    • 输入:inputs = [[],[1],[100],[3001],[3002]] 输出:[null,1,2,3,3]

    • 有请求就入队,3000ms 前发出的请求出队。

    • 队列的长度就是最近请求次数。

      var RecentCounter= function(){
          this.q = [];
      }
      RecentCounter.prototype.ping = function(t){
          this.q.push(t)
          while(this.q[0] < t-3000){
              this.q.shit()
          }
          return this.q.length
      }
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

公诚士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值