认识队列

85 阅读3分钟

受限的线性结构

1.其中一种栈结构,这种受限的数据结构对于解决某些特定问题,会有特别的效果.

队列

  1. 它是一种受限的线性表,先进先出(FIFO First In First Out)
  2. 受限之处在于它只允许在表的前端(front)进行删除操作
  3. 而在表的后端(rear)进行插入操作

举例

  • 打印队列:
    • 有五份文档需要打印,这些文档会按照次序放入到打印队列中
    • 打印机会依次从队列中取出文档,优先放入的文档,优先被取出,并且对该文档进行打印
    • 以此类推,直到队列中不再有新的文档.
  • 线程队列:
    • 在开发中,为了让任务可以并行处理,通常会开启多个线程口
    • 但是,我们不能让大量的线程同时运行处理任务.(占用过多的资源)
    • 这个时候,如果有需要开启线程处理任务的情况,我们就会使用线程队列
    • 线程队列会依照次序来启动线程,并且处理对应的任务

队列类的创建

  1. 队列的实现和栈一样,有两种方案:
    • 基于数组实现
    • 基于链表实现

队列的常见操作

  1. 队列有哪些常见的操作呢?
    • enqueue(element) : 向队列尾部添加一个( 或多个 )新的项。
    • dequeue(): 移除队列的第一( 即排在队列最前面的 )项,并返回被移除的元素.
    • front(): 返回队列中第一个元素一最先被添加,也将是最先被移除的元素。队列不做任何变动( 不移除元素只返回元素信息一与Stack类的peek方法非常类似 )。
    • isEmpty0 :如果队列中不包含任何元素,返回true,否则返回false。
    • size( : 返回队列包含的元素个数,与数组的length属性类似。
    • toString0:将队列中的内容, 转成字符串形式
<script>
    function Queue() {
        this.arr = []
        //将元素加入到队列中
        Stack.prototype.push = function (ele) {
            this.arr.push(ele)
        }
        //从队列中删除前端数据
        Stack.prototype.dequeue = function () {
            return this.arr.shift()   //返会的就是最后一个元素
        }
        //查看前端的元素
        Stack.prototype.front = function () {
            return this.arr[0]
        }
        //查看队列是否为空
        Stack.prototype.isEmpty = 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 Queue()
    a.enqueue('abc')
    a.enqueue('cbd')
    a.enqueue('nmf')
    alert(a)   //添加 
    a.dequeue()  //删除第一个进入栈的元素
   //front方法
   alert(a.front())
   //验证其他方法
   alert(a.isEmpty())
   alert(a.size())   
    
</script>

常见的击鼓传花面试题

  • 击鼓传花是一个常见的面试算法题.使用队列可以非常方便的实现最终的结果
  • 原游戏规则:
    • 班级中玩一个游戏,所有学生围成一圈,从某位同学手里开始向旁边的同学传一束花
    • 这个时候某个人(比如班长),在击鼓,鼓声停下的一颗,花落在谁手里,谁就出来表演节目
  • 修改游戏规则:
    • 我们来修改一下这个游戏规则
    • 几个朋友一起玩一个游戏,围成一圈,开始数数,数到某个数字的人自动淘汰
    • 最后剩下的这个人会获得胜利, 请问最后剩下的是原来在哪一个位置上的人?
  • 封装一个基于队列的函数
    • 参数: 所有参与人的姓名,基于的数字
    • 结果: 最终剩下的一人的姓名
//面试题:击鼓传花
    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对应这个人,直接从队列中删除掉
            queue.dequeue()
        }
        //4.获取剩下的那个人
        alert(queue.size())
        var endName = queue.front()
        alert('最终剩下的人:' + endName)
        return nameList.indexOf(endName)
    }
    //测试
    names=['ony','tom','why','lilel','lily']
    alert(passGame(names,3)