一、认识队列
- 受限的线性结构
栈是一种受限的线性结构,但是有些特定的问题,栈结构无法解决,所以就有了另一种受限的线性结构-队列。
- 队列(Queue):是一种受限的线性表,先进先出(FIFO first in first out)
受限之处:只允许在表的前端(front)进行删除,在表的后端(rear)进行插入。
二、生活中的例子以及程序中的应用场景
- 比如电影院,商场排队
- 优先队列:优先处理(医院急诊…)
-
三、队列的常用方法
enqueue(element):向队列尾部添加一个或多个元素(新的项)
- dequeue():移除队列的第一项,并返回移除的元素
- front():返回队列第一个元素,不对队列做任何操作
- isEmpty():判断队列是否为空
- size():返回队列长度
- 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}Queue.prototype.toString = function() {var str = ''for(var i = 0; i < this.items.length; i ++) {str += this.items[i] + ' '}return str}}var queue = new Queue()queue.enqueue('11')queue.enqueue('22')queue.enqueue('33')queue.enqueue('44')console.log(queue.items)
五、队列完成击鼓传花
游戏规则:班级中所有学生围成一圈,从某位同学开始向旁边的同学传一束花;这个时候有一个人(班长)来击鼓,鼓声停下的那一刻,花落在谁手里,谁就出来表演节目。
修改游戏规则:所有人围成一圈,进行数数,数到某个数的人自动淘汰,最后剩下的会获得胜利,请问最后剩下的是在原来哪一个位置上的人?思路:1、创建一个队列2、将人循环添加到队列中3、从0位置开始,循环num-1位置(这里num是传入的要数的数字,并不是数组的长度)4、循环不断将num之前的元素删除并重新添加到队列的末尾(不断向队列中添加删除的元素(队列中删除的都是一个元素))5、将num位置的元素直接删除6、直到删除到队列中还剩下一个元素的时候,停止删除 while循环7、获取当前队列的第一个元素8、通过indexOf方法在数组中查找到该元素function passGream(nameList, num) {// 1、创建一个队列var queue = new Queue()// 2、将name添加到队列中for (var i = 0; i < nameList.length; i ++) {queue.enqueue(nameList[i])}// 3、开始数数字while (queue.size() > 1) { // 当队列中的长度为1的时候,停止循环// 不是num的时候,重新加入队列的末尾// 是num这个数字的时候,将其从队列中删除// 3.1 num数字之前的人重新放到队列的末尾for (var j = 0; j < num - 1; j ++) {queue.enqueue(queue.dequeue()) // 从第0位置开始,不断循环到num(传入的数字)-1的位置,将不是num位置的删除后重新插入到队列的末端}console.log(queue.dequeue(), '=====')// num对应的这个人直接删除queue.dequeue()}// 4、获取剩下的那个人// console.log(queue.size())var endName = queue.front()// console.log('最终剩下的人:'+endName)return nameList.indexOf(endName)}// 测试击鼓传花var names = [1, 2, 3, 4, 5]console.log(passGream(names, 3), '====传花最后的人')
六、优先级队列
需要有一个优先级字段,用来进行比较function PriorityQueue() {// 封装内部类(函数)function QueueElement(element, priority) {this.element = elementthis.priority = priority}// 创建队列this.items = []// 实现插入方法PriorityQueue.prototype.enqueue = function (element, priority) {// 1、创建queueElement类var queueElement = new QueueElement(element, priority)// 2、判断队列是否为空if (this.items.length == 0) {// 如果为空,直接插入到队列中,不需要比较this.items.push(queueElement)} else { // 原数组中有元素,循环比较原数组var added = falsefor (var i = 0; i < this.items.length; i ++) {if (queueElement.priority < this.items[i].priority) {// 传入元素的优先级和队列中的优先级比较this.items.splice(1, 0, queueElement)added = truebreak}}if (!added) {this.items.push(queueElement)}}}PriorityQueue.prototype.dequeue = function() {return this.items.shift()}PriorityQueue.prototype.front = function() {return this.items[0]}PriorityQueue.prototype.isEmpty = function() {return this.items.length == 0}PriorityQueue.prototype.size = function() {return this.items.length}PriorityQueue.prototype.toString = function() {var str = ''for(var i = 0; i < this.items.length; i ++) {str += this.items[i].element + '-' + this.items[i].priority + ' '}return str}}var pq = new PriorityQueue()pq.enqueue('aa', 1)pq.enqueue('gf', 52)pq.enqueue('dd', 32)pq.enqueue('rr', 15)pq.enqueue('tt', 100)console.log(pq.items)console.log(pq.toString())
