Skip to content

Instantly share code, notes, and snippets.

@kyleshevlin
Last active February 13, 2025 18:32
Show Gist options
  • Save kyleshevlin/39c8d5bfb9579afa472825ef279b34b1 to your computer and use it in GitHub Desktop.
Save kyleshevlin/39c8d5bfb9579afa472825ef279b34b1 to your computer and use it in GitHub Desktop.
Heap class with customizable comparator
class Heap {
constructor(comparator = (a, b) => a - b) {
this.heap = []
this.comparator = comparator
}
getParentIndex(index) {
return Math.floor((index - 1) / 2)
}
getLeftChildIndex(index) {
return 2 * index + 1
}
getRightChildIndex(index) {
return 2 * index + 2
}
add(val) {
this.heap.push(val)
this.bubbleUp(this.heap.length - 1)
return this
}
bubbleUp(index) {
let currentIndex = index
let parentIndex = this.getParentIndex(currentIndex)
// Keep bubbling up while parent should be below current
while (parentIndex >= 0 && this.comparator(this.heap[parentIndex], this.heap[currentIndex]) > 0) {
// Swap
const temp = this.heap[currentIndex]
this.heap[currentIndex] = this.heap[parentIndex]
this.heap[parentIndex] = temp
currentIndex = parentIndex
parentIndex = this.getParentIndex(currentIndex)
}
}
remove() {
if (this.heap.length === 0) return null
if (this.heap.length === 1) return this.heap.pop()
const result = this.heap[0]
this.heap[0] = this.heap.pop()
this.bubbleDown(0)
return result
}
bubbleDown(index) {
let currentIndex = index
while (true) {
const leftChildIndex = this.getLeftChildIndex(currentIndex)
const rightChildIndex = this.getRightChildIndex(currentIndex)
let candidateIndex = currentIndex
// Find which child should be the parent (if any)
if (leftChildIndex < this.heap.length &&
this.comparator(this.heap[candidateIndex], this.heap[leftChildIndex]) > 0) {
candidateIndex = leftChildIndex
}
if (rightChildIndex < this.heap.length &&
this.comparator(this.heap[candidateIndex], this.heap[rightChildIndex]) > 0) {
candidateIndex = rightChildIndex
}
if (candidateIndex === currentIndex) break
// Swap
const temp = this.heap[currentIndex]
this.heap[currentIndex] = this.heap[candidateIndex]
this.heap[candidateIndex] = temp
currentIndex = candidateIndex
}
}
peek() {
return this.heap[0]
}
get size() {
return this.heap.length
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment