diff --git a/src/data-structures/binary-tree/avl-tree.ts b/src/data-structures/binary-tree/avl-tree.ts index 1464d04..ed4e9b0 100644 --- a/src/data-structures/binary-tree/avl-tree.ts +++ b/src/data-structures/binary-tree/avl-tree.ts @@ -6,8 +6,17 @@ * @license MIT License */ import { BST, BSTNode } from './bst'; -import type { AVLTreeNested, AVLTreeNodeNested, AVLTreeOptions, BiTreeDeleteResult, BTNKey } from '../../types'; -import { BTNCallback, IterableEntriesOrKeys } from '../../types'; +import type { + AVLTreeNested, + AVLTreeNodeNested, + AVLTreeOptions, + BiTreeDeleteResult, + BSTNKeyOrNode, + BTNExemplar, + BTNKey, + BTNKeyOrNode +} from '../../types'; +import { BTNCallback } from '../../types'; import { IBinaryTree } from '../../interfaces'; export class AVLTreeNode = AVLTreeNodeNested> extends BSTNode { @@ -29,7 +38,7 @@ export class AVLTree = AVLTreeNode, options?: Partial) { + constructor(elements?: Iterable>, options?: Partial) { super([], options); if (elements) this.init(elements); } @@ -66,7 +75,7 @@ export class AVLTree = AVLTreeNode, value?: V): N | undefined { if (keyOrNode === null) return undefined; const inserted = super.add(keyOrNode, value); if (inserted) this._balancePath(inserted); @@ -112,7 +121,7 @@ export class AVLTree = AVLTreeNode): void { + init(elements: Iterable>): void { if (elements) { for (const entryOrKey of elements) { if (Array.isArray(entryOrKey)) { @@ -135,7 +144,7 @@ export class AVLTree = AVLTreeNode, destNode: BSTNKeyOrNode): N | undefined { srcNode = this.ensureNotKey(srcNode); destNode = this.ensureNotKey(destNode); diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts index 909f7ed..dc0b9ff 100644 --- a/src/data-structures/binary-tree/binary-tree.ts +++ b/src/data-structures/binary-tree/binary-tree.ts @@ -6,14 +6,20 @@ * @license MIT License */ -import type { BinaryTreeNodeNested, BinaryTreeOptions, BTNCallback, BTNKey } from '../../types'; +import type { + BinaryTreeNodeNested, + BinaryTreeOptions, + BTNCallback, + BTNExemplar, + BTNKey, + BTNKeyOrNode +} from '../../types'; import { BinaryTreeNested, BinaryTreePrintOptions, BiTreeDeleteResult, DFSOrderPattern, FamilyPosition, - IterableEntriesOrKeys, IterationType, NodeDisplayLayout } from '../../types'; @@ -125,7 +131,7 @@ export class BinaryTree = BinaryTreeNode * Creates a new instance of BinaryTree. * @param {BinaryTreeOptions} [options] - The options for the binary tree. */ - constructor(elements?: IterableEntriesOrKeys, options?: Partial) { + constructor(elements?: Iterable>, options?: Partial) { if (options) { const { iterationType } = options; @@ -184,7 +190,7 @@ export class BinaryTree = BinaryTreeNode * @returns The function `add` returns a node (`N`) if it was successfully inserted into the binary * tree, or `null` or `undefined` if the insertion was not successful. */ - add(keyOrNode: BTNKey | N | null | undefined, value?: V): N | null | undefined { + add(keyOrNode: BTNKeyOrNode, value?: V): N | null | undefined { const _bfs = (root: N, newNode: N | null): N | undefined | null => { const queue = new Queue([root]); while (queue.size > 0) { @@ -246,7 +252,7 @@ export class BinaryTree = BinaryTreeNode * keys or nodes during the add operation. * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values. */ - addMany(keysOrNodes: (BTNKey | N | null | undefined)[], values?: (V | undefined)[]): (N | null | undefined)[] { + addMany(keysOrNodes: (BTNKeyOrNode)[], values?: (V | undefined)[]): (N | null | undefined)[] { // TODO not sure addMany not be run multi times return keysOrNodes.map((keyOrNode, i) => { if (keyOrNode instanceof BinaryTreeNode) { @@ -279,7 +285,7 @@ export class BinaryTree = BinaryTreeNode * array. Each value in the `data` array will be assigned to the * @returns The method is returning a boolean value. */ - refill(keysOrNodes: (BTNKey | N | null | undefined)[], values?: (V | undefined)[]): boolean { + refill(keysOrNodes: (BTNKeyOrNode)[], values?: (V | undefined)[]): boolean { this.clear(); return keysOrNodes.length === this.addMany(keysOrNodes, values).length; } @@ -378,7 +384,7 @@ export class BinaryTree = BinaryTreeNode * `N` (binary tree node) or `null` or `undefined`. If no value is provided for `beginRoot * @returns the depth of the `distNode` relative to the `beginRoot`. */ - getDepth(distNode: BTNKey | N | null | undefined, beginRoot: BTNKey | N | null | undefined = this.root): number { + getDepth(distNode: BTNKeyOrNode, beginRoot: BTNKeyOrNode = this.root): number { distNode = this.ensureNotKey(distNode); beginRoot = this.ensureNotKey(beginRoot); let depth = 0; @@ -411,7 +417,7 @@ export class BinaryTree = BinaryTreeNode * values: * @returns the height of the binary tree. */ - getHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): number { + getHeight(beginRoot: BTNKeyOrNode = this.root, iterationType = this.iterationType): number { beginRoot = this.ensureNotKey(beginRoot); if (!beginRoot) return -1; @@ -460,7 +466,7 @@ export class BinaryTree = BinaryTreeNode * to calculate the minimum height of a binary tree. It can have two possible values: * @returns The function `getMinHeight` returns the minimum height of a binary tree. */ - getMinHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): number { + getMinHeight(beginRoot: BTNKeyOrNode = this.root, iterationType = this.iterationType): number { beginRoot = this.ensureNotKey(beginRoot); if (!beginRoot) return -1; @@ -520,7 +526,7 @@ export class BinaryTree = BinaryTreeNode * value of a binary tree node), `N` (a node of a binary tree), `null`, or `undefined`. If * @returns a boolean value. */ - isPerfectlyBalanced(beginRoot: BTNKey | N | null | undefined = this.root): boolean { + isPerfectlyBalanced(beginRoot: BTNKeyOrNode = this.root): boolean { return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot); } @@ -533,7 +539,7 @@ export class BinaryTree = BinaryTreeNode identifier: BTNKey, callback?: C, onlyOne?: boolean, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType ): N[]; @@ -541,7 +547,7 @@ export class BinaryTree = BinaryTreeNode identifier: N | null | undefined, callback?: C, onlyOne?: boolean, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType ): N[]; @@ -549,7 +555,7 @@ export class BinaryTree = BinaryTreeNode identifier: ReturnType, callback: C, onlyOne?: boolean, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType ): N[]; @@ -582,7 +588,7 @@ export class BinaryTree = BinaryTreeNode identifier: ReturnType | null | undefined, callback: C = this._defaultOneParamCallback as C, onlyOne = false, - beginRoot: BTNKey | N | null | undefined = this.root, + beginRoot: BTNKeyOrNode = this.root, iterationType = this.iterationType ): N[] { if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode) @@ -630,21 +636,21 @@ export class BinaryTree = BinaryTreeNode has>( identifier: BTNKey, callback?: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType ): boolean; has>( identifier: N | null | undefined, callback?: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType ): boolean; has>( identifier: ReturnType | null | undefined, callback: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType ): boolean; @@ -671,7 +677,7 @@ export class BinaryTree = BinaryTreeNode has>( identifier: ReturnType | null | undefined, callback: C = this._defaultOneParamCallback as C, - beginRoot: BTNKey | N | null | undefined = this.root, + beginRoot: BTNKeyOrNode = this.root, iterationType = this.iterationType ): boolean { if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode) @@ -688,21 +694,21 @@ export class BinaryTree = BinaryTreeNode getNode>( identifier: BTNKey, callback?: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType ): N | null | undefined; getNode>( identifier: N | null | undefined, callback?: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType ): N | null | undefined; getNode>( identifier: ReturnType, callback: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType ): N | null | undefined; @@ -730,7 +736,7 @@ export class BinaryTree = BinaryTreeNode getNode>( identifier: ReturnType | null | undefined, callback: C = this._defaultOneParamCallback as C, - beginRoot: BTNKey | N | null | undefined = this.root, + beginRoot: BTNKeyOrNode = this.root, iterationType = this.iterationType ): N | null | undefined { if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode) @@ -799,28 +805,28 @@ export class BinaryTree = BinaryTreeNode * @returns either the node corresponding to the given key if it is a valid node key, or the key * itself if it is not a valid node key. */ - ensureNotKey(key: BTNKey | N | null | undefined, iterationType = IterationType.ITERATIVE): N | null | undefined { + ensureNotKey(key: BTNKeyOrNode, iterationType = IterationType.ITERATIVE): N | null | undefined { return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key; } get>( identifier: BTNKey, callback?: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType ): V | undefined; get>( identifier: N | null | undefined, callback?: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType ): V | undefined; get>( identifier: ReturnType, callback: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType ): V | undefined; @@ -849,7 +855,7 @@ export class BinaryTree = BinaryTreeNode get>( identifier: ReturnType | null | undefined, callback: C = this._defaultOneParamCallback as C, - beginRoot: BTNKey | N | null | undefined = this.root, + beginRoot: BTNKeyOrNode = this.root, iterationType = this.iterationType ): V | undefined { if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode) @@ -893,7 +899,7 @@ export class BinaryTree = BinaryTreeNode * reversed before returning it. If `isReverse` is set to `false`, the path will be returned as is * @returns The function `getPathToRoot` returns an array of nodes (`N[]`). */ - getPathToRoot(beginRoot: BTNKey | N | null | undefined, isReverse = true): N[] { + getPathToRoot(beginRoot: BTNKeyOrNode, isReverse = true): N[] { // TODO to support get path through passing key const result: N[] = []; beginRoot = this.ensureNotKey(beginRoot); @@ -930,7 +936,7 @@ export class BinaryTree = BinaryTreeNode * is no leftmost node, it returns `null` or `undefined` depending on the input. */ getLeftMost( - beginRoot: BTNKey | N | null | undefined = this.root, + beginRoot: BTNKeyOrNode = this.root, iterationType = this.iterationType ): N | null | undefined { beginRoot = this.ensureNotKey(beginRoot); @@ -976,7 +982,7 @@ export class BinaryTree = BinaryTreeNode * is no rightmost node, it returns `null` or `undefined`, depending on the input. */ getRightMost( - beginRoot: BTNKey | N | null | undefined = this.root, + beginRoot: BTNKeyOrNode = this.root, iterationType = this.iterationType ): N | null | undefined { // TODO support get right most by passing key in @@ -1018,7 +1024,7 @@ export class BinaryTree = BinaryTreeNode * possible values: * @returns a boolean value. */ - isSubtreeBST(beginRoot: BTNKey | N | null | undefined, iterationType = this.iterationType): boolean { + isSubtreeBST(beginRoot: BTNKeyOrNode, iterationType = this.iterationType): boolean { // TODO there is a bug beginRoot = this.ensureNotKey(beginRoot); if (!beginRoot) return true; @@ -1077,21 +1083,21 @@ export class BinaryTree = BinaryTreeNode subTreeTraverse>( callback?: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType, includeNull?: false ): ReturnType[]; subTreeTraverse>( callback?: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType, includeNull?: undefined ): ReturnType[]; subTreeTraverse>( callback?: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType, includeNull?: true ): ReturnType[]; @@ -1120,7 +1126,7 @@ export class BinaryTree = BinaryTreeNode */ subTreeTraverse>( callback: C = this._defaultOneParamCallback as C, - beginRoot: BTNKey | N | null | undefined = this.root, + beginRoot: BTNKeyOrNode = this.root, iterationType = this.iterationType, includeNull = false ): ReturnType[] { @@ -1210,7 +1216,7 @@ export class BinaryTree = BinaryTreeNode dfs>( callback?: C, pattern?: DFSOrderPattern, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType, includeNull?: false ): ReturnType[]; @@ -1218,7 +1224,7 @@ export class BinaryTree = BinaryTreeNode dfs>( callback?: C, pattern?: DFSOrderPattern, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType, includeNull?: undefined ): ReturnType[]; @@ -1226,7 +1232,7 @@ export class BinaryTree = BinaryTreeNode dfs>( callback?: C, pattern?: DFSOrderPattern, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType, includeNull?: true ): ReturnType[]; @@ -1257,7 +1263,7 @@ export class BinaryTree = BinaryTreeNode dfs>( callback: C = this._defaultOneParamCallback as C, pattern: DFSOrderPattern = 'in', - beginRoot: BTNKey | N | null | undefined = this.root, + beginRoot: BTNKeyOrNode = this.root, iterationType: IterationType = IterationType.ITERATIVE, includeNull = false ): ReturnType[] { @@ -1356,21 +1362,21 @@ export class BinaryTree = BinaryTreeNode bfs>( callback?: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType, includeNull?: false ): ReturnType[]; bfs>( callback?: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType, includeNull?: undefined ): ReturnType[]; bfs>( callback?: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType, includeNull?: true ): ReturnType[]; @@ -1398,7 +1404,7 @@ export class BinaryTree = BinaryTreeNode */ bfs>( callback: C = this._defaultOneParamCallback as C, - beginRoot: BTNKey | N | null | undefined = this.root, + beginRoot: BTNKeyOrNode = this.root, iterationType = this.iterationType, includeNull = false ): ReturnType[] { @@ -1457,21 +1463,21 @@ export class BinaryTree = BinaryTreeNode listLevels>( callback?: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType, includeNull?: false ): ReturnType[][]; listLevels>( callback?: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType, includeNull?: undefined ): ReturnType[][]; listLevels>( callback?: C, - beginRoot?: BTNKey | N | null | undefined, + beginRoot?: BTNKeyOrNode, iterationType?: IterationType, includeNull?: true ): ReturnType[][]; @@ -1499,7 +1505,7 @@ export class BinaryTree = BinaryTreeNode */ listLevels>( callback: C = this._defaultOneParamCallback as C, - beginRoot: BTNKey | N | null | undefined = this.root, + beginRoot: BTNKeyOrNode = this.root, iterationType = this.iterationType, includeNull = false ): ReturnType[][] { @@ -1557,7 +1563,7 @@ export class BinaryTree = BinaryTreeNode * `null`, or `undefined`. * @returns The function `getPredecessor` returns a value of type `N | undefined`. */ - getPredecessor(node: BTNKey | N | null | undefined): N | undefined { + getPredecessor(node: BTNKeyOrNode): N | undefined { node = this.ensureNotKey(node); if (!this.isRealNode(node)) return undefined; @@ -1617,7 +1623,7 @@ export class BinaryTree = BinaryTreeNode morris>( callback: C = this._defaultOneParamCallback as C, pattern: DFSOrderPattern = 'in', - beginRoot: BTNKey | N | null | undefined = this.root + beginRoot: BTNKeyOrNode = this.root ): ReturnType[] { beginRoot = this.ensureNotKey(beginRoot); if (beginRoot === null) return []; @@ -1825,7 +1831,7 @@ export class BinaryTree = BinaryTreeNode * following types: * @param {BinaryTreePrintOptions} [options={ isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false}] - Options object that controls printing behavior. You can specify whether to display undefined, null, or sentinel nodes. */ - print(beginRoot: BTNKey | N | null | undefined = this.root, options?: BinaryTreePrintOptions): void { + print(beginRoot: BTNKeyOrNode = this.root, options?: BinaryTreePrintOptions): void { const opts = { isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false, ...options }; beginRoot = this.ensureNotKey(beginRoot); if (!beginRoot) return; @@ -1847,7 +1853,7 @@ export class BinaryTree = BinaryTreeNode display(beginRoot); } - init(elements: IterableEntriesOrKeys): void { + init(elements: Iterable>): void { if (elements) { for (const entryOrKey of elements) { if (Array.isArray(entryOrKey)) { @@ -1918,7 +1924,7 @@ export class BinaryTree = BinaryTreeNode * @param {N} destNode - The destination node to swap. * @returns {N} - The destination node after the swap. */ - protected _swap(srcNode: BTNKey | N | null | undefined, destNode: BTNKey | N | null | undefined): N | undefined { + protected _swap(srcNode: BTNKeyOrNode, destNode: BTNKeyOrNode): N | undefined { srcNode = this.ensureNotKey(srcNode); destNode = this.ensureNotKey(destNode); @@ -1950,7 +1956,7 @@ export class BinaryTree = BinaryTreeNode * the binary tree. If neither the left nor right child is available, the function returns undefined. * If the parent node is null, the function also returns undefined. */ - protected _addTo(newNode: N | null | undefined, parent: BTNKey | N | null | undefined): N | null | undefined { + protected _addTo(newNode: N | null | undefined, parent: BTNKeyOrNode): N | null | undefined { if (this.isNodeKey(parent)) parent = this.getNode(parent); if (parent) { diff --git a/src/data-structures/binary-tree/bst.ts b/src/data-structures/binary-tree/bst.ts index 30f4d96..64f9aa1 100644 --- a/src/data-structures/binary-tree/bst.ts +++ b/src/data-structures/binary-tree/bst.ts @@ -5,8 +5,18 @@ * @copyright Copyright (c) 2022 Tyler Zeng * @license MIT License */ -import type { BSTNested, BSTNodeNested, BSTOptions, BTNCallback, BTNKey, Comparator } from '../../types'; -import { CP, IterableEntriesOrKeys, IterationType } from '../../types'; +import type { + BSTNested, + BSTNKeyOrNode, + BSTNodeNested, + BSTOptions, + BTNCallback, + BTNExemplar, + BTNKey, + BTNKeyOrNode, + Comparator +} from '../../types'; +import { CP, IterationType } from '../../types'; import { BinaryTree, BinaryTreeNode } from './binary-tree'; import { IBinaryTree } from '../../interfaces'; import { Queue } from '../queue'; @@ -71,7 +81,7 @@ export class BST = BSTNode> * @param {BSTOptions} [options] - An optional object that contains additional configuration options * for the binary search tree. */ - constructor(elements?: IterableEntriesOrKeys, options?: Partial) { + constructor(elements?: Iterable>, options?: Partial) { super([], options); if (options) { @@ -127,7 +137,7 @@ export class BST = BSTNode> * @returns The method `add` returns a node (`N`) that was inserted into the binary search tree. If * no node was inserted, it returns `undefined`. */ - override add(keyOrNode: BTNKey | N | null | undefined, value?: V): N | undefined { + override add(keyOrNode: BTNKeyOrNode, value?: V): N | undefined { if (keyOrNode === null) return undefined; // TODO support node as a parameter let inserted: N | undefined; @@ -220,13 +230,13 @@ export class BST = BSTNode> * @returns The function `addMany` returns an array of nodes (`N`) or `undefined` values. */ override addMany( - keysOrNodes: (BTNKey | N | undefined)[], + keysOrNodes: (BSTNKeyOrNode)[], data?: (V | undefined)[], isBalanceAdd = true, iterationType = this.iterationType ): (N | undefined)[] { // TODO this addMany function is inefficient, it should be optimized - function hasNoUndefined(arr: (BTNKey | N | undefined)[]): arr is (BTNKey | N)[] { + function hasNoUndefined(arr: (BSTNKeyOrNode)[]): arr is (BTNKey | N)[] { return arr.indexOf(undefined) === -1; } @@ -263,7 +273,7 @@ export class BST = BSTNode> } sortedKeysOrNodes = sorted.map(([keyOrNode]) => keyOrNode); sortedData = sorted.map(([, value]) => value); - const _dfs = (arr: (BTNKey | undefined | N)[], data?: (V | undefined)[]) => { + const _dfs = (arr: (BSTNKeyOrNode)[], data?: (V | undefined)[]) => { if (arr.length === 0) return; const mid = Math.floor((arr.length - 1) / 2); @@ -318,7 +328,7 @@ export class BST = BSTNode> * the key of the leftmost node if the comparison result is greater than, and the key of the * rightmost node otherwise. If no node is found, it returns 0. */ - lastKey(beginRoot: BTNKey | N | undefined = this.root, iterationType = this.iterationType): BTNKey { + lastKey(beginRoot: BSTNKeyOrNode = this.root, iterationType = this.iterationType): BTNKey { if (this._compare(0, 1) === CP.lt) return this.getRightMost(beginRoot, iterationType)?.key ?? 0; else if (this._compare(0, 1) === CP.gt) return this.getLeftMost(beginRoot, iterationType)?.key ?? 0; else return this.getRightMost(beginRoot, iterationType)?.key ?? 0; @@ -382,7 +392,7 @@ export class BST = BSTNode> * type of iteration to be performed. It has a default value of `IterationType.ITERATIVE`. * @returns either a node object (N) or undefined. */ - override ensureNotKey(key: BTNKey | N | undefined, iterationType = IterationType.ITERATIVE): N | undefined { + override ensureNotKey(key: BSTNKeyOrNode, iterationType = IterationType.ITERATIVE): N | undefined { return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key; } @@ -413,7 +423,7 @@ export class BST = BSTNode> identifier: ReturnType | undefined, callback: C = this._defaultOneParamCallback as C, onlyOne = false, - beginRoot: BTNKey | N | undefined = this.root, + beginRoot: BSTNKeyOrNode = this.root, iterationType = this.iterationType ): N[] { beginRoot = this.ensureNotKey(beginRoot); @@ -494,7 +504,7 @@ export class BST = BSTNode> lesserOrGreaterTraverse>( callback: C = this._defaultOneParamCallback as C, lesserOrGreater: CP = CP.lt, - targetNode: BTNKey | N | undefined = this.root, + targetNode: BSTNKeyOrNode = this.root, iterationType = this.iterationType ): ReturnType[] { targetNode = this.ensureNotKey(targetNode); @@ -659,7 +669,7 @@ export class BST = BSTNode> * Space Complexity: O(log n) - Space for the recursive call stack in the worst case. */ - init(elements: IterableEntriesOrKeys): void { + override init(elements: Iterable>): void { if (elements) { for (const entryOrKey of elements) { if (Array.isArray(entryOrKey)) { diff --git a/src/data-structures/binary-tree/rb-tree.ts b/src/data-structures/binary-tree/rb-tree.ts index 8ccf2b4..2b6e23b 100644 --- a/src/data-structures/binary-tree/rb-tree.ts +++ b/src/data-structures/binary-tree/rb-tree.ts @@ -8,9 +8,11 @@ import { BiTreeDeleteResult, + BSTNKeyOrNode, BTNCallback, + BTNExemplar, BTNKey, - IterableEntriesOrKeys, + BTNKeyOrNode, IterationType, RBTNColor, RBTreeOptions, @@ -51,7 +53,7 @@ export class RedBlackTree = RedBlackTr * @param {RBTreeOptions} [options] - The `options` parameter is an optional object that can be * passed to the constructor. It is used to configure the RBTree object with specific options. */ - constructor(elements?: IterableEntriesOrKeys, options?: Partial) { + constructor(elements?: Iterable>, options?: Partial) { super([], options); this._root = this.Sentinel; @@ -92,7 +94,7 @@ export class RedBlackTree = RedBlackTr * key in the node being added to the Red-Black Tree. * @returns The method returns either a node (`N`) or `undefined`. */ - override add(keyOrNode: BTNKey | N | null | undefined, value?: V): N | undefined { + override add(keyOrNode: BTNKeyOrNode, value?: V): N | undefined { let node: N; if (this.isNodeKey(keyOrNode)) { node = this.createNode(keyOrNode, value, RBTNColor.RED); @@ -285,7 +287,7 @@ export class RedBlackTree = RedBlackTr getNode>( identifier: ReturnType | undefined, callback: C = this._defaultOneParamCallback as C, - beginRoot: BTNKey | N | undefined = this.root, + beginRoot: BSTNKeyOrNode = this.root, iterationType = this.iterationType ): N | null | undefined { if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C; @@ -357,7 +359,7 @@ export class RedBlackTree = RedBlackTr this._size = 0; } - init(elements: IterableEntriesOrKeys): void { + init(elements: Iterable>): void { if (elements) { for (const entryOrKey of elements) { if (Array.isArray(entryOrKey)) { diff --git a/src/data-structures/binary-tree/tree-multimap.ts b/src/data-structures/binary-tree/tree-multimap.ts index 7e93faa..d9ffffb 100644 --- a/src/data-structures/binary-tree/tree-multimap.ts +++ b/src/data-structures/binary-tree/tree-multimap.ts @@ -5,16 +5,15 @@ * @copyright Copyright (c) 2022 Tyler Zeng * @license MIT License */ -import type { BTNKey, TreeMultimapNodeNested, TreeMultimapOptions } from '../../types'; -import { - BiTreeDeleteResult, - BTNCallback, - CP, - FamilyPosition, - IterableEntriesOrKeys, - IterationType, - TreeMultimapNested +import type { + BSTNKeyOrNode, + BTNExemplar, + BTNKey, + BTNKeyOrNode, + TreeMultimapNodeNested, + TreeMultimapOptions } from '../../types'; +import { BiTreeDeleteResult, BTNCallback, CP, FamilyPosition, IterationType, TreeMultimapNested } from '../../types'; import { IBinaryTree } from '../../interfaces'; import { AVLTree, AVLTreeNode } from './avl-tree'; @@ -54,7 +53,7 @@ export class TreeMultimap = TreeMultim * @param {TreeMultimapOptions} [options] - An optional object that contains additional configuration options for the * TreeMultimap. */ - constructor(elements?: IterableEntriesOrKeys, options?: Partial) { + constructor(elements?: Iterable>, options?: Partial) { super([], options); if (elements) this.init(elements); } @@ -99,7 +98,7 @@ export class TreeMultimap = TreeMultim * times the key-value pair should be added to the multimap. If not provided, the default value is 1. * @returns a node (`N`) or `undefined`. */ - override add(keyOrNode: BTNKey | N | null | undefined, value?: V, count = 1): N | undefined { + override add(keyOrNode: BTNKeyOrNode, value?: V, count = 1): N | undefined { if (keyOrNode === null) return undefined; let inserted: N | undefined = undefined, newNode: N | undefined; @@ -186,7 +185,7 @@ export class TreeMultimap = TreeMultim * TreeMultimap. If provided, the length of the `data` array should be the same as the length of the * @returns The function `addMany` returns an array of nodes (`N`) or `undefined` values. */ - override addMany(keysOrNodes: (BTNKey | N | undefined)[], data?: V[]): (N | undefined)[] { + override addMany(keysOrNodes: (BSTNKeyOrNode)[], data?: V[]): (N | undefined)[] { const inserted: (N | undefined)[] = []; for (let i = 0; i < keysOrNodes.length; i++) { @@ -363,7 +362,7 @@ export class TreeMultimap = TreeMultim * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size. */ - init(elements: IterableEntriesOrKeys): void { + init(elements: Iterable>): void { if (elements) { for (const entryOrKey of elements) { if (Array.isArray(entryOrKey)) { @@ -391,7 +390,7 @@ export class TreeMultimap = TreeMultim * @returns The method `_addTo` returns either the `parent.left` or `parent.right` node that was * added, or `undefined` if no node was added. */ - protected override _addTo(newNode: N | undefined, parent: BTNKey | N | undefined): N | undefined { + protected override _addTo(newNode: N | undefined, parent: BSTNKeyOrNode): N | undefined { parent = this.ensureNotKey(parent); if (parent) { if (parent.left === undefined) { @@ -426,7 +425,7 @@ export class TreeMultimap = TreeMultim * @returns either the `destNode` object if both `srcNode` and `destNode` are defined, or `undefined` * if either `srcNode` or `destNode` is undefined. */ - protected _swap(srcNode: BTNKey | N | undefined, destNode: BTNKey | N | undefined): N | undefined { + protected _swap(srcNode: BSTNKeyOrNode, destNode: BSTNKeyOrNode): N | undefined { srcNode = this.ensureNotKey(srcNode); destNode = this.ensureNotKey(destNode); if (srcNode && destNode) { diff --git a/src/interfaces/binary-tree.ts b/src/interfaces/binary-tree.ts index f8a5595..589811d 100644 --- a/src/interfaces/binary-tree.ts +++ b/src/interfaces/binary-tree.ts @@ -5,8 +5,8 @@ import { BinaryTreeOptions, BiTreeDeleteResult, BTNCallback, + BTNExemplar, BTNKey, - IterableEntriesOrKeys } from '../types'; export interface IBinaryTree = BinaryTreeNodeNested, TREE extends BinaryTree = BinaryTreeNested> { @@ -14,7 +14,7 @@ export interface IBinaryTree = BinaryTre createTree(options?: Partial): TREE; - init(elements: IterableEntriesOrKeys): void; + init(elements: Iterable>): void; add(keyOrNode: BTNKey | N | null, value?: N['value']): N | null | undefined; diff --git a/src/types/common.ts b/src/types/common.ts index d5fb02a..c6c760c 100644 --- a/src/types/common.ts +++ b/src/types/common.ts @@ -24,4 +24,8 @@ export type IterableWithSizeOrLength = IterableWithSize | IterableWithLeng export type BinaryTreePrintOptions = { isShowUndefined?: boolean, isShowNull?: boolean, isShowRedBlackNIL?: boolean } -export type IterableEntriesOrKeys = Iterable<[BTNKey, T | undefined] | BTNKey> \ No newline at end of file +export type BTNExemplar = [BTNKey | null | undefined, T | undefined] | BTNKeyOrNode + +export type BTNKeyOrNode = BTNKey | null | undefined | N; + +export type BSTNKeyOrNode = BTNKey | undefined | N; \ No newline at end of file