基于JavaScript语言简单描述一下计算机科学中的 队列(Queue)

304 阅读2分钟

什么是队列?

队列是一种特殊的线性表,遵循先进先出的规则(FIFO First In First Out),特殊之处在于它只允许在表的前端(front)进行移出(删除)操作,而在表的后端(rear)进行插入(添加)操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

image.png

通俗来讲队就是,像我们平时去超市买东西,在收银台结账的时候需要排队,先去排队的就先结账出去,排在后面的就后结账,有其他人再要过来结账,必须排在队尾不能在队中间插队。

在开发中,为了让任务可以并行处理,通常会 开启多个线程 但是,我们不能让大量的线程同时运行处理任务。(占用过多的资源) 这个时候,如果有需要开启线程处理任务的情况,我们就会使用 线程队列. 线程队列会依照次序启动线程,并且处理对应的任务

队列的常见操作

1. enqueue(element) : 向队列尾部添加一个( 或多个 )新的项

2. delqueue : 移除队列的第一( 即排在队列最前面的 )项,并返回被移除的元素

3. front: 返回队列中第一个元素一最先被添加,也将是最先被移除的元素。队列不做任何变动( 不移除元素只返回元素信息一与Stack类的peek方法非常类似)。

4. isEmpty : 如果队列中不包含任何元素,返回true,否则返回false。

5. size : 返回队列包含的元素个数,与数组的length属性类似。

6. toString0:将队列中的内容,转成字符串形式。

用JavaScript实现一个队列

function Queue() {
        //属性
        this.items = []

        //方法
        // 1.将元素加入到队列中
        Queue.prototype.enqueue = function (ele) {
            this.items.push(ele)
        }

        // 2.从队列中删除前端元素
        Queue.prototype.delqueue = 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 () {
            let resultString = ''
            for (let i = 0; i < this.items.length; i++) {
               resultString += this.items[i] + ' '
            }
            return resultString
        }

    }

    //使用队列
    let queue = new Queue()
    //将元素加入到队列中
    queue.enqueue('A')
    queue.enqueue('B')
    queue.enqueue('C')
    // alert(queue)

    //将元素移出出队列
    queue.delqueue()
    // alert(queue)

    //查看队列中前端元素
    alert(queue.front())

    //查看队列是否为空
    alert(queue.isEmpty())

    //查看队列中元素个数
    alert(queue.size())

    //toString方法
    alert(queue.toString())

典型面试题:击鼓传花

几个人围城一圈,规定一个数字,其他人数数,当数到某个数字的人自动淘汰,
最后剩下的这个人会获得胜利,请问最后剩下的是原来在那一个位置上的人

思路:利用队列做
从第一个人开始把所有人依次加入队列中
第一个人开始数数,没有数到规定数字的再依次加到队列的末尾
当数到规定的数字的时候,把那个人从队列最前面删除掉
然后继续数,继续往末尾添加
直到队列的长度为一的时候,就是最后获胜的人,求出它的下标值就可以

    //常见面试题:击鼓传花
    //nameList: 参与游戏的所有人
    //num: 指定淘汰的数字
    function passGame(nameList,num){
        //创建一个队列结构
        let queue = new Queue()

        //将所有人依次加入队列
        for(let i = 0; i < nameList.length; i++){
            queue.enqueue(nameList[i])
        }

        //使用while循环,满足条件跳出循环
        while(queue.size() > 1){
          // 开始数数,不是num的时候,重新加入到队列末尾
          // 是num进行删除
          // num数字出现之前删除掉的人重新放入队列的末尾,因为我们这个游戏要遵循先进先出原则
          for(let i = 0; i < num-1; i++){
            //循环num-1次
            queue.enqueue(queue.delqueue())
          }
          queue.delqueue()
        }

        let endName = queue.front()
        alert(queue.front())
        return nameList.indexOf(endName)

    }


    let nameList = [ 'A','B','C','D','E','F','G']
    let result =  passGame(nameList,5)
    alert(result)