队列的理解
队列是遵循先进先出(FIFO)原则的一组有序的项,队列在尾部添加元素,并从顶部移除元素,最新添加的元素必须排在队列的末尾。生活中常见的例子如排队等
队列的封装
function Queue() {
// 属性
this.items = [];
// 方法
// 1将元素加入队列中
Queue.prototype.enqueue = function (elment) {
this.items.push(elment);
}
// 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 === 0;
}
// 5查看队列中的元素个数
Queue.prototype.size = function () {
return this.items.length;
}
// 6 toString方法
Queue.prototype.toString = function () {
let res = '';
for (let i = 0; i < this.items.length; i++) {
res += this.items[i] + ' ';
}
return res;
}
}
队列的应用-击鼓传花
function passGame(names, num) {
// 创建一个队列
let q = new Queue();
// 加入队列
for (let i = 0; i < names.length; i++) {
q.enqueue(names[i]);
}
// 游戏只剩一个人的时候即找到那个人了 所以条件为 人数大于1
if (q.size() > 1) {
// 1 先将num前面的人加入到队列的尾部
for (let j = 0; j < num - 1; j++) {
q.enqueue(q.dequeue())
}
// 如果找到num,在队列删除对应的人
q.dequeue()
}
// 找到相应的人
let target = q.front();
return '下标' + names.indexOf(target) + ':' + target;
}
let names = ['张三', '李四', '王五', '马梅梅', '孙倩', '武东', '孙婷'];
let result = passGame(names, 3);
console.log(result); // 下标3:马梅梅
分析
击鼓传花
1 '张三', '李四', '王五', '马梅梅', '孙倩', '武东', '孙婷' --> '马梅梅', '孙倩', '武东', '孙婷' '张三', '李四',
2 '马梅梅', '孙倩', '武东', '孙婷' '张三', '李四', ---> '孙婷' '张三', '李四', '马梅梅', '孙倩',
3 '孙婷' '张三', '李四', '马梅梅', '孙倩', ---> '马梅梅', '孙倩', '孙婷' '张三',
4 '马梅梅', '孙倩', '孙婷' '张三', ---> '张三', '马梅梅', '孙倩',
5 '张三', '马梅梅', '孙倩', ---> '张三', '马梅梅',
6 '张三', '马梅梅', ---> '张三', '马梅梅', '张三', ---> '马梅梅'
两个栈实现一个队列
// 栈 后进先出 比如 堆放盘子和取盘子
let stack1 = [];
let stack2 = [];
/**
* 入队
* @param n n
*/
function add(n) {
stack1.push(n)
}
/**
* 出队
*/
function deleteOne() {
let res
const s1 = stack1
const s2 = stack2
// 将 stack1 所有元素移动到 stack2 中
while (s1.length) {
const n = s1.pop()
if (n != null) {
s2.push(n)
}
}
// stack2 pop
res = s2.pop()
// 将 stack2 所有元素“还给”stack1
while (s2.length) {
const n = s2.pop()
if (n != null) {
s1.push(n)
}
}
return res || null
}
function getLength() {
return stack1.length
}
add(100)
add(200)
add(300)
console.info(getLength())
console.info(deleteOne(),stack1)
优先队列
function PriorityQueue() {
this.items = []
// 封装内部类
function PriorityElement(element, priority) {
this.element = element;
this.priority = priority;
}
PriorityQueue.prototype.add = function (element, priority) {
let queueElement = new PriorityElement(element, priority);
// 如果队列为空,直接添加
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)
}
}
}
// toString方法
PriorityQueue.prototype.toString = function () {
let res = '';
for (let i = 0; i < this.items.length; i++) {
res += this.items[i].element + '的优先级: ' + this.items[i].priority + '\n';
}
return res;
}
}
let pq = new PriorityQueue()
pq.add('张三', 122);
pq.add('李四', 12);
pq.add('王五', 35);
pq.add('李磊', 23);
let res = pq.toString();
console.log(res)
/*
李四的优先级: 12
李磊的优先级: 23
王五的优先级: 35
张三的优先级: 122
*/