declare class Node<T = any> {
    parent: Node<T> | null;
    left: Node<T> | null;
    right: Node<T> | null;
    value: T;
    constructor(value: T);
}
export declare class BinarySearchTree<T = any> {
    private _root;
    private _size;
    private readonly comparator;
    constructor(compareFn?: (a: T, b: T) => number);
    get root(): Node<T> | null;
    get size(): number;
    insert(value: T): Node<T>;
    remove(node: Node<T>, root?: Node<T> | null): void;
    removeWithValue(target: T, predicate?: (value: T) => unknown): void;
    contains(node: Node<T>, root?: Node<T> | null): boolean;
    findNode(target: T, predicate?: (value: T) => unknown): Node<T> | undefined;
    find(target: T, predicate?: (value: T) => unknown): T | undefined;
    findMinNode(root?: Node<T> | null): Node<T> | undefined;
    findMin(root?: Node<T> | null): T | undefined;
    findMaxNode(root?: Node<T> | null): Node<T> | undefined;
    findMax(root?: Node<T> | null): T | undefined;
    traverseInOrder(callbackfn: (value: T) => void, node?: Node<T> | null): void;
    traversePreOrder(callbackfn: (value: T) => void, node?: Node<T> | null): void;
    traversePostOrder(callbackfn: (value: T) => void, node?: Node<T> | null): void;
    private removeNodeWithTwoChildren;
    private removeRoot;
    private removeSingleChildOrLeafNode;
}
export {};
