Hey folks, I’m working on a little task scheduler in TypeScript for practice, and I’m trying to use a min-heap so I can always grab the next task by time. The weird part is when I pop one task, update its time, and push it back, another task sometimes gets skipped, which makes me think I broke the heap while trying to keep it fast.
class MinHeap {
data: { id: string; time: number }[] = [];
push(item: { id: string; time: number }) {
this.data.push(item);
this.bubbleUp(this.data.length - 1);
}
pop() {
if (this.data.length === 0) return undefined;
const top = this.data[0];
const end = this.data.pop()!;
if (this.data.length) {
this.data[0] = end;
this.bubbleDown(0);
}
return top;
}
bubbleUp(i: number) {
while (i > 0) {
const p = Math.floor((i - 1) / 2);
if (this.data[p].time <= this.data[i].time) break;
[this.data[p], this.data[i]] = [this.data[i], this.data[p]];
i = p;
}
}
bubbleDown(i: number) {
const n = this.data.length;
while (true) {
let smallest = i;
const left = i * 2 + 1;
const right = i * 2 + 2;
if (left < n && this.data[left].time < this.data[smallest].time) {
smallest = left;
}
if (right < n && this.data[right].time < this.data[smallest].time) {
smallest = right;
}
if (smallest === i) break;
[this.data[i], this.data[smallest]] = [this.data[smallest], this.data[i]];
}
}
}
const heap = new MinHeap();
heap.push({ id: "a", time: 2 });
heap.push({ id: "b", time: 5 });
heap.push({ id: "c", time: 3 });
const task = heap.pop()!;
task.time = 10;
heap.push(task);
console.log(heap.data);
Am I missing something obvious in my heap maintenance here, or is reinserting a mutated item the part that’s biting me?
Yoshiii ![]()