1.队列结构
队列(Queue)结构是一种受限的线性表,先进先出(FIFO First In First Out)
- 受限之处在于,它只允许在表的前端(front)进行删除操作
- 在表的后端(rear)进行插入操作
2.生活中类似的队列结构
- 电影院,商场排队,游乐场排队买票
- 打印机打印文件
3.队列的应用
打印队列:
- 有五份文档需要打印,这些文档会按照次序放入到打印队列中
- 打印机会一次从队列中取出文档,优先放入的文档,优先被取出,并且对该文档进行打印
- 依此类推,知道文档中不再有新的文档
线程队列:
- 在开发中,为了让人物并行处理,通常会开启多个线程
- 但是我们不能让大量的线程同时运行处理任务(占用过多的资源)
- 这个时候,如果需要开启线程处理任务的情况,我们就会使用线程队列
- 线程队列会按照次序来启动线程
4.队列的常见操作
- enqueue(element):向队列尾部添加一个(或多个)新的元素
- dequeue():移除队列的第一个元素,最前面的项,并返回被移除的元素
- front():返回队列中的第一个元素,队列不做任何变动。
- isEmpty():如果队列中不包含任何元素,返回true,否则返回false
- size():返回队列包含的元素个数,与数组的length属性类似
- toString():将队列中的元素内容,转成字符串形式
5.队列类的创建
队列的实现和栈一样,有两种方案
- 基于数组实现
- 基于链表实现
//封装队列类
function Queue(){
//属性
this.items = [];
//方法
//1.将元素加入到队列中
Queue.prototype.enqueue = function(element){
this.items.push(element);
}
//2.从队列中删除前端元素
Queue.prototype.dequeue = function(){
this.items.shift()
}
//3.查看前端的元素
Queue.prototype.front = function(){
return this.items[0];
}
//4.查看队列是否为空
Queue.prototype.isEmpty = function(){
return this.items.length == 0;
}
//5.查看队列中元素的个数
Queue.prototype.size = function(){
return this.items.length;
}
//6.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.enqueue(4);
queue.enqueue(5);
console.log(queue);
//从前端删除元素
queue.dequeue();
queue.dequeue();
console.log(queue);
//查看前端的元素
console.log(queue.front());
//查看队列是否为空
console.log(queue.isEmpty());
//查看队列元素的个数
console.log(queue.size());
//队列的toString方法
console.log(queue.toString());
6.队列提醒讲解–击鼓传花
-
击鼓传花: 一人敲鼓,剩下的人围成一圈,开始传花,当鼓声停了,花在谁手上,谁表演节目,完了继续执行
-
新规则: 一群人围成一圈数数,数到某个数字的人被淘汰,最终留下的人胜利,算出来最后剩下的人是原来在那个位置上的人
-
参数:所有参与者的姓名,基于的数字
-
结果:最终剩下的一个人的姓名
-
代码实现的思想:(加入数字为5)
依次将学生添加进队列,第一个数1添加到队列尾部,第二个数2添加到队列尾部,依次到第五个数5被淘汰,然后循环执行当队列的size为1的时候就执行完成了,输出。 -
击鼓传花代码实现
//击鼓传花
function passGame(nameList,number){
//1.创建一个队列结构
let queue = new Queue();
//2.将所有人依次加入队列
for(let i= 0; i< nameList.length; i++){
queue.enqueue(nameList[i]);
}
//开始数数字,不是number的话就加入到队列的末尾
//如果是number的数字的话从队列删除掉
//这个里面的所有人从队列前端删除掉,然后添加到队列的后面
//3.number数字之前的人重新放入到队列的尾部
while(queue.size() > 1){
for(var i = 0; i < number - 1; i++){
queue.enqueue(queue.dequeue());
}
//3.2number数字对应的人直接删除
queue.dequeue();
}
//相当于每次将前四个一次删除并且插入到队列的末尾,然后将第五个真正删除
//4.获取剩下的那个人
let finalName = queue.front();
let nameIndex = nameList.indexOf(finalName);
return [finalName,nameIndex]
}
let nameList = ['小王','张三','李四','王五','赵六','钱七','周八','五九'];
let number = 5;
console.log(passGame(nameList,number));
//["李四", 2]
7.优先级队列
1.普通队列和优先级队列比较
-
普通队列:我们知道,普通的队列插入一个元素,数据会被放在后端,并且需要前面所有的元素都处理完成后才会处理插入的数据。
-
优先级队列,在插入一个元素的时候会考虑当前数据的优先级
-
和其他数据优先级进行比较
-
比较完成后,可以得出这个元素在队列中正确的位置
-
其他处理方式,和基本队列的处理方式一样
2.有限级队列主要考虑的问题
-
每个元素不再只是一个数据,而且包含数据的优先级
-
在添加方式中,根据优先级放入正确的位置
3.优先级队列的应用
- 登机顺序,头等舱,商务舱登机顺序高于经济舱乘客。
- 急诊科需要按照病人的病情排序候诊。
- 计算机中我们也可以通过重新排序队列中任务的顺序
- 比如某个线程处理的任务并不重要,我们可以通过优先级的大小,来决定该线程在队列中被处理的次序。
4.优先级队列(模拟根据数字排列,数字小的优先级高)
- 1.数据项既包含数据也包含数据优先级
- 2.插入方法: 当前队列没有元素的时候直接插入,当前队列有元素的时候,根据优先级插入
5.优先级队列的代码实现
//封装优先级队列
function PriorityQueue(){
//为了保存数据,再封装一个类,内部类
function QueueElement(element, priority){
this,element = element;
this.priority = priority;
}
//封装属性
this.items = [];
//1.实现插入方法
PriorityQueue.prototype.enqueue = function(element, priority){
//1.创建QueueElement对象
let queueElement = new QueueElement(element, priority);
//2.判断当前队列是否为空
if(this.items.length == 0){
this.items.push(queueElement);
} else{
let flag = false;
for(let i =0 ; i< this.items.length; i++){
if(queueElement.priority < this.items[i].priority){
this.items.splice(i,0,queueElement);
flag = true;
break;
}
}
if(!flag){
this.items.push(queueElement);
}
}
}
//2.从队列中删除前端元素
PriorityQueue.prototype.dequeue = function(){
return this.items.shift()
}
//3.查看前端的元素
PriorityQueue.prototype.front = function(){
return this.items[0];
}
//4.查看队列是否为空
PriorityQueue.prototype.isEmpty = function(){
return this.items.length == 0;
}
//5.查看队列中元素的个数
PriorityQueue.prototype.size = function(){
return this.items.length;
}
//6.toString方法
PriorityQueue.prototype.toString = function(){
let resultString = '';
for(let i = 0; i < this.items.length; i++){
resultString += this.items[i] + ',';
}
return resultString;
}
}
let pq = new PriorityQueue();
//1.插入元素
pq.enqueue('abc',1);
pq.enqueue('kjh',998);
pq.enqueue('hig',100);
pq.enqueue('def',10);
pq.enqueue('kjh',1000);
console.log(pq);
//2.删除元素
pq.dequeue();
//3....