class MinHeap {
constructor(arr = []) {
this.container = [];
if (Array.isArray(arr)) {
arr.forEach(this.insert.bind(this));
}
}
parent(index) {
return Math.floor((index - 1) / 2);
}
left(index) {
return 2 * index + 1;
}
right(index) {
return 2 * index + 2;
}
swap(i, j) {
const { container } = this;
[container[i], container[j]] = [container[j], container[i]];
}
insert(data) {
const { container } = this;
container.push(data);
let index = container.length - 1;
while (this.parent(index) >= 0 && container[index] < container[this.parent(index)]) {
this.swap(index, this.parent(index));
index = this.parent(index);
}
}
extract() {
const { container } = this;
if (!container.length) {
return null;
}
this.swap(0, container.length - 1);
const res = container.pop();
this.sink(0);
return res;
}
sink(index) {
const { container } = this;
let smallestIndex = index;
const l = this.left(index), r = this.right(index);
if (l < container.length && container[l] < container[smallestIndex]) {
smallestIndex = l;
}
if (r < container.length && container[r] < container[smallestIndex]) {
smallestIndex = r;
}
if (smallestIndex !== index) {
this.swap(index, smallestIndex);
this.sink(smallestIndex);
}
}
}