@practicaljs/priority-queue
Version:
Javascript / Typescript priority queue ( max / min heap )
79 lines (78 loc) • 3.03 kB
JavaScript
var y = Object.defineProperty;
var d = (r, e, t) => e in r ? y(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
var a = (r, e, t) => (d(r, typeof e != "symbol" ? e + "" : e, t), t);
class g {
constructor(e, t) {
a(this, "parentIndex", (e) => Math.ceil(e / 2) - 1);
a(this, "leftIndex", (e) => e * 2 + 1);
a(this, "rightIndex", (e) => e * 2 + 2);
a(this, "getKey");
a(this, "heap", []);
a(this, "keyTrack", /* @__PURE__ */ new Map());
a(this, "compare");
this.compare = e, this.enqueue = this.enqueue.bind(this), this.dequeue = this.dequeue.bind(this), this.clear = this.clear.bind(this), this.hasItem = this.hasItem.bind(this), this.dequeueByIndex = this.dequeueByIndex.bind(this), this.dequeueItem = this.dequeueItem.bind(this), this.getKey = t;
}
get peek() {
return this.heap[0];
}
get length() {
return this.heap.length;
}
hasItem(e) {
return this.getKey ? this.keyTrack.has(this.getKey(e)) : !1;
}
enqueue(e) {
if (this.getKey && this.hasItem(e)) {
const i = this.heap[this.keyTrack.get(this.getKey(e))];
if (this.compare(e, i) === 0)
return;
this.dequeueItem(e);
}
this.heap.push(e);
let t = this.heap.length - 1;
this.getKey && this.keyTrack.set(this.getKey(e), t);
let h = this.parentIndex(t);
for (; h > -1 && this.compare(this.heap[h], this.heap[t]) > 0; ) {
if ([this.heap[h], this.heap[t]] = [this.heap[t], this.heap[h]], this.getKey) {
const i = this.getKey(this.heap[h]);
this.keyTrack.set(i, h), this.keyTrack.set(this.getKey(this.heap[t]), t);
}
[t, h] = [h, this.parentIndex(h)];
}
}
dequeueByIndex(e) {
const t = this.heap.length - 1;
[this.heap[e], this.heap[t]] = [this.heap[t], this.heap[e]], this.getKey && (this.keyTrack.set(this.getKey(this.heap[e]), e), this.keyTrack.set(this.getKey(this.heap[t]), t));
let h = e, i = this.leftIndex(h), n = this.rightIndex(h);
for (; i < t || n < t; ) {
let s = -1;
i < t && n < t ? s = this.compare(this.heap[i], this.heap[n]) > 0 ? n : i : i < t ? s = i : s = n;
const p = this.compare(this.heap[s], this.heap[h]);
if (p > 0)
break;
p < 1 && ([this.heap[h], this.heap[s]] = [this.heap[s], this.heap[h]], this.getKey && (this.keyTrack.set(this.getKey(this.heap[h]), h), this.keyTrack.set(this.getKey(this.heap[s]), s)), [h, i, n] = [s, this.leftIndex(s), this.rightIndex(s)]);
}
const u = this.heap.pop();
return this.getKey && u && this.keyTrack.delete(this.getKey(u)), u;
}
dequeueItem(e) {
if (!this.getKey || !this.hasItem(e))
return null;
const t = this.keyTrack.get(this.getKey(e));
return this.dequeueByIndex(t);
}
dequeueByKey(e) {
const t = this.keyTrack.get(e);
if (t !== void 0)
return this.dequeueByIndex(t);
}
dequeue() {
return this.dequeueByIndex(0);
}
clear() {
this.heap = [], this.keyTrack.clear();
}
}
export {
g as PriorityQueue
};