@andrewrubin/min-heap
Version:
Min Heap data structure in JavaScript
1 lines • 8.38 kB
Source Map (JSON)
{"version":3,"file":"min-heap.cjs","sources":["../index.js"],"sourcesContent":["/**\n * Creates a HeapNode object for use in the MinHeap class.\n * The purpose of HeapNode is to establish some consistency across different\n * potential data types you'd use with MinHeap.\n */\nclass HeapNode {\n /**\n * Instantiates a HeapNode with a value property equal to the value passed.\n * @param {*} value\n */\n constructor(value) {\n this.value = value;\n }\n}\n\n/**\n * Creates a min heap data structure\n * Public methods are insert(), pull(), and peek().\n */\nclass MinHeap {\n #list = [];\n\n /**\n * Compares two nodes. Can be overridden with a custom function passed to the\n * class constructor.\n *\n * @param {HeapNode} n1 - a node to compare\n * @param {HeapNode} n2 - a node to compare\n * @returns Returns true if n2's value is greater than n1's; false otherwise.\n */\n #compare = (n1, n2) => {\n if (!n1 instanceof HeapNode || !n2 instanceof HeapNode) {\n throw \"Comparison argument must be an instance of HeapNode.\";\n }\n return n2.value > n1.value;\n };\n\n /**\n * Instantiates a MinHeap.\n *\n * @param {Function} compareFunction - optional custom comparison function.\n * See the #compare member for implementation details.\n */\n constructor(compareFunction) {\n if (compareFunction && typeof compareFunction === \"function\") {\n this.#compare = compareFunction;\n }\n }\n\n /**\n * Gets the parent node's index.\n *\n * @param {Number} i index of the node whose parent you want.\n * @returns the index of the parent node.\n */\n #parent(i) {\n return Math.floor((i - 1) * 0.5);\n }\n\n /**\n * Gets the index of the node's left child.\n *\n * @param {Number} i index of the node whose left child you want.\n * @returns the index of the node's left child.\n */\n #leftChild(i) {\n const childIndex = i * 2 + 1;\n return this.#list[childIndex] && childIndex;\n }\n\n /**\n * Gets the index of the node's right child.\n *\n * @param {Number} i index of the node whose right child you want.\n * @returns the index of the node's right child.\n */\n #rightChild(i) {\n const childIndex = i * 2 + 2;\n return this.#list[childIndex] && childIndex;\n }\n\n /**\n * Bubbles a node up the heap to its proper position, to maintain the min heap\n * strutcure.\n *\n * @param {Number} i index of the node to bubble up.\n */\n #heapifyUp(i) {\n if (this.#list.length < 2) return;\n\n while (this.#parent(i) >= 0) {\n const iParent = this.#parent(i);\n\n // Get references to the nodes themselves\n let node = this.#list[i];\n let parentNode = this.#list[iParent];\n\n // Exit early if the node at i is greater than the parent node\n if (this.#compare(parentNode, node)) break;\n\n // Swap the nodes and set them:\n [parentNode, node] = [node, parentNode];\n this.#list[iParent] = parentNode;\n this.#list[i] = node;\n\n i = iParent;\n }\n }\n\n /**\n * Moves a node down the heap to its proper position, to maintain the min heap\n * strutcure.\n *\n * @param {Number} i index of the node to move down.\n */\n #heapifyDown(i) {\n if (this.#list.length < 2) return;\n\n while (this.#leftChild(i)) {\n // Get the child indeces, and find the smaller of the two nodes\n const iChildL = this.#leftChild(i);\n const iChildR = this.#rightChild(i);\n let iSmallestChild =\n iChildR && this.#compare(this.#list[iChildR], this.#list[iChildL])\n ? iChildR\n : iChildL;\n\n // Get references to the nodes themselves\n let node = this.#list[i];\n let childNode = this.#list[iSmallestChild];\n\n // Exit early if the child is greater than the node at i\n if (this.#compare(node, childNode)) break;\n\n // Swap the nodes and set them\n [node, childNode] = [childNode, node];\n this.#list[i] = node;\n this.#list[iSmallestChild] = childNode;\n\n i = iSmallestChild;\n }\n }\n\n /**\n * Peek the root node.\n *\n * @returns the root node's value property.\n */\n peek() {\n return this.#list[0].value;\n }\n\n /**\n * Removes and returns the root node. Readjusts the heap to maintain its\n * required structure.\n *\n * @returns the root node's value property.\n */\n pull() {\n if (this.#list.length === 0) return;\n\n const firstNode = this.#list[0];\n const poppedNode = this.#list.pop();\n\n if (this.#list.length !== 0) {\n this.#list[0] = poppedNode;\n this.#heapifyDown(0);\n }\n\n return firstNode.value;\n }\n\n /**\n * Inserts a HeapNode instance.\n *\n * @param {*} value - The value of the node to insert.\n * @returns the value passed.\n */\n insert(value) {\n const length = this.#list.push(new HeapNode(value));\n this.#heapifyUp(length - 1);\n return value;\n }\n\n /**\n * Gets the heap array. Useful for debugging/logging.\n *\n * @returns the heap array.\n */\n getList() {\n return this.#list;\n }\n\n /**\n * Checks if the heap is empty.\n *\n * @returns true if empty, false otherwise.\n */\n isEmpty() {\n return this.#list.length === 0;\n }\n}\n\nexport default MinHeap;\n"],"names":["HeapNode","value","this","_list","_classPrivateFieldLooseKey","_compare","_parent","_leftChild","_rightChild","_heapifyUp","_heapifyDown","_parent2","i","Math","floor","_leftChild2","childIndex","_classPrivateFieldLooseBase","_rightChild2","_heapifyUp2","length","iParent","node","parentNode","_ref","_heapifyDown2","iChildL","iChildR","iSmallestChild","childNode","_ref2","MinHeap","compareFunction","Object","defineProperty","writable","n1","n2","_proto","prototype","peek","pull","firstNode","poppedNode","pop","insert","push","getList","isEmpty"],"mappings":"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"}