队列也是一种受限的线性结构,只允许在表的前端删除,在表的后端插入。
创建队列
虽然可以基于数组来创建队列,但是基于对象的队列效率更高,因为我们选择基于对象来创建队列。
队列需要一个lowetCount来跟踪现在最小的队列序号,且count不应该随着元素删除而减小,不然在插入元素时无法得知最后一个序号的大小。
class Queue {constructor() {this.item = {};this.count = 0;this.lowestCount = 1;}enqueue(ele) {this.count += 1;this.item[this.count] = ele;}dequeue() {if(this.isEmpty()) {return undefined;}const res = this.item[this.lowestCount];delete this.item[this.lowestCount];this.lowestCount += 1;return res;}peek() {if(this.isEmpty()) {return undefined;}return this.item[this.lowestCount];}isEmpty() {return this.size() === 0;}size() {return this.count + 1 - this.lowestCount;}toString() {if(this.isEmpty()) {return '';}let str = '';for(const k in this.item) {str = str?`${str},${this.item[k]}`:this.item[k];}return str;}}const queue = new Queue();console.log(queue.isEmpty()); // 输出truequeue.enqueue('John');queue.enqueue('Jack');console.log(queue.toString()); // John,Jackqueue.enqueue('Camila');console.log(queue.toString()); // John, Jack, Camilaconsole.log(queue.size()); // 输出3console.log(queue.isEmpty()); // 输出falsequeue.dequeue(); // 移除Johnqueue.dequeue(); // 移除Jackconsole.log(queue.toString()); // Camila
双端队列
前后均可添加或者删除。
操作方法,addFront(element)、addBack(element)、removeFront``()、removeBack()、peekFront()、peekBack()。
击鼓传花问题
核心是将队列的第一个人丢到队列末尾去。
function hotPotato(names, number) {const queue = new Queue();let outNames = [];names.forEach((item) => {queue.enqueue(item);});while (queue.size() > 1) {for (let i = 0; i < number; i++) {queue.enqueue(queue.dequeue());}outNames.push(queue.dequeue());}return {winner: queue.dequeue(),outNames: outNames,};}const names = ["John", "Jack", "Camila", "Ingrid", "Carl"];const result = hotPotato(names, 7);console.log(result);// { winner: 'John', outNames: [ 'Camila', 'Jack', 'Carl', 'Ingrid' ] }// 在我们的写法中,每次淘汰的是第八个人。
回文检查器
核心是使用双端队列,取出队列队首和队尾的值进行比较。
