Sunday, March 16, 2025

Min Priority Queue in TypeScript

/**
* @class
* Class representing a min/max PriorityQueue
*
* The default is a minPriorityQueue if no value is used in the constructor.
* If you want a maxPriorityQueue, pass true in the constructor e.g.
*
* let maxPQ = new PriorityQueue(true);
* let minPQ = new PriorityQueue();
*
* AppsScripts won't let you define private methods, so here are the public methds
*
* add(v {int}) // adds a new value into the queue
* contains(v {int}) // returns true if the queue contains the value
* isEmpty() {bool} // returns true if there are no ints in the queue
* pop() {int} // returns the min/max value in the queue
*
*/
class PriorityQueue {
constructor(isMax) {
if (undefined == isMax || null == isMax || false == isMax) {
this.isMax = false;
} else {
this.isMax = true;
}
this.heap = [];
this.index = new Map();
this.size = this.heap.length;
}
contains(v) {
return this.index.has(v);
}
exch(i, j) {
let t = this.heap[i];
this.heap[i] = this.heap[j];
this.index.set(t, j);
this.index.set(this.heap[j], i);
this.heap[j] = t;
}
add(v) {
if (this.contains(v)) return;
this.size++;
this.heap[this.size] = v;
this.swim(this.size);
this.index.set(v, this.size);
}
isEmpty() {
return this.size == 0;
}
length() {
return this.size;
}
less(i, j) {
if (this.isMax) {
return this.heap[i] < this.heap[j];
}
return this.heap[i] > this.heap[j];
}
pop() {
let max = this.heap[1];
this.exch(1, this.size--);
this.heap.pop();
this.sink(1);
return max;
}
sink(n) {
while (n*2 <= this.size) {
let j = n*2;
if (j < this.size && this.less(j, j+1)) j++;
if (!this.less(n, j)) break;
this.exch(n, j);
n = j;
}
}
swim(n) {
while (n > 1 && this.less(Math.floor(n/2), n)) {
this.exch(Math.floor(n/2), n);
n = Math.floor(n/2);
}
}
}

function testArray() {
console.log("Testing a min PQ.");
let t = new PriorityQueue(false);
console.log("Inserting 7, 5, 9, 3, 10, 1");
t.add(7);
t.add(5);
t.add(9);
t.add(7);
t.add(3);
t.add(10);
t.add(1);
console.log(`Does the queue contain 5? : ${t.contains(5)}`);
console.log(`Does the queue contain 3? : ${t.contains(3)}`);
let incr = 0;
let output = "";
while (!t.isEmpty() && incr++ < 10)
output += `${t.pop()} `;
console.log(`Output: ${output}`);
console.log("Testing a max PQ.");
console.log("Inserting 7, 5, 9, 3, 10, 1");
output = "";
t = new PriorityQueue(true);
t.add(7);
t.add(5);
t.add(9);
t.add(3);
t.add(10);
t.add(1);
console.log(`Does the queue contain 5? : ${t.contains(5)}`);
console.log(`Does the queue contain 3? : ${t.contains(3)}`);
incr = 0;
while (!t.isEmpty() && incr++ < 10)
output += `${t.pop()} `;
console.log(`Output: ${output}`);
}

No comments: