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.
222 lines (219 loc) • 7.57 kB
JavaScript
import { clear as clear$1, size as size$1, peek as peek$1, entries as entries$1, keys as keys$1 } from './heap.js';
import { swapHeapNodes, getRightChildIndex, getLeftChildIndex, getParentIndex } from './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 = getLeftChildIndex(index);
const leftChild = instance[li];
if (leftChild === undefined) {
return;
}
const ri = getRightChildIndex(index);
const rightChild = instance[ri];
const higherKeyChildIndex = rightChild !== undefined && rightChild.key > leftChild.key ? ri : li;
if (instance[index].key >= instance[higherKeyChildIndex].key) {
return;
}
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 = getParentIndex(index);
if (instance[pi] === undefined ||
instance[pi].key > instance[index].key) {
return;
}
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 clear$1(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 size$1(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 peek$1(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();
}
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;
}
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 entries$1(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 keys$1(instance, reversed);
}
export { add, clear, create, decrease, entries, increase, keys, peek, pop, remove, size };