优先队列是一种抽象数据类型,它支持插入一个元素,并从所有插入的元素中删除最小(或最大)元素的操作。JavaScript 中没有内置的优先队列数据结构,但我们可以使用数组、链表或堆来实现它。
这里给出一个使用最小堆实现的优先队列的基本模板:
class PriorityQueue {
constructor(compareFunc = (a, b) => a < b) {
this.queue = [];
this.compare = compareFunc;
}
// 入队
enqueue(val) {
this.queue.push(val);
this._heapifyUp();
}
// 出队
dequeue() {
if (this.size() === 1) return this.queue.pop();
const val = this.queue[0];
this.queue[0] = this.queue.pop();
this._heapifyDown();
return val;
}
// 返回队首元素
front() {
return this.queue[0];
}
// 返回队列大小
size() {
return this.queue.length;
}
_heapifyUp() {
let idx = this.size() - 1;
while (idx > 0 && this.compare(this.queue[idx], this.queue[Math.floor((idx - 1) / 2)])) {
[this.queue[idx], this.queue[Math.floor((idx - 1) / 2)]] = [this.queue[Math.floor((idx - 1) / 2)], this.queue[idx]];
idx = Math.floor((idx - 1) / 2);
}
}
_heapifyDown() {
let idx = 0;
while ((2 * idx + 1) < this.size()) {
let smallerIdx = 2 * idx + 1;
if (2 * idx + 2 < this.size() && this.compare(this.queue[2 * idx + 2], this.queue[smallerIdx])) {
smallerIdx = 2 * idx + 2;
}
if (this.compare(this.queue[idx], this.queue[smallerIdx])) break;
[this.queue[idx], this.queue[smallerIdx]] = [this.queue[smallerIdx], this.queue[idx]];
idx = smallerIdx;
}
}
}