Last active
October 9, 2019 23:55
-
-
Save uhop/c1bc5af4f3b2434ab9b0a0ceabea9f75 to your computer and use it in GitHub Desktop.
Simple heap implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'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