Skip to content

Instantly share code, notes, and snippets.

@veryjos
Created August 17, 2019 03:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save veryjos/c056aaf57d5dc1ed3287208ea9f8bd8f to your computer and use it in GitHub Desktop.
Save veryjos/c056aaf57d5dc1ed3287208ea9f8bd8f to your computer and use it in GitHub Desktop.
class Heap {
constructor(comparator) {
this.elements = [];
this.end = -1;
this.cmp = comparator || ((a, b) => a - b);
}
getLeft(n) {
return (2 * (n + 1)) - 1;
}
getRight(n) {
return 2 * (n + 1);
}
getParent(n) {
return Math.floor((n - 1) / 2);
}
swap(i, j) {
const tmp = this.elements[i];
this.elements[i] = this.elements[j];
this.elements[j] = tmp;
}
heapify(pos) {
// assume the subtrees are valid heaps
// therefore we just swap if violating, and recurse
const lhs = this.getLeft(pos);
const rhs = this.getRight(pos);
let smallest = pos;
if (lhs <= this.end &&
this.cmp(this.elements[smallest], this.elements[lhs]) > 0) {
smallest = lhs
}
if (rhs <= this.end &&
this.cmp(this.elements[smallest], this.elements[rhs]) > 0) {
smallest = rhs
}
if (smallest != pos) {
// swap and heapify
this.swap(pos, smallest);
this.heapify(smallest);
}
}
push(e) {
let pos = ++this.end;
this.elements[pos] = e;
// swap with parent until heap condition is satisfied
while (true) {
if (this.cmp(this.elements[this.getParent(pos)], e) >= 0) {
this.swap(pos, this.getParent(pos));
pos = this.getParent(pos);
} else {
break;
}
}
}
pop() {
if (this.end < 0) {
return undefined;
}
const output = this.elements[0];
// move the last element to the front
this.elements[0] = this.elements[this.end];
--this.end;
// heapify
this.heapify(0);
return output;
}
len() {
return this.end + 1;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment