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
JavaScript
;
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;