/**
 * data-structure-typed
 *
 * @author Pablo Zeng
 * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
 * @license MIT License
 */
import type { BinaryTreeDeleteResult, BinaryTreeOptions, BinaryTreePrintOptions, BTNEntry, BTNRep, 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 `set` 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 = any> 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) `set` operation). Space O(N) for storing the nodes.
     *
     * @param [keysNodesEntriesOrRaws=[]] - An iterable of items to set.
     * @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 readonly _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 readonly _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, BinaryTreeNode<K, V>>;
    /**
     * Gets the external value store (used in Map mode).
     * @remarks Time O(1)
     *
     * @returns The map storing key-value pairs.
     */
    get store(): Map<K, BinaryTreeNode<K, V>>;
    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 readonly _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 readonly _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: unknown): key is K;
    /**
     * Adds a new node to the tree.
     * @remarks Time O(N) — level-order traversal to find an empty slot. Space O(N) for the BFS queue. BST/Red-Black Tree/AVL Tree subclasses override to O(log N).
     *
     * @param keyNodeOrEntry - The key, node, or entry to add.
     * @returns True if the addition was successful, false otherwise.
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Add a single node
   *  const tree = new BinaryTree<number>();
   *     tree.add(1);
   *     tree.add(2);
   *     tree.add(3);
   *     console.log(tree.size); // 3;
   *     console.log(tree.has(1)); // true;
     */
    add(keyNodeOrEntry: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): boolean;
    /**
     * Adds or updates a new node to the tree.
     * @remarks Time O(N) — level-order traversal to find an empty slot. Space O(N) for the BFS queue. BST/Red-Black Tree/AVL Tree subclasses override to O(log N).
     *
     * @param keyNodeOrEntry - The key, node, or entry to set or update.
     * @param [value] - The value, if providing just a key.
     * @returns True if the addition was successful, false otherwise.
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // basic BinaryTree creation and insertion
   *  // Create a BinaryTree with entries
   *     const entries: [number, string][] = [
   *       [6, 'six'],
   *       [1, 'one'],
   *       [2, 'two'],
   *       [7, 'seven'],
   *       [5, 'five'],
   *       [3, 'three'],
   *       [4, 'four'],
   *       [9, 'nine'],
   *       [8, 'eight']
   *     ];
   *
   *     const tree = new BinaryTree(entries);
   *
   *     // Verify size
   *     console.log(tree.size); // 9;
   *
   *     // Add new element
   *     tree.set(10, 'ten');
   *     console.log(tree.size); // 10;
     */
    set(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 set and M is the size of the tree at insertion (due to O(M) `set` operation). Space O(M) (from `set`) + O(N) (for the `inserted` array).
     *
     * @param keysNodesEntriesOrRaws - An iterable of items to set.
     * @returns An array of booleans indicating the success of each individual `set` operation.
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Bulk add
   *  const tree = new BinaryTree<number>();
   *     tree.addMany([1, 2, 3, 4, 5]);
   *     console.log(tree.size); // 5;
     */
    addMany(keysNodesEntriesOrRaws: Iterable<K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | R>): boolean[];
    /**
     * Adds or updates multiple items to the tree.
     * @remarks Time O(N * M), where N is the number of items to set and M is the size of the tree at insertion (due to O(M) `set` operation). Space O(M) (from `set`) + O(N) (for the `inserted` array).
     *
     * @param keysNodesEntriesOrRaws - An iterable of items to set or update.
     * @param [values] - An optional parallel iterable of values.
     * @returns An array of booleans indicating the success of each individual `set` operation.
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Set multiple entries
   *  const tree = new BinaryTree<number, string>();
   *     tree.setMany([[1, 'a'], [2, 'b'], [3, 'c']]);
   *     console.log(tree.size); // 3;
     */
    setMany(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 seting all its nodes.
     * @remarks Time O(N * M), same as `setMany`, where N is the size of `anotherTree` and M is the size of this tree. Space O(M) (from `set`).
     *
     * @param anotherTree - The tree to merge.
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Combine trees
   *  const t1 = new BinaryTree<number>([1, 2]);
   *     const t2 = new BinaryTree<number>([3, 4]);
   *     t1.merge(t2);
   *     console.log(t1.size); // 4;
     */
    merge(anotherTree: BinaryTree<K, V, R>): void;
    /**
     * Deletes a node from the tree (internal, returns balancing metadata).
     * @remarks Time O(N) — O(N) to find the node + O(H) for predecessor swap. Space O(1). BST/Red-Black Tree/AVL Tree subclasses override to O(log N).
     * @internal Used by AVL/BST subclasses that need balancing metadata after deletion.
     *
     * @param keyNodeEntryRawOrPredicate - The node to delete.
     * @returns An array containing deletion results with balancing metadata.
     */
    protected _deleteInternal(keyNodeEntryRawOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V> | null>): BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[];
    /**
     * Deletes a node from the tree.
     * @remarks Time O(N) — O(N) to find the node + O(H) for predecessor swap. Space O(1). BST/Red-Black Tree/AVL Tree subclasses override to O(log N).
     *
     * @param keyNodeEntryRawOrPredicate - The node to delete.
     * @returns True if the node was found and deleted, false otherwise.
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Remove a node
   *  const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
   *     tree.delete(3);
   *     console.log(tree.has(3)); // false;
   *     console.log(tree.size); // 4;
     */
    delete(keyNodeEntryRawOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V> | null>): boolean;
    /**
   * Search by predicate
  
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
    * @example
 * // Search by predicate
 *  const tree = new BinaryTree<number>([5, 3, 7, 1, 9]);
 *     const found = tree.search(n => n!.key > 5, true);
 *     console.log(found.length); // >= 1;
   */
    search(keyNodeEntryOrPredicate: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V> | null>, onlyOne?: boolean): (K | undefined)[];
    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.
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Get nodes by condition
   *  const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
   *     const nodes = tree.getNodes(node => node.key > 3);
   *     console.log(nodes.length); // 2;
     */
    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(N) via `search`. Space O(H) or O(N). BST/Red-Black Tree/AVL Tree subclasses override to O(log N) for key lookups.
     *
     * @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.
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Get node by key
   *  const tree = new BinaryTree<number, string>([[1, 'root'], [2, 'child']]);
   *     console.log(tree.getNode(2)?.value); // 'child';
     */
    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(1) in Map mode, O(N) otherwise (via `getNode`). Space O(1) in Map mode, O(H) or O(N) otherwise. BST subclasses override non-Map-mode to O(log N).
     *
     * @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.
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Retrieve value by key
   *  const tree = new BinaryTree<number, string>([[1, 'root'], [2, 'left'], [3, 'right']]);
   *     console.log(tree.get(2)); // 'left';
   *     console.log(tree.get(99)); // 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(N) via `search`. Space O(H) or O(N). BST/Red-Black Tree/AVL Tree subclasses override to O(log N) for key lookups.
     *
     * @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.
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // BinaryTree get and has operations
   *  const tree = new BinaryTree(
   *       [
   *         [5, 'five'],
   *         [3, 'three'],
   *         [7, 'seven'],
   *         [1, 'one'],
   *         [4, 'four'],
   *         [6, 'six'],
   *         [8, 'eight']
   *       ],
   *       { isMapMode: false }
   *     );
   *
   *     // Check if key exists
   *     console.log(tree.has(5)); // true;
   *     console.log(tree.has(10)); // false;
   *
   *     // Get value by key
   *     console.log(tree.get(3)); // 'three';
   *     console.log(tree.get(7)); // 'seven';
   *     console.log(tree.get(100)); // undefined;
   *
   *     // Get node structure
   *     const node = tree.getNode(5);
   *     console.log(node?.key); // 5;
   *     console.log(node?.value); // 'five';
     */
    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)
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Remove all nodes
   *  const tree = new BinaryTree<number>([1, 2, 3]);
   *     tree.clear();
   *     console.log(tree.isEmpty()); // true;
     */
    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.
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Check empty
   *  console.log(new BinaryTree().isEmpty()); // true;
     */
    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.
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Check BST property
   *  const tree = new BinaryTree<number>([1, 2, 3]);
   *     // BinaryTree doesn't guarantee BST order
   *     console.log(typeof tree.isBST()); // 'boolean';
     */
    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`).
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Get depth of a node
   *  const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
   *     const node = tree.getNode(4);
   *     console.log(tree.getDepth(node!)); // 2;
     */
    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).
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Get tree height
   *  const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
   *     console.log(tree.getHeight()); // 2;
     */
    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;
    getPathToRoot(beginNode: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): (K | undefined)[];
    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>[];
    getLeftMost(): K | undefined;
    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>;
    getRightMost(): K | undefined;
    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;
    /**
   * Depth-first search traversal
  
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
    * @example
 * // Depth-first search traversal
 *  const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
 *     const inOrder = tree.dfs(node => node.key, 'IN');
 *     console.log(inOrder); // [4, 2, 5, 1, 3];
   */
    dfs(): (K | 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>[];
    /**
   * BinaryTree level-order traversal
  
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
    * @example
 * // BinaryTree level-order traversal
 *  const tree = new BinaryTree([
 *       [1, 'one'],
 *       [2, 'two'],
 *       [3, 'three'],
 *       [4, 'four'],
 *       [5, 'five'],
 *       [6, 'six'],
 *       [7, 'seven']
 *     ]);
 *
 *     // Binary tree maintains level-order insertion
 *     // Complete binary tree structure
 *     console.log(tree.size); // 7;
 *
 *     // Verify all keys are present
 *     console.log(tree.has(1)); // true;
 *     console.log(tree.has(4)); // true;
 *     console.log(tree.has(7)); // true;
 *
 *     // Iterate through tree
 *     const keys: number[] = [];
 *     for (const [key] of tree) {
 *       keys.push(key);
 *     }
 *     console.log(keys.length); // 7;
   */
    bfs(): (K | undefined)[];
    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>[];
    /**
   * Get leaf nodes
  
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
    * @example
 * // Get leaf nodes
 *  const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
 *     const leafKeys = tree.leaves(node => node.key);
 *     console.log(leafKeys.length); // > 0;
   */
    leaves(): (K | undefined)[];
    leaves<C extends NodeCallback<BinaryTreeNode<K, V>>>(callback: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>[];
    /**
   * Level-order grouping
  
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
    * @example
 * // Level-order grouping
 *  const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
 *     const levels = tree.listLevels(node => node.key);
 *     console.log(levels[0]); // [1];
 *     console.log(levels[1].sort()); // [2, 3];
   */
    listLevels(): (K | undefined)[][];
    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 traversal (O(1) space)
  
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
    * @example
 * // Morris traversal (O(1) space)
 *  const tree = new BinaryTree<number>([1, 2, 3]);
 *     const result = tree.morris(node => node.key, 'IN');
 *     console.log(result.length); // 3;
   */
    morris(): (K | undefined)[];
    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` + `set`, and `set` is O(M)). Space O(N) for the new tree and the BFS queue.
     *
     * @returns A new, cloned instance of the tree.
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Deep copy
   *  const tree = new BinaryTree<number>([1, 2, 3]);
   *     const copy = tree.clone();
   *     copy.delete(1);
   *     console.log(tree.has(1)); // true;
     */
    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) `set` 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.
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Filter nodes by condition
   *  const tree = new BinaryTree<number>([1, 2, 3, 4]);
   *     const result = tree.filter((_, key) => key > 2);
   *     console.log(result.size); // 2;
     */
    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.
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Transform to new tree
   *  const tree = new BinaryTree<number, number>([[1, 10], [2, 20]]);
   *     const mapped = tree.map((v, key) => [key, (v ?? 0) + 1] as [number, number]);
   *     console.log([...mapped.values()]); // contains 11;
     */
    map<MK = K, MV = V, MR = any>(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.
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      * @example
   * // Display tree
   *  const tree = new BinaryTree<number>([1, 2, 3]);
   *     expect(() => tree.print()).not.toThrow();
     */
    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 readonly _DEFAULT_NODE_CALLBACK: NodeCallback<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 = 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 = 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 = 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 sets all nodes to the new tree.
     * @remarks Time O(N * M) (O(N) BFS + O(M) `set` 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 static _buildNodeDisplay(line: string, width: number, left: NodeDisplayLayout, right: NodeDisplayLayout): NodeDisplayLayout;
    /**
     * Check if a node is a display leaf (empty, null, undefined, NIL, or real leaf).
     */
    protected _isDisplayLeaf(node: BinaryTreeNode<K, V> | null | undefined, options: BinaryTreePrintOptions): boolean;
    protected _hasDisplayableChild(child: BinaryTreeNode<K, V> | null | undefined, options: BinaryTreePrintOptions): boolean;
    /**
     * Resolve a display leaf node to its layout.
     */
    protected _resolveDisplayLeaf(node: BinaryTreeNode<K, V> | null | undefined, options: BinaryTreePrintOptions, emptyDisplayLayout: NodeDisplayLayout): 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: unknown): 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): boolean;
    /**
     * (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;
}
