UNPKG

addressable-binary-heaps

Version:

A versatile TypeScript library for addressable binary heaps, delivering optimized and scalable min-heap and max-heap implementations, seamlessly supporting both object-oriented and functional paradigms.

234 lines (230 loc) 7.69 kB
'use strict'; var heap = require('./heap.js'); var heap_util = require('./heap.util.js'); /* ----------------------------------------- */ /* ---------- // Helper functions ---------- */ /* ----------------------------------------- */ /** * Rebalances the max-heap by moving an element down to maintain heap property. * Compares the element with its children and swaps with the larger child if necessary. * * @typeParam H - The type of max-heap array. * @param instance - The max-heap instance to rebalance. * @param index - Starting index of the element to move down. */ function heapifyDown(instance, index) { const li = heap_util.getLeftChildIndex(index); const leftChild = instance[li]; if (leftChild === undefined) { return; } const ri = heap_util.getRightChildIndex(index); const rightChild = instance[ri]; const higherKeyChildIndex = rightChild !== undefined && rightChild.key > leftChild.key ? ri : li; if (instance[index].key >= instance[higherKeyChildIndex].key) { return; } heap_util.swapHeapNodes(instance, index, higherKeyChildIndex); heapifyDown(instance, higherKeyChildIndex); } /** * Rebalances the max-heap by moving an element up to maintain heap property. * Compares the element with its parent and swaps if the element is larger. * * @typeParam H - The type of max-heap array. * @param instance - The max-heap instance to rebalance. * @param index - Starting index of the element to move up. */ function heapifyUp(instance, index) { const pi = heap_util.getParentIndex(index); if (instance[pi] === undefined || instance[pi].key > instance[index].key) { return; } heap_util.swapHeapNodes(instance, index, pi); heapifyUp(instance, pi); } /* ----------------------------------------- */ /* ---------- Helper functions // ---------- */ /* ----------------------------------------- */ /** * Creates a new max-heap instance, optionally initialized with elements. * * @typeParam H - The type of max-heap array. * @param [initialNodes] - Array of unsorted heap elements to initialize with. * @returns A new max-heap instance. */ function create(initialNodes) { const instance = []; instance.indices = new WeakMap(); if (initialNodes) { for (const node of initialNodes) { add(instance, node); } } return instance; } /** * Clears a max-heap instance by removing all elements and their index mappings. * * @typeParam H - The type of max-heap array. * @param instance - The max-heap instance to clear. */ function clear(instance) { return heap.clear(instance); } /** * Returns the current number of elements in the max-heap. * * @typeParam H - The type of max-heap array. * @param instance - The max-heap instance. * @returns The number of elements in the heap. */ function size(instance) { return heap.size(instance); } /** * Adds a new element to the max-heap while maintaining the heap property. * The element is initially added at the end and then bubbled up as needed. * * @typeParam H - The type of max-heap array. * @param instance - The max-heap instance. * @param node - The new element to add. */ function add(instance, node) { instance.indices.set(node, instance.length); instance.push(node); heapifyUp(instance, instance.length - 1); } /** * Returns the maximum element (root) of the max-heap without removing it. * * @typeParam H - The type of max-heap array. * @param instance - The max-heap instance. * @returns The maximum element or `undefined` if heap is empty. */ function peek(instance) { return heap.peek(instance); } /** * Removes and returns the maximum element (root) from the heap. * Replaces root with last element and restores heap property. * * @typeParam H - The type of max-heap array. * @param instance - The max-heap instance. * @returns The maximum element or `undefined` if heap is empty. */ function pop(instance) { if (0 === instance.length) { return; } if (1 === instance.length) { return instance.pop(); } heap_util.swapHeapNodes(instance, 0, instance.length - 1); const popped = instance.pop(); instance.indices.delete(popped); heapifyDown(instance, 0); return popped; } /** * Removes a specific element from anywhere in the heap. * Maintains heap property after removal. * * @typeParam H - The type of max-heap array. * @param instance - The max-heap instance. * @param node - The element to remove. * @returns `true` if element was found and removed, `false` otherwise. */ function remove(instance, node) { if (0 === instance.length) { return false; } if (node === instance.at(-1)) { instance.pop(); return true; } const index = instance.indices.get(node); if (index === undefined) { return false; } heap_util.swapHeapNodes(instance, index, instance.length - 1); const deleted = instance.indices.delete(instance.pop()); heapifyDown(instance, index); return deleted; } /** * Increases the key value of a heap element by a specified amount. * After increase, element may need to bubble up to maintain heap property. * * @typeParam H - The type of max-heap array. * @param instance - The max-heap instance. * @param node - The element to modify. * @param increaseValue - Amount to increase the key by. * @returns `true` if element was found and modified, `false` otherwise. */ function increase(instance, node, increaseValue) { const index = instance.indices.get(node); if (undefined === index) { return false; } node.key += increaseValue; heapifyUp(instance, index); return true; } /** * Decreases the key value of a heap element by a specified amount. * After decrease, element may need to sink down to maintain heap property. * * @typeParam H - The type of max-heap array. * @param instance - The max-heap instance. * @param node - The element to modify. * @param decreaseValue - Amount to decrease the key by. * @returns `true` if element was found and modified, `false` otherwise. */ function decrease(instance, node, decreaseValue) { const index = instance.indices.get(node); if (undefined === index) { return false; } node.key -= decreaseValue; heapifyDown(instance, index); return true; } /** * Returns an iterator for traversing all elements in the max-heap. * * *Note*: The traversal follows the order of the underlying array, not the priority order. * * @typeParam H - The type of max-heap array. * @param instance - The max-heap instance. * @param [reversed=false] - If `true`, the iterator will traverse the heap in reverse order. * @returns An iterator yielding heap elements in the specified order. */ function entries(instance, reversed = false) { return heap.entries(instance, reversed); } /** * Returns an iterator for traversing just the key values in the max-heap. * * *Note*: The traversal follows the order of the underlying array, not the priority order. * * @typeParam H - The type of max-heap array. * @param instance - The max-heap instance. * @param [reversed=false] - If `true`, the iterator will traverse the heap in reverse order. * @returns An iterator yielding heap element keys in the specified order. */ function keys(instance, reversed = false) { return heap.keys(instance, reversed); } exports.add = add; exports.clear = clear; exports.create = create; exports.decrease = decrease; exports.entries = entries; exports.increase = increase; exports.keys = keys; exports.peek = peek; exports.pop = pop; exports.remove = remove; exports.size = size;