概念:只允许在表的前端(front)进行删除操作,在表的后端(rear)进行插入操作的一种特殊线性表
核心思想:先进先出
分类:1)循环队列:普通队列的首尾相接形成圆环,这样的队列称为循环队列(Circular Queue)
2)优先队列:普通队列的元素被赋予了优先级,具有最高优先级的元素最先删除,这样的队列称为优先队列(Priority Queue)
操作方法:1)enqueue() 入列,即元素插入队列
2)dequeue() 出列,即从队列删除元素
3)front() 查找队列头
4)isEmpty() 判断队列是否为空
5)size() 队列大小
应用场景:适用于多任务同步进行操作的场景,根据优先权选择优先级高的优先处理。
队列的理解:把队列比作是一个排队的过程,机场里检票登机的时候,谁先排队的谁就优先检票(先进先出),但是有某些人是VIP会员,可以走VIP通道会比大部分人都优先登机(优先队列)。
js实现一个队列类
class Queue{
constructor(){
this.arr = [] //一个队列
}
getQueue(){ //查询队列
return this.arr;
}
enqueue(element){ //入列
this.arr.push(element);
}
dequeue(){ //出列
return this.arr.shift();
}
front(){ //查看队列头
return this.arr[0]
}
isEmpty(){ //判断队列是否为空
return this.arr.length === 0;
}
size(){ //查询队列大小(即数组长度)
return this.arr.length;
}
}
循环队列类,破解击鼓传花的游戏
游戏介绍:一群人围城一圈,一朵花从某个人开始顺时针依次传递,第三次传递拿到花者出局,从下一位又重新开始,已旧是第三次传递拿到花者出局,游戏以这规则进行下去,直到只剩下一个人,即为最终胜利者。
解题分析:用一个数组代表一圈人,第一次传花把数组第一项拿出插入到数组尾,第二次传花(在第一次基础上)又把数组的第一项拿出插入到数组尾,第三次(在第二次基础上)删除第一项(出局),依次进行下去,直到数组只剩下一项。
class PassTheParcel{
winner(attendees){ //attendees是由参与者的名字组成的一个数组
let q = new Queue(); // 调用队列的操作方法
for(let item of attendees){
q.enqueue(item); //元素一个个入栈
}
while(q.size()>1){
for(let i=0; i<2; i++ ){ //第一次和第二次传花
q.enqueue(q.dequeue()); //拿出第一项插入尾部
}
q.dequeue(); //第三次出局
}
return '最终胜利者是 ' + q.getQueue();
}
}
优先队列,根据优先级插入队列
/* 辅助类,代表一个元素 */
class Item{
constructor(element,priority){
this.element = element; // 元素名称
this.priority = priority; // 优先级标识
}
}
/* 定义一个优先队列类 */
class PriorityQueue{
constructor(){
this.list = [] // 队列
}
enqueue(element,priority){
let item = new Item(element,priority); // 调用辅助类创建一个元素
let added = false;
for(let i=0,len=this.list.length; i<len; i++){
if(item.priority > this.list[i].priority){ // 与每一项做比较,若优先级比较高,则插入其前面,结束比较
this.list.splice(i,0,item);
added = true;
break;
}
}
if(!added){ // 比队列的所有项都小,则插入尾部
this.list.push(item);
}
}
getQueue(){ //查看队列
return this.list
}
}
更多数据结构相关,请查看专栏:《JavaScript数据结构与算法》
(完)