Skip to content

Instantly share code, notes, and snippets.

@fazeelanizam13
Last active May 29, 2022 07:15
Show Gist options
  • Save fazeelanizam13/67126de1ec4021542e5031acb89a4e45 to your computer and use it in GitHub Desktop.
Save fazeelanizam13/67126de1ec4021542e5031acb89a4e45 to your computer and use it in GitHub Desktop.
Implementation of a (min) heap data structure in JavaScript
class MinHeap {
// creates an array of given length
constructor(length) {
this.data = new Array(length)
this.size = 0
}
// helpers
rehash = () => {
// create a new array that is twice the size of current array
let newData = new Array(this.data.length * 2)
// copy all values in current array to new array
// not going through whole array as only .75 array should have values at the point of rehashing
let i = 0
while (this.data[i] !== undefined) {
newData[i] = this.data[i]
i++
}
// assign new array to current array
this.data = newData
}
// moves a smaller value up to right place
bubbleUp = valueIndex => {
// get new value from index
let value = this.data[valueIndex]
let parentIndex = Math.floor((valueIndex - 1) / 2)
let parentValue = this.data[parentIndex]
// if new value is less than parent value
// (as this is a min heap, smaller values should be moved up)
if (value < parentValue) {
// swap spots of parent and new value
let temp = parentValue
this.data[parentIndex] = value
this.data[valueIndex] = temp
// perform same operation from the current spot
this.bubbleUp(parentIndex)
// if at right place, return
} else return
}
// moves a larger value down to right place
bubbleDown = valueIndex => {
// get new value from index
let value = this.data[valueIndex]
let leftChildIndex = 2 * valueIndex + 1 // 7
let leftChildValue = this.data[leftChildIndex] // x
let rightChildIndex = 2 * valueIndex + 2 // 8
let rightChildValue = this.data[rightChildIndex] // x
// if not any of children are undefined
if (leftChildValue && rightChildValue) {
// if either of children are smaller
if (value > leftChildValue || value > rightChildValue) {
// get smaller of two children
let smallerChildValue = Math.min(leftChildValue, rightChildValue)
let smallerChildIndex = smallerChildValue === leftChildValue ? leftChildIndex : rightChildIndex
// swap spots with smaller child
let temp = smallerChildValue
this.data[smallerChildIndex] = value
this.data[valueIndex] = temp
// continue same from current spot
this.bubbleDown(smallerChildIndex)
} else return
// if right child is undefined and left child is smaller, we need to swap one last time
} else if (rightChildValue === undefined && value > leftChildValue) {
let temp = leftChildValue
this.data[leftChildIndex] = value
this.data[valueIndex] = temp
// perform same operation from the current spot
this.bubbleDown(valueIndex)
// if both are undefined, return.
// they are vacant spots
} else return
}
// helper functions end
insert = value => {
// if array empty, just insert at root,
// increase size
// and return
if (this.size === 0) {
this.data[0] = value
this.size++
return
}
// load factor = filled slots / total slots
let loadFactor = this.size / this.data.length
// if gte to .75, increase (double) the size
if (loadFactor >= .75) this.rehash()
// insert new value at the end
this.data[this.size] = value
// move new value up the tree to the right place from current spot
this.bubbleUp(this.size)
this.size++
}
removeRoot = () => {
// get the lowest, right-most value and
// assign to root
this.data[0] = this.data[this.size - 1]
this.data[this.size - 1] = undefined
// move new root value down the tree to the right place
// swapping with the smaller of two children
this.bubbleDown(0)
this.size--
}
getMin = () => {
return this.data[0]
}
}
// tests
// let heap = new MinHeap(10)
// heap.insert(1)
// heap.insert(9)
// heap.insert(13)
// heap.insert(8)
// heap.insert(20)
// heap.insert(2)
// heap.insert(2)
// heap.insert(2)
// console.log(heap.size)
// console.log(heap.data)
// heap.removeRoot()
// console.log('size', heap.size)
// console.log(heap.data)
// heap.removeRoot()
// console.log('size', heap.size)
// console.log(heap.data)
// heap.removeRoot()
// console.log('size', heap.size)
// console.log(heap.data)
// heap.insert(26)
// heap.insert(76)
// heap.insert(90)
// heap.insert(-90)
// console.log(heap.data)
// console.log(heap.getMin())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment