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.
221 lines (218 loc) • 7.54 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, getParentIndex, getRightChildIndex, getLeftChildIndex } 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) {
let i = index;
let li = getLeftChildIndex(i);
while (li < instance.length) {
const ri = getRightChildIndex(i);
const higherKeyIndex = ri < instance.length && instance[ri].key > instance[li].key ? ri : li;
if (instance[i].key >= instance[higherKeyIndex].key) {
break;
}
swapHeapNodes(instance, i, higherKeyIndex);
i = higherKeyIndex;
li = getLeftChildIndex(i);
}
}
/**
* 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) {
for (let i = index, pi = getParentIndex(i); 0 <= pi && instance[pi].key <= instance[i].key; i = pi, pi = getParentIndex(i)) {
swapHeapNodes(instance, i, 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();
initialNodes?.forEach((node) => 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 ret = instance.pop();
if (ret) {
instance.indices.delete(ret);
}
heapifyDown(instance, 0);
return ret;
}
/**
* 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[instance.length - 1]) {
instance.pop();
return true;
}
const index = instance.indices.get(node);
if (undefined === index) {
return false;
}
swapHeapNodes(instance, index, instance.length - 1);
let ret = false;
const poppedNode = instance.pop();
if (poppedNode) {
ret = instance.indices.delete(poppedNode);
}
if (ret) {
heapifyDown(instance, index);
}
return ret;
}
/**
* 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 dencreaseValue - Amount to decrease the key by.
* @returns `true` if element was found and modified, `false` otherwise.
*/
function decrease(instance, node, dencreaseValue) {
const index = instance.indices.get(node);
if (undefined === index) {
return false;
}
node.key -= dencreaseValue;
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 };