1、认识队列
受限的线性数据结构
队列(Queue),它是一种受限的线性数据表,先进先出(FIFO: First In First Out)
受限之处在于,他只允许在表的前端(front)删除数据,在表的后端(rear)插入数据
生活中的类似队列结构场景:商场、影院排队(优先排队的人优先处理)
消息队列亦同:某一个线程检测到其所管理的某个异步任务触发,将回调函数包装成任务,加入到消息队列中排队(先进先出),等待渲染主线程调度。
2、队列的封装
//队列的封装和栈一样,有两种方式 1、基于数组 2、基于链表
/**
* 队列有哪些常见的操作呢?
* enqueue(element):向队列尾部添加一个(或多个)新的项。
* dequeue():移除队列的第一(即排在队列最前面的)项,并返回被移除的元素。
* front():返回队列中第一个元素——最先被添加,也将是最先被移除的元素。队列不做任何变动(不移除元素.只返回元素信息——与Stack类的peek方法非常类似)。
* isEmpty():如果队列中不包含任何元素,返回true,否则返回false。
* size():返回队列包含的元素个数,与数组的length属性类似。
* toString0:将队列中的内容,转成字符串形式
* */
class Queue{
constructor(){
this.items=[]
}
// enqueue(element):向队列尾部添加一个(或多个)新的项。
enqueue(...element){
this.items.push(...element)
}
// dequeue():移除队列的第一(即排在队列最前面的)项,并返回被移除的元素。
dequeue(){
return this.items.shift()
}
// front():返回队列中第一个元素——最先被添加,也将是最先被移除的元素。队列不做任何变动(不移除元素.只返回元素信息——与Stack类的peek方法非常类似)。
front(){
if(this.items.length===0)return null;
return this.items[0]
}
// isEmpty():如果队列中不包含任何元素,返回true,否则返回false。
isEmpty(){
return this.items.length===0
}
// size():返回队列包含的元素个数,与数组的length属性类似。
size(){
return this.items.length
}
// toString:将队列中的内容,转成字符串形式
toString(){
this.items=this.items.join('')
}
}
let queue=new Queue();
queue.enqueue('qwe','rty','uio','plm');
console.log(queue.items);//['qwe', 'rty', 'uio', 'plm']
queue.dequeue();
console.log(queue.items);//['rty', 'uio', 'plm']
console.log(queue.front());//rty
console.log(queue.isEmpty());//false
console.log(queue.size());//3
3、队列的应用【击鼓传花】--基于上面封装的队列
//击鼓传花【队列的应用】
function game(name,num){
let queue=new Queue();
queue.enqueue(...name);
while (queue.size()!==1) {
for (let i = 0; i <=num; i++) {
if (i === num) {
queue.dequeue();//每轮数到num数的这个人,将其淘汰
}
else {
queue.enqueue(queue.dequeue());//循环队列【从队头删除添加到队尾】
}
}
// queue.dequeue();//每轮数到num数的这个人,将其淘汰
}
return queue.front();
}
console.log(game(['小林','小明','小李','小张','小刘'],7))
4、优先级队列
优先级队列
在插入元素的时候会考虑优先级,和其他数据优先级进行比较,比较完成后可以得出这个元素在队列中的正确位置
生活中优先级队列的场景:机场登机顺序【头等舱和商务舱要高于经济舱】,医生一般会优先治疗病情较严重的病人,浏览器消息队列的优先级【微队列优先级最高】
class QueueElement{
constructor(element,priority) {
this.element=element;
this.priority=priority
}
}
class QueuePriority extends Queue{
enqueue(element,priority) {
// let elPriority=new QueueElement(element,priority);
let elPriority={
element,//k与v一致 ,简写
priority
}
if(this.isEmpty()){//不包含任何元素【刚开始】
this.items.push(elPriority);
}
else {
let status=true;//循环完还是为true,说明优先级最小,这个数最大
for(let i=0;i<this.items.length;i++){
if(this.items[i].priority>priority){
this.items.splice(i,0,elPriority);//会在下标i所对的元素前面添加
status=false;//标记这次有没有添加上
break;
}
}
if (status){
this.items.push(elPriority);//优先级最小【在后面】
}
}
}
}
let queuepriority=new QueuePriority();
queuepriority.enqueue('q',90)
queuepriority.enqueue('w',80)
queuepriority.enqueue('e',116)
queuepriority.enqueue('r',100)
console.log(queuepriority.items);
//[{element: 'w', priority: 80},
// {element: 'q', priority: 90},
// {element: 'r', priority: 100},
// {element: 'e', priority: 116}]
console.log(queuepriority.front());//80
console.log(queuepriority.size());//4