队列结构
- 先进先出 FIFO (First In First Out)
- 允许在前端(front)删除,允许在后端(rear)插入
- 特殊:优先级队列
自己封装一个队列结构
// es5
function Queue() {
// 创建一个队列容器
this.containter = [];
}
Queue.prototype = {
construtor: Queue,
// 进入队列 element进入队列的元素
enter: function enter(element) {
this.containter.push(element);
},
// 移除队列
leave: function leave() {
if (this.containter.length == 0) return;
return this.containter.shift();
},
// 查看队列的长度
size: function size() {
return this.containter.length;
},
// 查看队列的内容
value: function value() {
// 深拷贝是为了保证外面接收到的结果不论如何的操作都不会影响内部容器的内容
return JSON.parse(JSON.stringify(this.containter));
}
}
// es6
class Queue {
container = [];
// 进入
enter(element) {
this.container.push(element);
}
// 离开
leave() {
return this.container.shift();
}
// 队列的长度
size() {
return this.container.length;
}
// 获取队列中的结果
value() {
return this.container.slice(0);
}
}
// 创建一个队列
var qe = new Queue();
qe.enter(1);
qe.enter(2);
qe.enter(3);
qe.leave();
console.log(qe.value());
面试题:击鼓传花
N个人一起玩游戏,围成一圈,从1开始数数,数到M的人自动淘汰;最后剩下的人会取得胜利,问最后剩下的是原来的哪一位?
class Queue {
container = [];
// 进入
enter(element) {
this.container.push(element);
}
// 离开
leave() {
return this.container.shift();
}
// 队列的长度
size() {
return this.container.length;
}
// 获取队列中的结果
value() {
return this.container.slice(0);
}
}
// 算法题,击鼓传花
// N个人一起玩游戏,围成一圈,从1开始数数,数到M的人自动淘汰;最后剩下的人会取得胜利,问最后剩下的是原来的哪一位?
// n:参加游戏的人数 m:关键数
function game(n, m) {
let qe = new Queue();
// 先把人都依次放入到队列中
for (let i = 1; i <= n; i++) {
qe.enter(i);
}
// 开始处理
while (qe.size() > 1) {
for (let i = 0; i < m - 1; i++) {
qe.enter(qe.leave());
}
qe.leave();
}
return qe.value()[0];
}
let res = game(6, 4);
console.log(res)
优先级队列
- 每个新增的元素不是放到队列的末尾,而是按照指定的优先级放置到指定的位置
- 每个元素都有自己的优先级
自己封装一个优先级队列
function Queue() {
this.container = [];
}
Queue.prototype = {
constructor: Queue,
// 进入队列 priority优先级,默认都是0,数值越大,优先级越高
enter: function enter(element, priority = 0) {
let obj = {
value: element,
priority: priority
};
if (priority === 0) {
// 不指定优先级(最小优先级):存储到末尾即可
this.container.push(obj);
return;
}
// 指定优先级,我们需要从最后一项依次来比较
let flag = false;
for (let i = this.container.length - 1; i >= 0; i--) {
let item = this.container[i];
if (item.priority >= priority) {
// 插入到比较项的后面
this.container.splice(i + 1, 0, obj);
flag = true;
break;
}
};
// 没有比我大的,我就是最大的,插入到容器最开始的位置即可
!flag ? this.container.unshift(obj) : null;
},
// 移除队列
leave: function leave() {
if (this.container.length === 0) return;
return this.container.shift();
},
// 查看队列的长度
size: function size() {
return this.container.length;
},
// 查看队列的内容
value: function value() {
return JSON.parse(JSON.stringify(this.container));
}
};
// 创建一个队列
var qe = new Queue();
qe.enter(10);
qe.enter(12);
qe.enter(14, 2);
qe.leave();
console.log(qe.value());