UNPKG

doubly-linked-list-typed

Version:
462 lines (461 loc) 29.6 kB
/** * data-structure-typed * * @author Pablo Zeng * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com> * @license MIT License */ import type { BSTNOptKeyOrNode, BSTOptions, BTNRep, Comparable, Comparator, CP, DFSOrderPattern, EntryCallback, IterationType, NodeCallback, NodePredicate, OptNode } from '../../types'; import { BinaryTree, BinaryTreeNode } from './binary-tree'; import { IBinaryTree } from '../../interfaces'; import { Range } from '../../common'; export declare class BSTNode<K = any, V = any> extends BinaryTreeNode<K, V> { parent?: BSTNode<K, V>; /** * This TypeScript constructor function initializes an instance with a key and an optional value. * @param {K} key - The `key` parameter is typically used to uniquely identify an object or element * within a data structure. It serves as a reference or identifier for accessing or manipulating the * associated value. * @param {V} [value] - The `value` parameter in the constructor is optional, meaning it does not * have to be provided when creating an instance of the class. If a value is not provided, it will * default to `undefined`. */ constructor(key: K, value?: V); _left?: BSTNode<K, V> | null | undefined; get left(): BSTNode<K, V> | null | undefined; set left(v: BSTNode<K, V> | null | undefined); _right?: BSTNode<K, V> | null | undefined; get right(): BSTNode<K, V> | null | undefined; set right(v: BSTNode<K, V> | null | undefined); } /** * 1. Node Order: Each node's left child has a lesser value, and the right child has a greater value. * 2. Unique Keys: No duplicate keys in a standard BST. * 3. Efficient Search: Enables quick search, minimum, and maximum operations. * 4. Inorder Traversal: Yields nodes in ascending order. * 5. Logarithmic Operations: Ideal operations like insertion, deletion, and searching are O(log n) time-efficient. * 6. Balance Variability: Can become unbalanced; special types maintain balance. * 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves. * @example * // Merge 3 sorted datasets * const dataset1 = new BST<number, string>([ * [1, 'A'], * [7, 'G'] * ]); * const dataset2 = [ * [2, 'B'], * [6, 'F'] * ]; * const dataset3 = new BST<number, string>([ * [3, 'C'], * [5, 'E'], * [4, 'D'] * ]); * * // Merge datasets into a single BinarySearchTree * const merged = new BST<number, string>(dataset1); * merged.addMany(dataset2); * merged.merge(dataset3); * * // Verify merged dataset is in sorted order * console.log([...merged.values()]); // ['A', 'B', 'C', 'D', 'E', 'F', 'G'] * @example * // Find elements in a range * const bst = new BST<number>([10, 5, 15, 3, 7, 12, 18]); * console.log(bst.search(new Range(5, 10))); // [5, 7, 10] * console.log(bst.rangeSearch([4, 12], node => node.key.toString())); // ['5', '7', '10', '12'] * console.log(bst.search(new Range(4, 12, true, false))); // [5, 7, 10] * console.log(bst.rangeSearch([15, 20])); // [15, 18] * console.log(bst.search(new Range(15, 20, false))); // [18] * @example * // Find lowest common ancestor * const bst = new BST<number>([20, 10, 30, 5, 15, 25, 35, 3, 7, 12, 18]); * * // LCA helper function * const findLCA = (num1: number, num2: number): number | undefined => { * const path1 = bst.getPathToRoot(num1); * const path2 = bst.getPathToRoot(num2); * // Find the first common ancestor * return findFirstCommon(path1, path2); * }; * * function findFirstCommon(arr1: number[], arr2: number[]): number | undefined { * for (const num of arr1) { * if (arr2.indexOf(num) !== -1) { * return num; * } * } * return undefined; * } * * // Assertions * console.log(findLCA(3, 10)); // 7 * console.log(findLCA(5, 35)); // 15 * console.log(findLCA(20, 30)); // 25 */ export declare class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object> extends BinaryTree<K, V, R, MK, MV, MR> implements IBinaryTree<K, V, R, MK, MV, MR> { /** * This TypeScript constructor initializes a binary search tree with optional options and adds * elements if provided. * @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the constructor is an * iterable that can contain elements of type `K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined ` or `R`. It is used to * initialize the binary search tree with keys, nodes, entries, or raw data. * @param [options] - The `options` parameter is an optional object that can contain the following * properties: */ constructor(keysNodesEntriesOrRaws?: Iterable<K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | R>, options?: BSTOptions<K, V, R>); protected _root?: BSTNode<K, V>; get root(): OptNode<BSTNode<K, V>>; protected _isReverse: boolean; get isReverse(): boolean; protected _comparator: Comparator<K>; get comparator(): Comparator<K>; protected _specifyComparable?: (key: K) => Comparable; get specifyComparable(): ((key: K) => Comparable) | undefined; /** * Time Complexity: O(1) * Space Complexity: O(1) * * The function creates a new BSTNode with the given key and value and returns it. * @param {K} key - The key parameter is of type K, which represents the type of the key for the node * being created. * @param {V} [value] - The "value" parameter is an optional parameter of type V. It represents the * value associated with the key in the node being created. * @returns The method is returning a new instance of the BSTNode class, casted as the BSTNode<K, V> type. */ createNode(key: K, value?: V): BSTNode<K, V>; /** * Time Complexity: O(1) * Space Complexity: O(1) * * The function creates a new binary search tree with the specified options. * @param [options] - The `options` parameter is an optional object that allows you to customize the * behavior of the `createTree` method. It accepts a partial `BSTOptions` object, which has the * following properties: * @returns a new instance of the BST class with the provided options. */ createTree(options?: BSTOptions<K, V, R>): BST<K, V, R, MK, MV, MR>; /** * Time Complexity: O(log n) * Space Complexity: O(log n) * * The function ensures the existence of a node in a data structure and returns it, or undefined if * it doesn't exist. * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The parameter * `keyNodeOrEntry` can accept a value of type `R`, which represents the key, node, * entry, or raw element that needs to be ensured in the tree. * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional * parameter that specifies the type of iteration to be used when ensuring a node. It has a default * value of `'ITERATIVE'`. * @returns The method is returning either the node that was ensured or `undefined` if the node could * not be ensured. */ ensureNode(keyNodeOrEntry: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): OptNode<BSTNode<K, V>>; /** * Time Complexity: O(1) * Space Complexity: O(1) * * The function checks if the input is an instance of the BSTNode class. * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The parameter * `keyNodeOrEntry` can be of type `R` or `K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined `. * @returns a boolean value indicating whether the input parameter `keyNodeOrEntry` is * an instance of the `BSTNode` class. */ isNode(keyNodeOrEntry: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): keyNodeOrEntry is BSTNode<K, V>; /** * Time Complexity: O(1) * Space Complexity: O(1) * * The function "override isValidKey" checks if a key is comparable based on a given comparator. * @param {any} key - The `key` parameter is a value that will be checked to determine if it is of * type `K`. * @returns The `override isValidKey(key: any): key is K` function is returning a boolean value based on * the result of the `isComparable` function with the condition `this._compare !== * this._DEFAULT_COMPARATOR`. */ isValidKey(key: any): key is K; /** * Time Complexity: O(log n) * Space Complexity: O(log n) * * The `add` function in TypeScript adds a new node to a binary search tree based on the key value. * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The parameter * `keyNodeOrEntry` can accept a value of type `R` or `K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined `. * @param {V} [value] - The `value` parameter is an optional value that can be associated with the * key in the binary search tree. If provided, it will be stored in the node along with the key. * @returns a boolean value. */ add(keyNodeOrEntry: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, value?: V): boolean; /** * Time Complexity: O(k log n) * Space Complexity: O(k + log n) * * The `addMany` function in TypeScript adds multiple keys or nodes to a data structure and returns * an array indicating whether each key or node was successfully inserted. * @param keysNodesEntriesOrRaws - An iterable containing keys, nodes, entries, or raw * elements to be added to the data structure. * @param [values] - An optional iterable of values to be associated with the keys or nodes being * added. If provided, the values will be assigned to the corresponding keys or nodes in the same * order. If not provided, undefined will be assigned as the value for each key or node. * @param [isBalanceAdd=true] - A boolean flag indicating whether the tree should be balanced after * adding the elements. If set to true, the tree will be balanced using a binary search tree * algorithm. If set to false, the elements will be added without balancing the tree. The default * value is true. * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that * specifies the type of iteration to use when adding multiple keys or nodes to the binary search * tree. It can have two possible values: * @returns The function `addMany` returns an array of booleans indicating whether each element was * successfully inserted into the data structure. */ addMany(keysNodesEntriesOrRaws: Iterable<R | BTNRep<K, V, BSTNode<K, V>>>, values?: Iterable<V | undefined>, isBalanceAdd?: boolean, iterationType?: IterationType): boolean[]; /** * Time Complexity: O(log n) * Space Complexity: O(k + log n) * * The function `search` in TypeScript overrides the search behavior in a binary tree structure based * on specified criteria. * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BSTNode<K, V>>} keyNodeEntryOrPredicate - The * `keyNodeEntryOrPredicate` parameter in the `override search` method can accept one of the * following types: * @param [onlyOne=false] - The `onlyOne` parameter is a boolean flag that determines whether the * search should stop after finding the first matching node. If `onlyOne` is set to `true`, the * search will return as soon as a matching node is found. If `onlyOne` is set to `false`, the * @param {C} callback - The `callback` parameter in the `override search` function is a function * that will be called on each node that matches the search criteria. It is of type `C`, which * extends `NodeCallback<BSTNode<K, V> | null>`. The callback function should accept a node of type `BSTNode<K, V>` as its * argument and * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the `override search` * method represents the node from which the search operation will begin. It is the starting point * for searching within the tree data structure. The method ensures that the `startNode` is a valid * node before proceeding with the search operation. If the ` * @param {IterationType} iterationType - The `iterationType` parameter in the `override search` * function determines the type of iteration to be used during the search operation. It can have two * possible values: * @returns The `override search` method returns an array of values that match the search criteria * specified by the input parameters. The method performs a search operation on a binary tree * structure based on the provided key, predicate, and other options. The search results are * collected in an array and returned as the output of the method. */ search<C extends NodeCallback<BSTNode<K, V>>>(keyNodeEntryOrPredicate: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BSTNode<K, V>> | Range<K>, onlyOne?: boolean, callback?: C, startNode?: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>[]; /** * Time Complexity: O(log n) * Space Complexity: O(k + log n) * * The `rangeSearch` function searches for nodes within a specified range in a binary search tree. * @param {Range<K> | [K, K]} range - The `range` parameter in the `rangeSearch` function can be * either a `Range` object or an array of two elements representing the range boundaries. * @param {C} callback - The `callback` parameter in the `rangeSearch` function is a callback * function that is used to process each node that is found within the specified range during the * search operation. It is of type `NodeCallback<BSTNode<K, V> | null>`, where `BSTNode<K, V>` is the type of nodes in the * data structure. * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter in the `rangeSearch` * function represents the node from which the search for nodes within the specified range will * begin. It is the starting point for the range search operation. * @param {IterationType} iterationType - The `iterationType` parameter in the `rangeSearch` function * is used to specify the type of iteration to be performed during the search operation. It has a * default value of `this.iterationType`, which suggests that it is likely a property of the class or * object that the `rangeSearch` * @returns The `rangeSearch` function is returning the result of calling the `search` method with * the specified parameters. */ rangeSearch<C extends NodeCallback<BSTNode<K, V>>>(range: Range<K> | [K, K], callback?: C, startNode?: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>[]; /** * Time Complexity: O(log n) * Space Complexity: O(log n) * * This function retrieves a node based on a given keyNodeEntryOrPredicate within a binary search tree structure. * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BSTNode<K, V>>} keyNodeEntryOrPredicate - The `keyNodeEntryOrPredicate` * parameter can be of type `K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined `, `R`, or `NodePredicate<BSTNode<K, V>>`. * @param {BSTNOptKeyOrNode<K, BSTNode<K, V>>} startNode - The `startNode` parameter in the `getNode` method * is used to specify the starting point for searching nodes in the binary search tree. If no * specific starting point is provided, the default value is set to `this._root`, which is the root * node of the binary search tree. * @param {IterationType} iterationType - The `iterationType` parameter in the `getNode` method is a * parameter that specifies the type of iteration to be used. It has a default value of * `this.iterationType`, which means it will use the iteration type defined in the class instance if * no value is provided when calling the method. * @returns The `getNode` method is returning an optional binary search tree node (`OptNode<BSTNode<K, V>>`). * It is using the `getNodes` method to find the node based on the provided keyNodeEntryOrPredicate, beginning at * the specified root node (`startNode`) and using the specified iteration type. The method then * returns the first node found or `undefined` if no node is found. */ getNode(keyNodeEntryOrPredicate: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BSTNode<K, V>>, startNode?: BSTNOptKeyOrNode<K, BSTNode<K, V>>, iterationType?: IterationType): OptNode<BSTNode<K, V>>; /** * Time complexity: O(n) * Space complexity: O(n) * * The function `dfs` in TypeScript overrides the base class method with default parameters and * returns the result of the super class `dfs` method. * @param {C} callback - The `callback` parameter is a function that will be called for each node * visited during the Depth-First Search traversal. It is a generic type `C` that extends the * `NodeCallback` interface for `BSTNode<K, V>`. The default value for `callback` is `this._ * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `override dfs` method * specifies the order in which the Depth-First Search (DFS) traversal should be performed on the * Binary Search Tree (BST). The possible values for the `pattern` parameter are: * @param {boolean} [onlyOne=false] - The `onlyOne` parameter in the `override dfs` method is a * boolean flag that indicates whether you want to stop the depth-first search traversal after * finding the first matching node or continue searching for all matching nodes. If `onlyOne` is set * to `true`, the traversal will stop after finding * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined} startNode - * The `startNode` parameter in the `override dfs` method can be one of the following types: * @param {IterationType} iterationType - The `iterationType` parameter in the `override dfs` method * specifies the type of iteration to be performed during the Depth-First Search (DFS) traversal of a * Binary Search Tree (BST). It is used to determine the order in which nodes are visited during the * traversal. The possible values for ` * @returns The `override` function is returning the result of calling the `dfs` method from the * superclass, with the provided arguments `callback`, `pattern`, `onlyOne`, `startNode`, and * `iterationType`. The return type is an array of the return type of the callback function `C`. */ dfs<C extends NodeCallback<BSTNode<K, V>>>(callback?: C, pattern?: DFSOrderPattern, onlyOne?: boolean, startNode?: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>[]; /** * Time complexity: O(n) * Space complexity: O(n) * * The function overrides the breadth-first search method and returns an array of the return types of * the callback function. * @param {C} callback - The `callback` parameter is a function that will be called for each node * visited during the breadth-first search. It should take a single argument, which is the current * node being visited, and it can return a value of any type. * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter is the starting * point for the breadth-first search. It can be either a root node, a key-value pair, or an entry * object. If no value is provided, the default value is the root of the tree. * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type * of iteration to be performed during the breadth-first search (BFS) traversal. It can have one of * the following values: * @returns an array of the return type of the callback function. */ bfs<C extends NodeCallback<BSTNode<K, V>>>(callback?: C, startNode?: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>[]; /** * Time complexity: O(n) * Space complexity: O(n) * * The function overrides the listLevels method from the superclass and returns an array of arrays * containing the results of the callback function applied to each level of the tree. * @param {C} callback - The `callback` parameter is a generic type `C` that extends * `NodeCallback<BSTNode<K, V> | null>`. It represents a callback function that will be called for each node in the * tree during the iteration process. * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } startNode - The `startNode` parameter is the starting * point for listing the levels of the binary tree. It can be either a root node of the tree, a * key-value pair representing a node in the tree, or a key representing a node in the tree. If no * value is provided, the root of * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type * of iteration to be performed on the tree. It can have one of the following values: * @returns The method is returning a two-dimensional array of the return type of the callback * function. */ listLevels<C extends NodeCallback<BSTNode<K, V>>>(callback?: C, startNode?: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>[][]; /** * Time complexity: O(n) * Space complexity: O(n) * * The `lesserOrGreaterTraverse` function traverses a binary tree and applies a callback function to * each node that meets a certain condition based on a target node and a comparison value. * @param {C} callback - The `callback` parameter is a function that will be called for each node * that meets the condition specified by the `lesserOrGreater` parameter. It takes a single argument, * which is the current node being traversed, and returns a value of any type. * @param {CP} lesserOrGreater - The `lesserOrGreater` parameter is used to determine whether to * traverse nodes that are lesser, greater, or both than the `targetNode`. It accepts the values -1, * 0, or 1, where: * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } targetNode - The `targetNode` parameter is the node in * the binary tree that you want to start traversing from. It can be specified either by providing * the key of the node, the node itself, or an entry containing the key and value of the node. If no * `targetNode` is provided, * @param {IterationType} iterationType - The `iterationType` parameter determines the type of * traversal to be performed on the binary tree. It can have two possible values: * @returns The function `lesserOrGreaterTraverse` returns an array of values of type * `ReturnType<C>`, which is the return type of the callback function passed as an argument. */ lesserOrGreaterTraverse<C extends NodeCallback<BSTNode<K, V>>>(callback?: C, lesserOrGreater?: CP, targetNode?: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>[]; /** * Time complexity: O(n) * Space complexity: O(n) * * The `perfectlyBalance` function takes an optional `iterationType` parameter and returns `true` if * the binary search tree is perfectly balanced, otherwise it returns `false`. * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that * specifies the type of iteration to use when building a balanced binary search tree. It has a * default value of `this.iterationType`, which means it will use the iteration type specified in the * current instance of the class. * @returns The function `perfectlyBalance` returns a boolean value. */ perfectlyBalance(iterationType?: IterationType): boolean; /** * Time Complexity: O(n) * Space Complexity: O(log n) * * The function `isAVLBalanced` checks if a binary tree is AVL balanced using either a recursive or * iterative approach. * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that * specifies the type of iteration to use when checking if the AVL tree is balanced. It has a default * value of `this.iterationType`, which means it will use the iteration type specified in the current * instance of the AVL tree. * @returns a boolean value. */ isAVLBalanced(iterationType?: IterationType): boolean; /** * Time complexity: O(n) * Space complexity: O(n) * * The `map` function in TypeScript overrides the default map behavior for a binary search tree by * applying a callback function to each entry and creating a new tree with the results. * @param callback - A function that will be called for each entry in the BST. It takes four * arguments: the key, the value (which can be undefined), the index of the entry, and a reference to * the BST itself. * @param [options] - The `options` parameter in the `override map` method is of type `BSTOptions<MK, * MV, MR>`. It is an optional parameter that allows you to specify additional options for the Binary * Search Tree (BST) being created in the `map` method. These options could include configuration * @param {any} [thisArg] - The `thisArg` parameter in the `override map` method is used to specify * the value of `this` that should be used when executing the `callback` function. It allows you to * set the context or scope in which the callback function will be called. This can be useful when * you want * @returns The `map` method is returning a new Binary Search Tree (`BST`) instance with the entries * transformed by the provided callback function. */ map(callback: EntryCallback<K, V | undefined, [MK, MV]>, options?: BSTOptions<MK, MV, MR>, thisArg?: any): BST<MK, MV, MR>; /** * Time complexity: O(n) * Space complexity: O(n) * * The function `clone` overrides the default cloning behavior to create a deep copy of a tree * structure. * @returns The `cloned` object is being returned. */ clone(): BST<K, V, R, MK, MV, MR>; /** * Time Complexity: O(1) * Space Complexity: O(1) * * The function overrides a method and converts a key, value pair or entry or raw element to a node. * @param {K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - A variable that can be of * type R or K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined . It represents either a key, a node, an entry, or a raw * element. * @param {V} [value] - The `value` parameter is an optional value of type `V`. It represents the * value associated with a key in a key-value pair. * @returns either a BSTNode<K, V> object or undefined. */ protected _keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry: K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, value?: V): [OptNode<BSTNode<K, V>>, V | undefined]; /** * Time Complexity: O(1) * Space Complexity: O(1) * * The function sets the root of a tree-like structure and updates the parent property of the new * root. * @param {OptNode<BSTNode<K, V>>} v - v is a parameter of type BSTNode<K, V> or undefined. */ protected _setRoot(v: OptNode<BSTNode<K, V>>): void; /** * Time Complexity: O(1) * Space Complexity: O(1) * * The _compare function compares two values using a specified comparator function and optionally * reverses the result. * @param {K} a - The parameter `a` is of type `K`, which is used as an input for comparison in the * `_compare` method. * @param {K} b - The parameter `b` in the `_compare` function is of type `K`. * @returns The `_compare` method is returning the result of the ternary expression. If `_isReverse` * is true, it returns the negation of the result of calling the `_comparator` function with * arguments `a` and `b`. If `_isReverse` is false, it returns the result of calling the * `_comparator` function with arguments `a` and `b`. */ protected _compare(a: K, b: K): number; }