lgrthms
Version:
Algorithms and data structures for your JavaScript and TypeScript projects 🧑💻
93 lines (92 loc) • 2.97 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Heap = void 0;
const Comparator_1 = require("../utils/Comparator");
class Heap {
constructor(method, compareFn) {
this.heap = [];
this.comparator = new Comparator_1.Comparator(compareFn);
this.method = method;
}
get size() {
return this.heap.length;
}
// O(n) time | O(n) space
build(array) {
this.heap = array;
const lastIndex = this.heap.length - 1;
const lastParentIndex = this.getParentIndex(lastIndex);
for (let index = lastParentIndex; index >= 0; index--) {
this.siftDown(index);
}
}
// O(log(n)) time | O(1) space
insert(value) {
this.heap.push(value);
this.siftUp(this.heap.length - 1);
return value;
}
// O(1) time | O(1) space
peek() {
return this.heap[0];
}
// O(n) time | O(n) space
toArray() {
return [...this.heap];
}
// O(log(n)) time | O(1) space
extract() {
if (this.heap.length === 0) {
return;
}
this.swap(0, this.heap.length - 1);
const value = this.heap.pop();
this.siftDown(0);
return value;
}
// O(log(n)) time | O(1) space
siftDown(index) {
let childOneIndex = this.getChildIndex(index, 1);
while (childOneIndex !== -1) {
const childTwoIndex = this.getChildIndex(index, 2);
let childIndexToSwapWith = childOneIndex;
if (childTwoIndex !== -1 && this.comparator[this.method](this.heap[childTwoIndex], this.heap[childOneIndex])) {
childIndexToSwapWith = childTwoIndex;
}
if (this.comparator[this.method](this.heap[childIndexToSwapWith], this.heap[index])) {
this.swap(childIndexToSwapWith, index);
index = childIndexToSwapWith;
childOneIndex = this.getChildIndex(index, 1);
}
else {
break;
}
}
}
// O(log(n)) time | O(1) space
siftUp(index) {
let parentIndex = this.getParentIndex(index);
while (index > 0 && this.comparator[this.method](this.heap[index], this.heap[parentIndex])) {
this.swap(index, parentIndex);
index = parentIndex;
parentIndex = this.getParentIndex(index);
}
}
// O(1) time | O(1) space
swap(i, j) {
const temp = this.heap[i];
this.heap[i] = this.heap[j];
this.heap[j] = temp;
}
// O(1) time | O(1) space
getChildIndex(parentIndex, childNumber) {
const childIndex = parentIndex * 2 + childNumber;
const lastIndex = this.heap.length - 1;
return childIndex > lastIndex ? -1 : childIndex;
}
// O(1) time | O(1) space
getParentIndex(childIndex) {
return Math.floor((childIndex - 1) / 2);
}
}
exports.Heap = Heap;