• 数据结构与算法之队列结构


    队列结构

    • 受限的线性结构
      • 之前我们总结了:栈结构
      • 并且已经知道这种受限的数据结构对于解决某些特定的问题,会有特别的效果
      • 这面文章,介绍了另外一个受限的数据结构:队列
    • 队列的结构:
      • 满足先进先出的一种结构
      • 受限之处:只允许在表的前端进行删除操作,表的后端进行插入操作
      • 抽象比喻:栈就是树立的杯子而队列就是横着的管道
    • 队列的应用:
      • 打印队列:这些文档会按照次序放入,优先的放入,优先的被取出
      • 线程队列:在开发中,为了让任务可以并行处理,通常会开启多个线程,但是我们不能让大量的线程同时运行处理(占用过多资源)。这个时候,如果有需要开启线程处理任务的话,就会使用线程队列,线程队列会依照次序来启动线程,并且处理任务

    队列类的创建和常见操作

    • 队列的实现和栈一样,有两种方案
      • 基于数组实现
      • 基于链表实现
     // 封装队列
        function Queue() {
          //属性
          this.items = []
    
          //方法
          // 1.将元素加入到队列中
          Queue.prototype.enqueue = function (element) {  
            this.items.push(element)
          }
          // 2.从队列中删除前端元素
          Queue.prototype.dequeue = function () {  
            return this.items.shift()
          }
          // 3.查看前端元素
          Queue.prototype.front = function () {
            return this.items[0]
          }
          // 4.判断队列是否为空
          Queue.prototype.isEmpty = function () {
            return this.items.length == 0
          }
          // 5.获取队列中元素的个数
          Queue.prototype.size = function () {
            return this.items.length
          }
          // 6.toString方法
          Queue.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 queue = new Queue()
    
        // 验证使用
        queue.enqueue('abc')
        queue.enqueue('cba')
        queue.enqueue('nba')
        queue.enqueue('mba')
        alert(queue)
        queue.dequeue()
        alert(queue)
        //....其他方法
    

    击鼓传花算法面试题

    击鼓传花规则

    • 几个朋友一起玩一个游戏,围城一圈开始数数数到某个数字的人自动淘汰
    • 最后剩下的这个人会获得胜利,请问最后剩下的是原来哪个位置上的人
    • 封装一个基于队列的函数:
      • 参数:所有参与人的姓名,基于的数字
      • 结果:最终剩下的一个人的姓名
    • 思路:将这几个人依此加入队列,然后将一个一个取出,每个取出的时候,就将其放入尾部,取出时,如果符合要求,就剔除

    代码实现

    //面试题,击鼓传花(使用了上面封装的队列类)
        function passGame(namelist, num) {
          //1.创建一个队列结构
          var queue = new Queue
          //2.所有人依此加入队列
          for (let i = 0; i < namelist.length; i++) {
            queue.enqueue(namelist[i])
          }
          //3.开始数数字
          while (queue.size() > 1) {
            //不是num的时候,重新加入到末尾,是num的时候,将其从队列中删除
            //3.1 num数字之前的人,依此放到末尾去
            for (let i = 0; i < num - 1; i++) {
              //先删除前端元素,再添加到尾部
              queue.enqueue(queue.dequeue())
            }
            //3.2 num对应的这个人,直接从队列中删除掉 
            //因为num对应的前面的人都放到后面去了,所以现在前端就是num对应的那个人
            queue.dequeue()
          }
            //获取最终剩下的那个人
            //获取最终剩下的那个人再原来的数组中是第一个位置
    
            var endName = queue.front()
            return (namelist.indexOf(endName)+1)+':'+endName
        }
         
        //测试击鼓传花
        names =['lili','lucy','tom','lilei','hy']
        console.log(passGame(names, 3))
    

    优先级队列

    • 优先级队列:再插入一个元素的时候会考虑该数据的优先级,而不是直接插入
    • 和其他数据优先级进行比较
    • 比较完成后,可以得出这个元素再队列中正确的位置
    • 其他处理方式,和基本队列的处理方式一样
    • 优先级队列主要考虑的问题:
      • 每个元素不再只是一个数据,而且还包含数据的优先级
      • 再添加方式中,根据优先级放入正确的位置
    • 优先级队列的应用:
      • 登机顺序:头等舱和商务舱的优先级顺序

    优先级队列的实现

    • 实现优先级队列相对队列主要有两仿麦呢的考虑:

      • 1.封装元素和优先级放在一起(可以封装一个新的构造函数)
      • 2.添加元素时,将新的插入元素的优先级和队列中已经存在的元素优先级进行比较,以获得自己正确的位置
    • 1.初步结构封装:

          //封装优先级队列
          function PrioritQueue(){
            //在封装一个类
            //类似java中的内部类,外部传入的两个数,但是内部对这两个数时有封装的
            function QueueElement(element,priorit){
              this.element = element
              this.priorit = priorit
            }
            //封装属性
            this.items = []
            
            //实现插入方法
            PrioritQueue.prototype.enqueue=function(element,priorit){
              //1.先创建QueueElement对象
              var queueElement = new QueueElement(element,priorit)
              	
            }
          }
      
    • 2.优先级队列数据结构实现:

       //封装优先级队列
          function PrioritQueue() {
            //在封装一个类
            //类似java中的内部类,外部传入的两个数,但是内部对这两个数时有封装的
            function QueueElement(element, priorit) {
              this.element = element
              this.priorit = priorit
            }
            //封装属性
            this.items = []
      
            //实现插入方法
            PrioritQueue.prototype.enqueue = function (element, priorit) {
              //先创建QueueElement对象
              var queueElement = new QueueElement(element, priorit)
      
              //判断队列是否为空
              if (this.items.length == 0) {
                //如果为空,则能直接插入
                this.items.push(queueElement)
              } else {
                let added = false
                for (let i = 0; i < this.items.length; i++) {
                  if (queueElement.priorit < this.items[i].priorit) {
                    this.items.splice(i, 0, queueElement)
                    added = true
                    break
                  }
                }
                if (!added) {
                  this.items.push(queueElement)
                }
              }
            }
            //(插以外,其他的操作与普通队列相同)
            // 2.从队列中删除前端元素
            PrioritQueue.prototype.dequeue = function () {
              return this.items.shift()
            }
            // 3.查看前端元素
            PrioritQueue.prototype.front = function () {
              return this.items[0]
            }
            // 4.判断队列是否为空
            PrioritQueue.prototype.isEmpty = function () {
              return this.items.length == 0
            }
            // 5.获取队列中元素的个数
            PrioritQueue.prototype.size = function () {
              return this.items.length
            }
            // 6.toString方法
            PrioritQueue.prototype.toString = function () {
              //20  10  12 8  7
              let resultString = ''
              for (let i = 0; i < this.items.length; i++) {
                resultString += this.items[i].element + '-' +this.items[i].priorit+ ' '
              }
              return resultString
            }
          }
          // 测试代码
          var pq = new PrioritQueue()
      
          //enqueue方法
          pq.enqueue('abc',111)
          pq.enqueue('cba',200)
          pq.enqueue('nba',50)
          pq.enqueue('nba',66)
          console.log(pq)
      
  • 相关阅读:
    qq划屏幕红包程序
    【图文教程】小米4如何获取触动精灵悬浮窗权限
    //6小时更新一次首页
    USBWebServer 中文便携版 快速搭建 PHP/MySQL 网站服务器环境
    【jquery】Validform,一款不错的 jquery 表单验证插件
    【html】关于锚点的一些事
    【css】关于 hr 在各浏览器中的问题
    【jquery】fancybox 是一款优秀的 jquery 弹出层展示插件
    【jquery】ajax 请求成功后新开窗口被拦截解决方法
    【html5】html5 本地存储
  • 原文地址:https://www.cnblogs.com/JCDXH/p/11908821.html
Copyright © 2020-2023  润新知