队列

190 阅读3分钟

队列

1、认识队列

队列(Queue),是一种受限的线性表,先进先出(FIFO Fist In Fist Out),受限之处在于它只允许在表的前端(front)进行删除操作,在表的后端(rear)进行插入操作,通常,称进数据的一端为队尾,出数据的一端为队首,数据元素进队列的过程称为入队,出队列的过程称为出队

image.png

2、队列的应用

打印队列

又五份文档需要打印,这些文档会按照次序放入到打印队列中,打印机会依次从队列中取出文档,优先放入的文档,优先被取出,并且对该文档进行打印,依次类推,直到队列中不再有新的文档

线程队列

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

3、生活中的队列

比如一些要排队的时候,大部分就都是队列,如:核酸检测,去人多的厕所等。

4、队列类的创建

队列的实现和栈一样,有两种方案

一是使用数组实现

二是使用链表实现

这里使用数组来实现

队列的常见操作

队列的常见操作有

enqueue(ele) 向队列尾部添加一个(或多个)新的项

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

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

isEmpty() 如果队列中包含任何元素,返回true,否则返回false。

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

toString() 将队列中的内容,转为字符串形式

 // 封装一个队列
 function Queue() {
        this.items = []

        // 添加
        Queue.prototype.enqueue = function (ele) {
            this.items.push(ele)
        }
        // 删除
        Queue.prototype.dequeue = function () {
            return this.items.shift()
        }
        // 查
        Queue.prototype.front = function () {
            return this.items[0]
        }
        // 查看队列是否为空
        Queue.prototype.isEmpty = function () {
            return this.items.length == 0
        }
        // 查看队列中数据的个数
        Queue.prototype.size = function () {
            return this.items.length
        }
        // 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(1)
    queue.enqueue(2)
    queue.enqueue(3)
    // 删除
    queue.dequeue()
    console.log(queue);
    // 查
    console.log(queue.front())
    console.log(queue.isEmpty());
    console.log(queue.size());

5、面试题

5.1、击鼓传花

实现代码

 function Queue() {
        this.items = []

        // 添加
        Queue.prototype.enqueue = function (ele) {
            this.items.push(ele)
        }
        // 删除
        Queue.prototype.dequeue = function () {
            return this.items.shift()
        }
        // 查
        Queue.prototype.front = function () {
            return this.items[0]
        }
        // 查看队列是否为空
        Queue.prototype.isEmpty = function () {
            return this.items.length == 0
        }
        // 查看队列中数据的个数
        Queue.prototype.size = function () {
            return this.items.length
        }
        // toString方法
        Queue.prototype.toString = function () {
            let resultString = ''
            for (let i = 0; i < this.items.length; i++) {
                resultString += this.items[i] + ''
            }
            return resultString
        }

    }

    // 面试题: 击鼓传花
    function passGame(nameList, num) {
        // 1、新建队列
        var queue = new Queue()
        // 2、将所有人依次加入队列中
        for (var i = 0; i < nameList.length; i++) {
            queue.enqueue(nameList[i])
        }

        // 3、开始数数
        while (queue.size() > 1) {
            // 不是nam的时候,重新加入到队列的末尾
            // 是num这个数字的时候,将其从队列中删除
            // 3.1 num数字之前的人重新放入队列的末尾
            for (var i = 0; i < num - 1; i++) {
                queue.enqueue(queue.dequeue())
            }
            // 3.2 num对应的这个人,直接从队列中删除掉
            queue.dequeue()
        }

        // 获取剩下的人
        console.log(queue.size());
        // 获取最后剩下的人
        var endName = queue.front()
        console.log('最后剩下的人是:' + endName);
        // 把最后剩的人的下标返回出去
        return '他在原数组的下标为' + nameList.indexOf(endName)
    }

    // 测试
    names = ['张三', "李四", "王五", "赵六"]
    console.log(passGame(names, 2))