一、什么是队列结构
前面一篇已经介绍了栈结构,我们对于栈结构已经有了很好的认识。栈结构的特点是'先进后出',而队列的特点正好相反是'先进先出'。
对于队列的实现,我们可以用数组或者是链表,接下来介绍一下数组的实现方法。话不多说,直接上代码。
class Queue {
constructor() {
this.queue = [];
}
// 进队列
enqueue(element) {
this.queue.unshift(element);
}
// 出队列
dequeue() {
this.queue.pop();
}
// 查看队列的大小
size() {
return this.queue.length;
}
// 查看队列是不是空的
isEmpty() {
return this.queue.length === 0;
}
// 返回队列第一个元素
front() {
return this.queue[this.queue.length - 1];
}
}
在看过上一篇[数组实现栈结构](js实现栈结构 - 掘金 (juejin.cn))后,用数组实现队列结构应该是很简单地。
让我们测试一下刚刚写的代码吧
// 实例化一个队列对象
const queue = new Queue();
// 往队列中添加元素
queue.enqueue(1);
queue.enqueue(2);
queue.enqueue(3);
queue.enqueue(4);
console.log(queue.size()); // 4
queue.dequeue();
console.log(queue.front()); // 2
console.log(queue.isEmpty()); // false
看来是没有什么bug。嘿嘿嘿。。。
接着,让我们来看一个非常金典的问题
二、 击鼓传花
简介, 有一群小朋友,围成一圈,席地而坐,从第一位小朋友开始传花,在指定几次鼓声后,手里有花的小朋友需要进行节目表演。表演完后,小朋友出圈,继续传花。求最后的小朋友是谁?
是不是很熟悉?这不就是约瑟夫环吗?如果用队列的方式,你会怎么实现。
思考实现方式
- 首先创建一个队列实例
- 往队列里放入元素
- 封装功能函数,传入队列和指定淘汰索引
- 循环遍历。定义一个count记录当前数值,当count不等于指定数字时,元素出队列,把出队列的元素再入队列。
- 当count等于指定数字时,出队列
- 当队列的长度为1时,停止循环,返回最后的元素
有了思考,我们可以落实到代码中。
function passGame(nameList, num) {
// 创建队列
const queue = new Queue();
// 数据入队列
for (let i = 0; i < nameList.length; i++) {
queue.enqueue(nameList[i]);
}
// 留下最后一人
while (queue.size() > 1) {
// 遍历到约定的num之前一位
for (let i = 0; i < num - 1; i++) {
// 把队列的头部重新入队列
queue.enqueue(queue.dequeue());
}
// 删除num元素
queue.dequeue();
}
console.log("最后留下的人是:", queue.front());
console.log("索引是:", nameList.indexOf(queue.front()));
}
好了,恭喜你,约瑟夫环问题已经被解决
三、优先级队列
什么是优先级队列呢?
顾名思义,就是按照优先级排列的队列。
那我们怎么实现优先级队列呢?
我们可以发现,优先级队列与普通的队列不同之处在于元素的入队列。在优先级队列中,我们要更具元素的优先级,进行优先级排序,然后插入。
思考
- 当队列为空时,直接插入
- 队列不为空时,遍历队列,查找有没有优先级大于要插入元素的优先级
- 如果有,则在优先级大的前面插入
- 没有,则直接在队列后插入
好了,我们来看一下代码怎么实现
enqueue(element, priorty) {
// 1. 如果队列为空
if (this.isEmpty()) {
this.queue.unshift({
element,
priorty,
});
} else {
// 2. 有比放入的优先级大的
for (let i = 0; i < this.queue.length; i++) {
if (priorty < this.queue[i].priorty) {
this.queue.splice(i, 0, { element, priorty });
return;
}
}
// 3. 没有比放入的优先级大
this.queue.push({ element, priorty });
}
}
这样,优先级队列的插入方法就实现了,其他方法和普通的队列方式一致。
感谢阅读,觉得有帮助可以点点赞,非常感谢!