Skip to content

Instantly share code, notes, and snippets.

@uhop
Last active October 9, 2019 23:55
Show Gist options
  • Save uhop/c1bc5af4f3b2434ab9b0a0ceabea9f75 to your computer and use it in GitHub Desktop.
Save uhop/c1bc5af4f3b2434ab9b0a0ceabea9f75 to your computer and use it in GitHub Desktop.
Simple heap implementation
'use strict';
// using heap implementation from https://github.com/heya/ctr under the BSD-3 license
class Heap {
constructor(less = (a, b) => a < b, arrayLike = []) {
this.less = less;
this.array = Heap.make(Array.from(arrayLike), this.less);
}
get length() {
return this.array.length;
}
get isEmpty() {
return !this.array.length;
}
clear() {
this.array = [];
return this;
}
top() {
return this.array[0];
}
pop() {
return Heap.pop(this.array, this.less);
}
push(value) {
Heap.push(this.array, value, this.less);
return this;
}
releaseSorted() {
Heap.sort(this.array, this.less);
const array = this.array;
this.array = [];
return array;
}
static make(array, less = (a, b) => a < b) {
if (array.length <= 1) return;
for (let n = array.length, j = (n >> 1) - 1, a, b; j >= 0; --j) {
for (let i = j, c = (i << 1) + 1; c < n; i = c, c = (i << 1) + 1) {
b = array[c];
if (c + 1 < n) {
a = array[c + 1];
if (!less(a, b)) {
++c;
b = a;
}
}
a = array[i];
if (!less(a, b)) break;
array[c] = a;
array[i] = b;
}
}
}
static pop(heap, less = (a, b) => a < b) {
const n = heap.length - 1;
if (n > 0) {
let a = heap[n],
b;
heap[n] = heap[0];
heap[0] = a;
for (let i = 0, c = 1; c < n; i = c, c = (i << 1) + 1) {
b = heap[c];
if (c + 1 < n) {
a = heap[c + 1];
if (!less(a, b)) {
++c;
b = a;
}
}
a = heap[i];
if (!less(a, b)) break;
heap[c] = a;
heap[i] = b;
}
}
return heap.pop();
}
static push(heap, b, less = (a, b) => a < b) {
let i = heap.length;
heap.push(b);
while (i) {
const p = (i - 1) >> 1,
a = heap[p];
if (!less(a, b)) break;
heap[i] = a;
heap[p] = b;
i = p;
}
}
static sort(heap, less = (a, b) => a < b) {
if (heap.length <= 1) return;
for (let n = heap.length - 1; n; --n) {
let a = heap[n],
b;
heap[n] = heap[0];
heap[0] = a;
for (let i = 0, c = 1; c < n; i = c, c = (i << 1) + 1) {
b = heap[c];
if (c + 1 < n) {
a = heap[c + 1];
if (!less(a, b)) {
++c;
b = a;
}
}
a = heap[i];
if (!less(a, b)) break;
heap[c] = a;
heap[i] = b;
}
}
}
}
module.exports = Heap;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment