tree-multimap-typed
Version:
755 lines (754 loc) • 40.9 kB
TypeScript
/**
* data-structure-typed
*
* @author Pablo Zeng
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import type { BinaryTreeDeleteResult, BinaryTreeOptions, BinaryTreePrintOptions, BTNEntry, DFSOrderPattern, EntryCallback, FamilyPosition, IterationType, NodeCallback, NodeDisplayLayout, NodePredicate, RBTNColor, ToEntryFn } from '../../types';
import { IBinaryTree } from '../../interfaces';
import { IterableEntryBase } from '../base';
import { Range } from '../../common';
/**
* @template K - The type of the key.
* @template V - The type of the value.
*/
export declare class BinaryTreeNode<K = any, V = any> {
key: K;
value?: V;
parent?: BinaryTreeNode<K, V>;
/**
* Creates an instance of BinaryTreeNode.
* @remarks Time O(1), Space O(1)
*
* @param key - The key of the node.
* @param [value] - The value associated with the key.
*/
constructor(key: K, value?: V);
_left?: BinaryTreeNode<K, V> | null | undefined;
/**
* Gets the left child of the node.
* @remarks Time O(1), Space O(1)
*
* @returns The left child.
*/
get left(): BinaryTreeNode<K, V> | null | undefined;
/**
* Sets the left child of the node and updates its parent reference.
* @remarks Time O(1), Space O(1)
*
* @param v - The node to set as the left child.
*/
set left(v: BinaryTreeNode<K, V> | null | undefined);
_right?: BinaryTreeNode<K, V> | null | undefined;
/**
* Gets the right child of the node.
* @remarks Time O(1), Space O(1)
*
* @returns The right child.
*/
get right(): BinaryTreeNode<K, V> | null | undefined;
/**
* Sets the right child of the node and updates its parent reference.
* @remarks Time O(1), Space O(1)
*
* @param v - The node to set as the right child.
*/
set right(v: BinaryTreeNode<K, V> | null | undefined);
_height: number;
/**
* Gets the height of the node (used in self-balancing trees).
* @remarks Time O(1), Space O(1)
*
* @returns The height.
*/
get height(): number;
/**
* Sets the height of the node.
* @remarks Time O(1), Space O(1)
*
* @param value - The new height.
*/
set height(value: number);
_color: RBTNColor;
/**
* Gets the color of the node (used in Red-Black trees).
* @remarks Time O(1), Space O(1)
*
* @returns The node's color.
*/
get color(): RBTNColor;
/**
* Sets the color of the node.
* @remarks Time O(1), Space O(1)
*
* @param value - The new color.
*/
set color(value: RBTNColor);
_count: number;
/**
* Gets the count of nodes in the subtree rooted at this node (used in order-statistic trees).
* @remarks Time O(1), Space O(1)
*
* @returns The subtree node count.
*/
get count(): number;
/**
* Sets the count of nodes in the subtree.
* @remarks Time O(1), Space O(1)
*
* @param value - The new count.
*/
set count(value: number);
/**
* Gets the position of the node relative to its parent.
* @remarks Time O(1), Space O(1)
*
* @returns The family position (e.g., 'ROOT', 'LEFT', 'RIGHT').
*/
get familyPosition(): FamilyPosition;
}
/**
* A general Binary Tree implementation.
*
* @remarks
* This class implements a basic Binary Tree, not a Binary Search Tree.
* The `add` operation inserts nodes level-by-level (BFS) into the first available slot.
*
* @template K - The type of the key.
* @template V - The type of the value.
* @template R - The type of the raw data object (if using `toEntryFn`).
* 1. Two Children Maximum: Each node has at most two children.
* 2. Left and Right Children: Nodes have distinct left and right children.
* 3. Depth and Height: Depth is the number of edges from the root to a node; height is the maximum depth in the tree.
* 4. Subtrees: Each child of a node forms the root of a subtree.
* 5. Leaf Nodes: Nodes without children are leaves.
* @example
* // determine loan approval using a decision tree
* // Decision tree structure
* const loanDecisionTree = new BinaryTree<string>(
* ['stableIncome', 'goodCredit', 'Rejected', 'Approved', 'Rejected'],
* { isDuplicate: true }
* );
*
* function determineLoanApproval(
* node?: BinaryTreeNode<string> | null,
* conditions?: { [key: string]: boolean }
* ): string {
* if (!node) throw new Error('Invalid node');
*
* // If it's a leaf node, return the decision result
* if (!node.left && !node.right) return node.key;
*
* // Check if a valid condition exists for the current node's key
* return conditions?.[node.key]
* ? determineLoanApproval(node.left, conditions)
* : determineLoanApproval(node.right, conditions);
* }
*
* // Test case 1: Stable income and good credit score
* console.log(determineLoanApproval(loanDecisionTree.root, { stableIncome: true, goodCredit: true })); // 'Approved'
*
* // Test case 2: Stable income but poor credit score
* console.log(determineLoanApproval(loanDecisionTree.root, { stableIncome: true, goodCredit: false })); // 'Rejected'
*
* // Test case 3: No stable income
* console.log(determineLoanApproval(loanDecisionTree.root, { stableIncome: false, goodCredit: true })); // 'Rejected'
*
* // Test case 4: No stable income and poor credit score
* console.log(determineLoanApproval(loanDecisionTree.root, { stableIncome: false, goodCredit: false })); // 'Rejected'
* @example
* // evaluate the arithmetic expression represented by the binary tree
* const expressionTree = new BinaryTree<number | string>(['+', 3, '*', null, null, 5, '-', null, null, 2, 8]);
*
* function evaluate(node?: BinaryTreeNode<number | string> | null): number {
* if (!node) return 0;
*
* if (typeof node.key === 'number') return node.key;
*
* const leftValue = evaluate(node.left); // Evaluate the left subtree
* const rightValue = evaluate(node.right); // Evaluate the right subtree
*
* // Perform the operation based on the current node's operator
* switch (node.key) {
* case '+':
* return leftValue + rightValue;
* case '-':
* return leftValue - rightValue;
* case '*':
* return leftValue * rightValue;
* case '/':
* return rightValue !== 0 ? leftValue / rightValue : 0; // Handle division by zero
* default:
* throw new Error(`Unsupported operator: ${node.key}`);
* }
* }
*
* console.log(evaluate(expressionTree.root)); // -27
*/
export declare class BinaryTree<K = any, V = any, R extends object = object> extends IterableEntryBase<K, V | undefined> implements IBinaryTree<K, V, R> {
iterationType: IterationType;
/**
* Creates an instance of BinaryTree.
* @remarks Time O(N * M), where N is the number of items in `keysNodesEntriesOrRaws` and M is the tree size at insertion time (due to O(M) `add` operation). Space O(N) for storing the nodes.
*
* @param [keysNodesEntriesOrRaws=[]] - An iterable of items to add.
* @param [options] - Configuration options for the tree.
*/
constructor(keysNodesEntriesOrRaws?: Iterable<K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | R>, options?: BinaryTreeOptions<K, V, R>);
protected _isMapMode: boolean;
/**
* Gets whether the tree is in Map mode.
* @remarks In Map mode (default), values are stored in an external Map, and nodes only hold keys. If false, values are stored directly on the nodes. Time O(1)
*
* @returns True if in Map mode, false otherwise.
*/
get isMapMode(): boolean;
protected _isDuplicate: boolean;
/**
* Gets whether the tree allows duplicate keys.
* @remarks Time O(1)
*
* @returns True if duplicates are allowed, false otherwise.
*/
get isDuplicate(): boolean;
protected _store: Map<K, V | undefined>;
/**
* Gets the external value store (used in Map mode).
* @remarks Time O(1)
*
* @returns The map storing key-value pairs.
*/
get store(): Map<K, V | undefined>;
protected _root?: BinaryTreeNode<K, V> | null | undefined;
/**
* Gets the root node of the tree.
* @remarks Time O(1)
*
* @returns The root node.
*/
get root(): BinaryTreeNode<K, V> | null | undefined;
protected _size: number;
/**
* Gets the number of nodes in the tree.
* @remarks Time O(1)
*
* @returns The size of the tree.
*/
get size(): number;
protected _NIL: BinaryTreeNode<K, V>;
/**
* Gets the sentinel NIL node (used in self-balancing trees like Red-Black Tree).
* @remarks Time O(1)
*
* @returns The NIL node.
*/
get NIL(): BinaryTreeNode<K, V>;
protected _toEntryFn?: ToEntryFn<K, V, R>;
/**
* Gets the function used to convert raw data objects (R) into [key, value] entries.
* @remarks Time O(1)
*
* @returns The conversion function.
*/
get toEntryFn(): ToEntryFn<K, V, R> | undefined;
/**
* (Protected) Creates a new node.
* @remarks Time O(1), Space O(1)
*
* @param key - The key for the new node.
* @param [value] - The value for the new node (used if not in Map mode).
* @returns The newly created node.
*/
_createNode(key: K, value?: V): BinaryTreeNode<K, V>;
/**
* Creates a new, empty tree of the same type and configuration.
* @remarks Time O(1) (excluding options cloning), Space O(1)
*
* @param [options] - Optional overrides for the new tree's options.
* @returns A new, empty tree instance.
*/
createTree(options?: Partial<BinaryTreeOptions<K, V, R>>): this;
/**
* Ensures the input is a node. If it's a key or entry, it searches for the node.
* @remarks Time O(1) if a node is passed. O(N) if a key or entry is passed (due to `getNode` performing a full search). Space O(1) if iterative search, O(H) if recursive (where H is height, O(N) worst-case).
*
* @param keyNodeOrEntry - The item to resolve to a node.
* @param [iterationType=this.iterationType] - The traversal method to use if searching.
* @returns The resolved node, or null/undefined if not found or input is null/undefined.
*/
ensureNode(keyNodeOrEntry: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): BinaryTreeNode<K, V> | null | undefined;
/**
* Checks if the given item is a `BinaryTreeNode` instance.
* @remarks Time O(1), Space O(1)
*
* @param keyNodeOrEntry - The item to check.
* @returns True if it's a node, false otherwise.
*/
isNode(keyNodeOrEntry: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): keyNodeOrEntry is BinaryTreeNode<K, V>;
/**
* Checks if the given item is a raw data object (R) that needs conversion via `toEntryFn`.
* @remarks Time O(1), Space O(1)
*
* @param keyNodeEntryOrRaw - The item to check.
* @returns True if it's a raw object, false otherwise.
*/
isRaw(keyNodeEntryOrRaw: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | R): keyNodeEntryOrRaw is R;
/**
* Checks if the given item is a "real" node (i.e., not null, undefined, or NIL).
* @remarks Time O(1), Space O(1)
*
* @param keyNodeOrEntry - The item to check.
* @returns True if it's a real node, false otherwise.
*/
isRealNode(keyNodeOrEntry: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): keyNodeOrEntry is BinaryTreeNode<K, V>;
/**
* Checks if the given item is either a "real" node or null.
* @remarks Time O(1), Space O(1)
*
* @param keyNodeOrEntry - The item to check.
* @returns True if it's a real node or null, false otherwise.
*/
isRealNodeOrNull(keyNodeOrEntry: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): keyNodeOrEntry is BinaryTreeNode<K, V> | null;
/**
* Checks if the given item is the sentinel NIL node.
* @remarks Time O(1), Space O(1)
*
* @param keyNodeOrEntry - The item to check.
* @returns True if it's the NIL node, false otherwise.
*/
isNIL(keyNodeOrEntry: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): boolean;
/**
* Checks if the given item is a `Range` object.
* @remarks Time O(1), Space O(1)
*
* @param keyNodeEntryOrPredicate - The item to check.
* @returns True if it's a Range, false otherwise.
*/
isRange(keyNodeEntryOrPredicate: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V>> | Range<K>): keyNodeEntryOrPredicate is Range<K>;
/**
* Checks if a node is a leaf (has no real children).
* @remarks Time O(N) if a key/entry is passed (due to `ensureNode`). O(1) if a node is passed. Space O(1) or O(H) (from `ensureNode`).
*
* @param keyNodeOrEntry - The node to check.
* @returns True if the node is a leaf, false otherwise.
*/
isLeaf(keyNodeOrEntry: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): boolean;
/**
* Checks if the given item is a [key, value] entry pair.
* @remarks Time O(1), Space O(1)
*
* @param keyNodeOrEntry - The item to check.
* @returns True if it's an entry, false otherwise.
*/
isEntry(keyNodeOrEntry: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): keyNodeOrEntry is BTNEntry<K, V>;
/**
* Checks if the given key is valid (comparable or null).
* @remarks Time O(1), Space O(1)
*
* @param key - The key to validate.
* @returns True if the key is valid, false otherwise.
*/
isValidKey(key: any): key is K;
/**
* Adds a new node to the tree.
* @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation adds the node at the first available position in a level-order (BFS) traversal. This is NOT a Binary Search Tree insertion. Time O(N), where N is the number of nodes. It must traverse level-by-level to find an empty slot. Space O(N) in the worst case for the BFS queue (e.g., a full last level).
*
* @param keyNodeOrEntry - The key, node, or entry to add.
* @param [value] - The value, if providing just a key.
* @returns True if the addition was successful, false otherwise.
*/
add(keyNodeOrEntry: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, value?: V): boolean;
/**
* Adds multiple items to the tree.
* @remarks Time O(N * M), where N is the number of items to add and M is the size of the tree at insertion (due to O(M) `add` operation). Space O(M) (from `add`) + O(N) (for the `inserted` array).
*
* @param keysNodesEntriesOrRaws - An iterable of items to add.
* @param [values] - An optional parallel iterable of values.
* @returns An array of booleans indicating the success of each individual `add` operation.
*/
addMany(keysNodesEntriesOrRaws: Iterable<K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | R>, values?: Iterable<V | undefined>): boolean[];
/**
* Merges another tree into this one by adding all its nodes.
* @remarks Time O(N * M), same as `addMany`, where N is the size of `anotherTree` and M is the size of this tree. Space O(M) (from `add`).
*
* @param anotherTree - The tree to merge.
*/
merge(anotherTree: BinaryTree<K, V, R>): void;
/**
* Clears the tree and refills it with new items.
* @remarks Time O(N) (for `clear`) + O(N * M) (for `addMany`) = O(N * M). Space O(M) (from `addMany`).
*
* @param keysNodesEntriesOrRaws - An iterable of items to add.
* @param [values] - An optional parallel iterable of values.
*/
refill(keysNodesEntriesOrRaws: Iterable<K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | R>, values?: Iterable<V | undefined>): void;
/**
* Deletes a node from the tree.
* @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation finds the node, and if it has two children, swaps it with the rightmost node of its left subtree (in-order predecessor) before deleting. Time O(N) in the worst case. O(N) to find the node (`getNode`) and O(H) (which is O(N) worst-case) to find the rightmost node. Space O(1) (if `getNode` is iterative, which it is).
*
* @param keyNodeOrEntry - The node to delete.
* @returns An array containing deletion results (for compatibility with self-balancing trees).
*/
delete(keyNodeOrEntry: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[];
/**
* Searches the tree for nodes matching a predicate.
* @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). Performs a full DFS (pre-order) scan of the tree. Time O(N), as it may visit every node. Space O(H) for the call stack (recursive) or explicit stack (iterative), where H is the tree height (O(N) worst-case).
*
* @template C - The type of the callback function.
* @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
* @param [onlyOne=false] - If true, stops after finding the first match.
* @param [callback=this._DEFAULT_NODE_CALLBACK] - A function to call on matching nodes.
* @param [startNode=this._root] - The node to start the search from.
* @param [iterationType=this.iterationType] - Whether to use 'RECURSIVE' or 'ITERATIVE' search.
* @returns An array of results from the callback function for each matching node.
*/
search<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(keyNodeEntryOrPredicate: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V> | null>, onlyOne?: boolean, callback?: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>[];
/**
* Gets all nodes matching a predicate.
* @remarks Time O(N) (via `search`). Space O(H) or O(N) (via `search`).
*
* @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
* @param [onlyOne=false] - If true, stops after finding the first match.
* @param [startNode=this._root] - The node to start the search from.
* @param [iterationType=this.iterationType] - The traversal method.
* @returns An array of matching nodes.
*/
getNodes(keyNodeEntryOrPredicate: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V>>, onlyOne?: boolean, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): BinaryTreeNode<K, V>[];
/**
* Gets the first node matching a predicate.
* @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). Time O(N) in the worst case (via `search`). Space O(H) or O(N) (via `search`).
*
* @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
* @param [startNode=this._root] - The node to start the search from.
* @param [iterationType=this.iterationType] - The traversal method.
* @returns The first matching node, or undefined if not found.
*/
getNode(keyNodeEntryOrPredicate: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V> | null>, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): BinaryTreeNode<K, V> | null | undefined;
/**
* Gets the value associated with a key.
* @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). Time O(1) if in Map mode. O(N) if not in Map mode (uses `getNode`). Space O(1) if in Map mode. O(H) or O(N) otherwise.
*
* @param keyNodeEntryOrPredicate - The key, node, or entry to get the value for.
* @param [startNode=this._root] - The node to start searching from (if not in Map mode).
* @param [iterationType=this.iterationType] - The traversal method (if not in Map mode).
* @returns The associated value, or undefined.
*/
get(keyNodeEntryOrPredicate: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): V | undefined;
/**
* Checks if a node matching the predicate exists in the tree.
* @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). Time O(N) in the worst case (via `search`). Space O(H) or O(N) (via `search`).
*
* @param [keyNodeEntryOrPredicate] - The key, node, entry, or predicate to check for.
* @param [startNode] - The node to start the search from.
* @param [iterationType] - The traversal method.
* @returns True if a matching node exists, false otherwise.
*/
has(keyNodeEntryOrPredicate?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V>>, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): boolean;
/**
* Clears the tree of all nodes and values.
* @remarks Time O(N) if in Map mode (due to `_store.clear()`), O(1) otherwise. Space O(1)
*/
clear(): void;
/**
* Checks if the tree is empty.
* @remarks Time O(1), Space O(1)
*
* @returns True if the tree has no nodes, false otherwise.
*/
isEmpty(): boolean;
/**
* Checks if the tree is perfectly balanced.
* @remarks A tree is perfectly balanced if the difference between min and max height is at most 1. Time O(N), as it requires two full traversals (`getMinHeight` and `getHeight`). Space O(H) or O(N) (from height calculation).
*
* @param [startNode=this._root] - The node to start checking from.
* @returns True if perfectly balanced, false otherwise.
*/
isPerfectlyBalanced(startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): boolean;
/**
* Checks if the tree is a valid Binary Search Tree (BST).
* @remarks Time O(N), as it must visit every node. Space O(H) for the call stack (recursive) or explicit stack (iterative), where H is the tree height (O(N) worst-case).
*
* @param [startNode=this._root] - The node to start checking from.
* @param [iterationType=this.iterationType] - The traversal method.
* @returns True if it's a valid BST, false otherwise.
*/
isBST(startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): boolean;
/**
* Gets the depth of a node (distance from `startNode`).
* @remarks Time O(H), where H is the depth of the `dist` node relative to `startNode`. O(N) worst-case. Space O(1).
*
* @param dist - The node to find the depth of.
* @param [startNode=this._root] - The node to measure depth from (defaults to root).
* @returns The depth (0 if `dist` is `startNode`).
*/
getDepth(dist: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): number;
/**
* Gets the maximum height of the tree (longest path from startNode to a leaf).
* @remarks Time O(N), as it must visit every node. Space O(H) for recursive stack (O(N) worst-case) or O(N) for iterative stack (storing node + depth).
*
* @param [startNode=this._root] - The node to start measuring from.
* @param [iterationType=this.iterationType] - The traversal method.
* @returns The height ( -1 for an empty tree, 0 for a single-node tree).
*/
getHeight(startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): number;
/**
* Gets the minimum height of the tree (shortest path from startNode to a leaf).
* @remarks Time O(N), as it must visit every node. Space O(H) for recursive stack (O(N) worst-case) or O(N) for iterative (due to `depths` Map).
*
* @param [startNode=this._root] - The node to start measuring from.
* @param [iterationType=this.iterationType] - The traversal method.
* @returns The minimum height (-1 for empty, 0 for single node).
*/
getMinHeight(startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): number;
/**
* Gets the path from a given node up to the root.
* @remarks Time O(H), where H is the depth of the `beginNode`. O(N) worst-case. Space O(H) for the result array.
*
* @template C - The type of the callback function.
* @param beginNode - The node to start the path from.
* @param [callback=this._DEFAULT_NODE_CALLBACK] - A function to call on each node in the path.
* @param [isReverse=false] - If true, returns the path from root-to-node.
* @returns An array of callback results.
*/
getPathToRoot<C extends NodeCallback<BinaryTreeNode<K, V> | undefined>>(beginNode: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, callback?: C, isReverse?: boolean): ReturnType<C>[];
/**
* Finds the leftmost node in a subtree (the node with the smallest key in a BST).
* @remarks Time O(H), where H is the height of the left spine. O(N) worst-case. Space O(H) for recursive/trampoline stack.
*
* @template C - The type of the callback function.
* @param [callback=this._DEFAULT_NODE_CALLBACK] - A function to call on the leftmost node.
* @param [startNode=this._root] - The subtree root to search from.
* @param [iterationType=this.iterationType] - The traversal method.
* @returns The callback result for the leftmost node.
*/
getLeftMost<C extends NodeCallback<BinaryTreeNode<K, V> | undefined>>(callback?: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>;
/**
* Finds the rightmost node in a subtree (the node with the largest key in a BST).
* @remarks Time O(H), where H is the height of the right spine. O(N) worst-case. Space O(H) for recursive/trampoline stack.
*
* @template C - The type of the callback function.
* @param [callback=this._DEFAULT_NODE_CALLBACK] - A function to call on the rightmost node.
* @param [startNode=this._root] - The subtree root to search from.
* @param [iterationType=this.iterationType] - The traversal method.
* @returns The callback result for the rightmost node.
*/
getRightMost<C extends NodeCallback<BinaryTreeNode<K, V> | undefined>>(callback?: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>;
/**
* Gets the Morris traversal predecessor (rightmost node in the left subtree, or node itself).
* @remarks This is primarily a helper for Morris traversal. Time O(H), where H is the height of the left subtree. O(N) worst-case. Space O(1).
*
* @param node - The node to find the predecessor for.
* @returns The Morris predecessor.
*/
getPredecessor(node: BinaryTreeNode<K, V>): BinaryTreeNode<K, V>;
/**
* Gets the in-order successor of a node in a BST.
* @remarks Time O(H), where H is the tree height. O(N) worst-case. Space O(H) (due to `getLeftMost` stack).
*
* @param [x] - The node to find the successor of.
* @returns The successor node, or null/undefined if none exists.
*/
getSuccessor(x?: K | BinaryTreeNode<K, V> | null): BinaryTreeNode<K, V> | null | undefined;
dfs<C extends NodeCallback<BinaryTreeNode<K, V>>>(callback?: C, pattern?: DFSOrderPattern, onlyOne?: boolean, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>[];
dfs<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(callback?: C, pattern?: DFSOrderPattern, onlyOne?: boolean, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType, includeNull?: boolean): ReturnType<C>[];
bfs<C extends NodeCallback<BinaryTreeNode<K, V>>>(callback?: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType, includeNull?: false): ReturnType<C>[];
bfs<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(callback?: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType, includeNull?: true): ReturnType<C>[];
/**
* Finds all leaf nodes in the tree.
* @remarks Time O(N), visits every node. Space O(H) for recursive stack or O(N) for iterative queue.
*
* @template C - The type of the callback function.
* @param [callback=this._DEFAULT_NODE_CALLBACK] - Function to call on each leaf node.
* @param [startNode=this._root] - The node to start from.
* @param [iterationType=this.iterationType] - The traversal method.
* @returns An array of callback results.
*/
leaves<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(callback?: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>[];
listLevels<C extends NodeCallback<BinaryTreeNode<K, V>>>(callback?: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType, includeNull?: false): ReturnType<C>[][];
listLevels<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(callback?: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType, includeNull?: true): ReturnType<C>[][];
morris<C extends NodeCallback<BinaryTreeNode<K, V>>>(callback?: C, pattern?: DFSOrderPattern, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): ReturnType<C>[];
/**
* Clones the tree.
* @remarks Time O(N * M), where N is the number of nodes and M is the tree size during insertion (due to `bfs` + `add`, and `add` is O(M)). Space O(N) for the new tree and the BFS queue.
*
* @returns A new, cloned instance of the tree.
*/
clone(): this;
/**
* Creates a new tree containing only the entries that satisfy the predicate.
* @remarks Time O(N * M), where N is nodes in this tree, and M is size of the new tree during insertion (O(N) iteration + O(M) `add` for each item). Space O(N) for the new tree.
*
* @param predicate - A function to test each [key, value] pair.
* @param [thisArg] - `this` context for the predicate.
* @returns A new, filtered tree.
*/
filter(predicate: EntryCallback<K, V | undefined, boolean>, thisArg?: unknown): this;
/**
* Creates a new tree by mapping each [key, value] pair to a new entry.
* @remarks Time O(N * M), where N is nodes in this tree, and M is size of the new tree during insertion. Space O(N) for the new tree.
*
* @template MK - New key type.
* @template MV - New value type.
* @template MR - New raw type.
* @param cb - A function to map each [key, value] pair.
* @param [options] - Options for the new tree.
* @param [thisArg] - `this` context for the callback.
* @returns A new, mapped tree.
*/
map<MK = K, MV = V, MR extends object = object>(cb: EntryCallback<K, V | undefined, [MK, MV]>, options?: Partial<BinaryTreeOptions<MK, MV, MR>>, thisArg?: unknown): BinaryTree<MK, MV, MR>;
/**
* Generates a string representation of the tree for visualization.
* @remarks Time O(N), visits every node. Space O(N*H) or O(N^2) in the worst case, as the string width can grow significantly.
*
* @param [startNode=this._root] - The node to start printing from.
* @param [options] - Options to control the output (e.g., show nulls).
* @returns The string representation of the tree.
*/
toVisual(startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, options?: BinaryTreePrintOptions): string;
/**
* Prints a visual representation of the tree to the console.
* @remarks Time O(N) (via `toVisual`). Space O(N*H) or O(N^2) (via `toVisual`).
*
* @param [options] - Options to control the output.
* @param [startNode=this._root] - The node to start printing from.
*/
print(options?: BinaryTreePrintOptions, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): void;
protected _dfs<C extends NodeCallback<BinaryTreeNode<K, V>>>(callback: C, pattern?: DFSOrderPattern, onlyOne?: boolean, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType, includeNull?: boolean, shouldVisitLeft?: (node: BinaryTreeNode<K, V> | null | undefined) => boolean, shouldVisitRight?: (node: BinaryTreeNode<K, V> | null | undefined) => boolean, shouldVisitRoot?: (node: BinaryTreeNode<K, V> | null | undefined) => boolean, shouldProcessRoot?: (node: BinaryTreeNode<K, V> | null | undefined) => boolean): ReturnType<C>[];
/**
* (Protected) Gets the iterator for the tree (default in-order).
* @remarks Time O(N) for full iteration. O(H) to get the first element. Space O(H) for the iterative stack. O(H) for recursive stack.
*
* @param [node=this._root] - The node to start iteration from.
* @returns An iterator for [key, value] pairs.
*/
protected _getIterator(node?: BinaryTreeNode<K, V> | null | undefined): IterableIterator<[K, V | undefined]>;
/**
* (Protected) Default callback function, returns the node's key.
* @remarks Time O(1)
*
* @param node - The node.
* @returns The node's key or undefined.
*/
protected _DEFAULT_NODE_CALLBACK: (node: BinaryTreeNode<K, V> | null | undefined) => K | undefined;
/**
* (Protected) Snapshots the current tree's configuration options.
* @remarks Time O(1)
*
* @template TK, TV, TR - Generic types for the options.
* @returns The options object.
*/
protected _snapshotOptions<TK = K, TV = V, TR extends object = R>(): BinaryTreeOptions<TK, TV, TR>;
/**
* (Protected) Creates a new, empty instance of the same tree constructor.
* @remarks Time O(1)
*
* @template TK, TV, TR - Generic types for the new instance.
* @param [options] - Options for the new tree.
* @returns A new, empty tree.
*/
protected _createInstance<TK = K, TV = V, TR extends object = R>(options?: Partial<BinaryTreeOptions<TK, TV, TR>>): this;
/**
* (Protected) Creates a new instance of the same tree constructor, potentially with different generic types.
* @remarks Time O(N) (or as per constructor) due to processing the iterable.
*
* @template TK, TV, TR - Generic types for the new instance.
* @param [iter=[]] - An iterable to populate the new tree.
* @param [options] - Options for the new tree.
* @returns A new tree.
*/
protected _createLike<TK = K, TV = V, TR extends object = R>(iter?: Iterable<TK | BinaryTreeNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR>, options?: Partial<BinaryTreeOptions<TK, TV, TR>>): BinaryTree<TK, TV, TR>;
/**
* (Protected) Converts a key, node, or entry into a standardized [node, value] tuple.
* @remarks Time O(1)
*
* @param keyNodeOrEntry - The input item.
* @param [value] - An optional value (used if input is just a key).
* @returns A tuple of [node, value].
*/
protected _keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, value?: V): [BinaryTreeNode<K, V> | null | undefined, V | undefined];
/**
* (Protected) Helper for cloning. Performs a BFS and adds all nodes to the new tree.
* @remarks Time O(N * M) (O(N) BFS + O(M) `add` for each node).
*
* @param cloned - The new, empty tree instance to populate.
*/
protected _clone(cloned: BinaryTree<K, V, R>): void;
/**
* (Protected) Recursive helper for `toVisual`.
* @remarks Time O(N), Space O(N*H) or O(N^2)
*
* @param node - The current node.
* @param options - Print options.
* @returns Layout information for this subtree.
*/
protected _displayAux(node: BinaryTreeNode<K, V> | null | undefined, options: BinaryTreePrintOptions): NodeDisplayLayout;
/**
* (Protected) Swaps the key/value properties of two nodes.
* @remarks Time O(1)
*
* @param srcNode - The source node.
* @param destNode - The destination node.
* @returns The `destNode` (now holding `srcNode`'s properties).
*/
protected _swapProperties(srcNode: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, destNode: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): BinaryTreeNode<K, V> | undefined;
/**
* (Protected) Replaces a node in the tree with a new node, maintaining children and parent links.
* @remarks Time O(1)
*
* @param oldNode - The node to be replaced.
* @param newNode - The node to insert.
* @returns The `newNode`.
*/
protected _replaceNode(oldNode: BinaryTreeNode<K, V>, newNode: BinaryTreeNode<K, V>): BinaryTreeNode<K, V>;
/**
* (Protected) Sets the root node and clears its parent reference.
* @remarks Time O(1)
*
* @param v - The node to set as root.
*/
protected _setRoot(v: BinaryTreeNode<K, V> | null | undefined): void;
/**
* (Protected) Converts a key, node, entry, or predicate into a standardized predicate function.
* @remarks Time O(1)
*
* @param keyNodeEntryOrPredicate - The item to convert.
* @returns A predicate function.
*/
protected _ensurePredicate(keyNodeEntryOrPredicate: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V>>): NodePredicate<BinaryTreeNode<K, V>>;
/**
* (Protected) Checks if an item is a predicate function.
* @remarks Time O(1)
*
* @param p - The item to check.
* @returns True if it's a function.
*/
protected _isPredicate(p: any): p is NodePredicate<BinaryTreeNode<K, V>>;
/**
* (Protected) Extracts the key from a key, node, or entry.
* @remarks Time O(1)
*
* @param keyNodeOrEntry - The item.
* @returns The extracted key.
*/
protected _extractKey(keyNodeOrEntry: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): K | null | undefined;
/**
* (Protected) Sets a value in the external store (Map mode).
* @remarks Time O(1) (average for Map.set).
*
* @param key - The key.
* @param value - The value.
* @returns True if successful.
*/
protected _setValue(key: K | null | undefined, value: V | undefined): false | Map<K, V | undefined>;
/**
* (Protected) Clears all nodes from the tree.
* @remarks Time O(1)
*/
protected _clearNodes(): void;
/**
* (Protected) Clears all values from the external store.
* @remarks Time O(N)
*/
protected _clearValues(): void;
}