diff --git a/CHANGELOG.md b/CHANGELOG.md index 71064cc..712f826 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. - [Semantic Versioning](https://semver.org/spec/v2.0.0.html) - [`auto-changelog`](https://github.com/CookPete/auto-changelog) -## [v1.53.8](https://github.com/zrwusa/data-structure-typed/compare/v1.51.5...main) (upcoming) +## [v1.53.9](https://github.com/zrwusa/data-structure-typed/compare/v1.51.5...main) (upcoming) ### Changes diff --git a/package-lock.json b/package-lock.json index 549eb25..804e678 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "data-structure-typed", - "version": "1.53.8", + "version": "1.53.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "data-structure-typed", - "version": "1.53.8", + "version": "1.53.9", "license": "MIT", "devDependencies": { "@eslint/compat": "^1.2.2", @@ -19,11 +19,11 @@ "@typescript-eslint/eslint-plugin": "^8.12.1", "@typescript-eslint/parser": "^8.12.1", "auto-changelog": "^2.5.0", - "avl-tree-typed": "^1.53.7", + "avl-tree-typed": "^1.53.8", "benchmark": "^2.1.4", - "binary-tree-typed": "^1.53.7", - "bst-typed": "^1.53.7", - "data-structure-typed": "^1.53.7", + "binary-tree-typed": "^1.53.8", + "bst-typed": "^1.53.8", + "data-structure-typed": "^1.53.8", "dependency-cruiser": "^16.5.0", "doctoc": "^2.2.1", "eslint": "^9.13.0", @@ -32,7 +32,7 @@ "eslint-import-resolver-typescript": "^3.6.3", "eslint-plugin-import": "^2.31.0", "fast-glob": "^3.3.2", - "heap-typed": "^1.53.7", + "heap-typed": "^1.53.8", "istanbul-badges-readme": "^1.9.0", "jest": "^29.7.0", "js-sdsl": "^4.4.2", @@ -3437,13 +3437,13 @@ } }, "node_modules/avl-tree-typed": { - "version": "1.53.7", - "resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.53.7.tgz", - "integrity": "sha512-+HyMQY+1FoOQm6ESwSbtJL6LnR9XNYxqJc6IdDEAhBZovRx2m3bwgse5q+3SLyEqQAUwSY9LsGD3A80UQq4fjQ==", + "version": "1.53.8", + "resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.53.8.tgz", + "integrity": "sha512-FJKmj/kYbdK7Du/Bva9NSLHmiSVA4KqV7AEd4yqnKYrwEfXVfvHJ6wggfyQmdwhrygFTET4ByAldshFzGIwBHQ==", "dev": true, "license": "MIT", "dependencies": { - "data-structure-typed": "^1.53.7" + "data-structure-typed": "^1.53.8" } }, "node_modules/babel-jest": { @@ -3602,13 +3602,13 @@ } }, "node_modules/binary-tree-typed": { - "version": "1.53.7", - "resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.53.7.tgz", - "integrity": "sha512-Pd/N1QOFm7qgBhdp4T43lBpUhPUex5hwL/9JuZ7qgfN++qxCQLAwU72tgPAvSjwb4z6njqG8/4hfLdnLUbDWUg==", + "version": "1.53.8", + "resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.53.8.tgz", + "integrity": "sha512-qMTzw2MfEB1Ihn5LBtmgk4bL5rBd0E6x1bJLiZTudbWv/PrDrT+GrtIcVozwKQG6QwjRbbnnkWYDm509l+To3g==", "dev": true, "license": "MIT", "dependencies": { - "data-structure-typed": "^1.53.7" + "data-structure-typed": "^1.53.8" } }, "node_modules/brace-expansion": { @@ -3691,13 +3691,13 @@ } }, "node_modules/bst-typed": { - "version": "1.53.7", - "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.53.7.tgz", - "integrity": "sha512-Sj2nJb/2SUAqcSg4oXNWMt9OxlF4NcxPQ6o2wMKbqiKp4JCblmLpVEjbaZBVrpRMTKHEZctW/is21QPcxQ9Hnw==", + "version": "1.53.8", + "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.53.8.tgz", + "integrity": "sha512-BvqI2skHCrPYE3JYhSpSjpsRwGHQKw9/SNE5vC4AzxOQpL3fmg9bSBG5aGIrPk4Uc3BEkL9NUignLbjJMNwXcw==", "dev": true, "license": "MIT", "dependencies": { - "data-structure-typed": "^1.53.7" + "data-structure-typed": "^1.53.8" } }, "node_modules/buffer-from": { @@ -4069,9 +4069,9 @@ } }, "node_modules/data-structure-typed": { - "version": "1.53.7", - "resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.53.7.tgz", - "integrity": "sha512-8higtCbppFIeHaz7JMJL2WdZ/vc4wtO8+Yh6qZtONDAy+shqafASqpTsYnKJaE8gNiPzOkP2YOMiEbVdpKLhhQ==", + "version": "1.53.8", + "resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.53.8.tgz", + "integrity": "sha512-d0kCsb0U1kNMNcsoJI2zX1LkrsiX9FSLXPN4PL9IweyvAsQybcwdV7Y48ZLcUPWnShipuvaaxFLYtznjNcSsqw==", "dev": true, "license": "MIT" }, @@ -5946,13 +5946,13 @@ } }, "node_modules/heap-typed": { - "version": "1.53.7", - "resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.53.7.tgz", - "integrity": "sha512-iXPgPtyCxDY/+e8eCvWUVSsQ2h+7L6upoP1QGJrIm47+tdTovV/EZ0PhCIKWERRzHI4Us/PM9hZbX0Jt8KBeRg==", + "version": "1.53.8", + "resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.53.8.tgz", + "integrity": "sha512-Gmwpyl0JSZka8KMR6q3OMsrfA88XA8BmP3aEdT26UnMsX5HBwlBnj2vJvKqOCl5lPl3AhOD5nAj5zxI84bwrrw==", "dev": true, "license": "MIT", "dependencies": { - "data-structure-typed": "^1.53.7" + "data-structure-typed": "^1.53.8" } }, "node_modules/html-escaper": { diff --git a/package.json b/package.json index 385974a..fec33d3 100644 --- a/package.json +++ b/package.json @@ -70,11 +70,11 @@ "@typescript-eslint/eslint-plugin": "^8.12.1", "@typescript-eslint/parser": "^8.12.1", "auto-changelog": "^2.5.0", - "avl-tree-typed": "^1.53.7", + "avl-tree-typed": "^1.53.8", "benchmark": "^2.1.4", - "binary-tree-typed": "^1.53.7", - "bst-typed": "^1.53.7", - "data-structure-typed": "^1.53.7", + "binary-tree-typed": "^1.53.8", + "bst-typed": "^1.53.8", + "data-structure-typed": "^1.53.8", "dependency-cruiser": "^16.5.0", "doctoc": "^2.2.1", "eslint": "^9.13.0", @@ -83,7 +83,7 @@ "eslint-import-resolver-typescript": "^3.6.3", "eslint-plugin-import": "^2.31.0", "fast-glob": "^3.3.2", - "heap-typed": "^1.53.7", + "heap-typed": "^1.53.8", "istanbul-badges-readme": "^1.9.0", "jest": "^29.7.0", "js-sdsl": "^4.4.2", diff --git a/src/data-structures/binary-tree/avl-tree-multi-map.ts b/src/data-structures/binary-tree/avl-tree-multi-map.ts index 00d0465..114758b 100644 --- a/src/data-structures/binary-tree/avl-tree-multi-map.ts +++ b/src/data-structures/binary-tree/avl-tree-multi-map.ts @@ -6,6 +6,7 @@ * @license MIT License */ import type { + AVLTreeMultiMapNested, AVLTreeMultiMapNodeNested, AVLTreeMultiMapOptions, BinaryTreeDeleteResult, @@ -36,25 +37,6 @@ export class AVLTreeMultiMapNode< super(key, value); this.count = count; } - - protected _count: number = 1; - - /** - * The function returns the value of the protected variable _count. - * @returns The count property of the object, which is of type number. - */ - get count(): number { - return this._count; - } - - /** - * The above function sets the value of the count property. - * @param {number} value - The value parameter is of type number, which means it can accept any - * numeric value. - */ - set count(value: number) { - this._count = value; - } } /** @@ -64,10 +46,23 @@ export class AVLTreeMultiMap< K = any, V = any, R = object, - NODE extends AVLTreeMultiMapNode = AVLTreeMultiMapNode> + MK = any, + MV = any, + MR = object, + NODE extends AVLTreeMultiMapNode = AVLTreeMultiMapNode>, + TREE extends AVLTreeMultiMap = AVLTreeMultiMap< + K, + V, + R, + MK, + MV, + MR, + NODE, + AVLTreeMultiMapNested + > > - extends AVLTree - implements IBinaryTree + extends AVLTree + implements IBinaryTree { /** * The constructor initializes a new AVLTreeMultiMap object with optional initial elements. @@ -132,16 +127,15 @@ export class AVLTreeMultiMap< * @returns a new instance of the AVLTreeMultiMap class, with the specified options, as a TREE * object. */ - // @ts-ignore - override createTree(options?: AVLTreeMultiMapOptions) { - return new AVLTreeMultiMap([], { + override createTree(options?: AVLTreeMultiMapOptions): TREE { + return new AVLTreeMultiMap([], { iterationType: this.iterationType, isMapMode: this._isMapMode, specifyComparable: this._specifyComparable, toEntryFn: this._toEntryFn, isReverse: this._isReverse, ...options - }); + }) as TREE; } /** @@ -220,7 +214,7 @@ export class AVLTreeMultiMap< } else { if (!curr.left) { if (!parent) { - if (curr.right !== undefined) this._setRoot(curr.right); + if (curr.right !== undefined && curr.right !== null) this._setRoot(curr.right); } else { const { familyPosition: fp } = curr; if (fp === 'LEFT' || fp === 'ROOT_LEFT') { @@ -330,8 +324,7 @@ export class AVLTreeMultiMap< * The function overrides the clone method to create a deep copy of a tree object. * @returns The `clone()` method is returning a cloned instance of the `TREE` object. */ - // @ts-ignore - override clone() { + override clone(): TREE { const cloned = this.createTree(); if (this._isMapMode) this.bfs(node => cloned.add(node.key, undefined, node.count)); else this.bfs(node => cloned.add(node.key, node.value, node.count)); @@ -357,12 +350,11 @@ export class AVLTreeMultiMap< * `callback` function along with the index and the original tree itself. The transformed entries are * then added to the new `AVLTreeMultiMap` instance, which is returned at the end. */ - // @ts-ignore override map( callback: EntryCallback, options?: AVLTreeMultiMapOptions, thisArg?: any - ) { + ): AVLTreeMultiMap { const newTree = new AVLTreeMultiMap([], options); let index = 0; for (const [key, value] of this) { diff --git a/src/data-structures/binary-tree/avl-tree.ts b/src/data-structures/binary-tree/avl-tree.ts index ae79479..e74481c 100644 --- a/src/data-structures/binary-tree/avl-tree.ts +++ b/src/data-structures/binary-tree/avl-tree.ts @@ -7,6 +7,7 @@ */ import { BST, BSTNode } from './bst'; import type { + AVLTreeNested, AVLTreeNodeNested, AVLTreeOptions, BinaryTreeDeleteResult, @@ -31,26 +32,6 @@ export class AVLTreeNode< */ constructor(key: K, value?: V) { super(key, value); - this._height = 0; - } - - protected _height: number; - - /** - * The function returns the value of the height property. - * @returns The height of the object. - */ - get height(): number { - return this._height; - } - - /** - * The above function sets the value of the height property. - * @param {number} value - The value parameter is a number that represents the new height value to be - * set. - */ - set height(value: number) { - this._height = value; } } @@ -67,10 +48,23 @@ export class AVLTree< K = any, V = any, R = object, - NODE extends AVLTreeNode = AVLTreeNode> + MK = any, + MV = any, + MR = object, + NODE extends AVLTreeNode = AVLTreeNode>, + TREE extends AVLTree = AVLTree< + K, + V, + R, + MK, + MV, + MR, + NODE, + AVLTreeNested + > > - extends BST - implements IBinaryTree + extends BST + implements IBinaryTree { /** * This is a constructor function for an AVLTree class that initializes the tree with keys, nodes, @@ -102,25 +96,21 @@ export class AVLTree< } /** - * The function `createTree` in TypeScript overrides the default AVLTree creation with the provided - * options. - * @param [options] - The `options` parameter in the `createTree` function is an object that contains - * configuration options for creating an AVL tree. These options can include properties such as - * `iterationType`, `isMapMode`, `specifyComparable`, `toEntryFn`, and `isReverse`. The function - * creates a - * @returns An AVLTree object is being returned with the specified options and properties inherited - * from the current object. + * The function creates a new AVL tree with the specified options and returns it. + * @param {AVLTreeOptions} [options] - The `options` parameter is an optional object that can be + * passed to the `createTree` function. It is used to customize the behavior of the AVL tree that is + * being created. + * @returns a new AVLTree object. */ - // @ts-ignore - override createTree(options?: AVLTreeOptions) { - return new AVLTree([], { + override createTree(options?: AVLTreeOptions): TREE { + return new AVLTree([], { iterationType: this.iterationType, isMapMode: this._isMapMode, specifyComparable: this._specifyComparable, toEntryFn: this._toEntryFn, isReverse: this._isReverse, ...options - }); + }) as TREE; } /** @@ -177,12 +167,11 @@ export class AVLTree< return deletedResults; } - // @ts-ignore - override map( + override map( callback: EntryCallback, options?: AVLTreeOptions, thisArg?: any - ) { + ): AVLTree { const newTree = new AVLTree([], options); let index = 0; for (const [key, value] of this) { @@ -279,7 +268,7 @@ export class AVLTree< protected _balanceLL(A: NODE): void { const parentOfA = A.parent; const B = A.left; - A.parent = B; + if (B !== null) A.parent = B; if (B && B.right) { B.right.parent = A; } @@ -316,12 +305,12 @@ export class AVLTree< if (B) { C = B.right; } - if (A) A.parent = C; - if (B) B.parent = C; + if (A && C !== null) A.parent = C; + if (B && C !== null) B.parent = C; if (C) { if (C.left) { - C.left.parent = B; + if (B !== null) C.left.parent = B; } if (C.right) { C.right.parent = A; @@ -363,7 +352,7 @@ export class AVLTree< protected _balanceRR(A: NODE): void { const parentOfA = A.parent; const B = A.right; - A.parent = B; + if (B !== null) A.parent = B; if (B) { if (B.left) { B.left.parent = A; @@ -406,15 +395,15 @@ export class AVLTree< C = B.left; } - A.parent = C; - if (B) B.parent = C; + if (C !== null) A.parent = C; + if (B && C !== null) B.parent = C; if (C) { if (C.left) { C.left.parent = A; } if (C.right) { - C.right.parent = B; + if (B !== null) C.right.parent = B; } C.parent = parentOfA; } diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts index a9595ea..d3076b5 100644 --- a/src/data-structures/binary-tree/binary-tree.ts +++ b/src/data-structures/binary-tree/binary-tree.ts @@ -8,6 +8,7 @@ import { BinaryTreeDeleteResult, + BinaryTreeNested, BinaryTreeNodeNested, BinaryTreeOptions, BinaryTreePrintOptions, @@ -22,6 +23,7 @@ import { NodeDisplayLayout, NodePredicate, OptNodeOrNull, + type RBTNColor, ToEntryFn } from '../../types'; import { IBinaryTree } from '../../interfaces'; @@ -51,7 +53,7 @@ export class BinaryTreeNode< this.value = value; } - protected _left?: OptNodeOrNull; + _left?: OptNodeOrNull; get left(): OptNodeOrNull { return this._left; @@ -64,7 +66,7 @@ export class BinaryTreeNode< this._left = v; } - protected _right?: OptNodeOrNull; + _right?: OptNodeOrNull; get right(): OptNodeOrNull { return this._right; @@ -77,6 +79,36 @@ export class BinaryTreeNode< this._right = v; } + _height: number = 0; + + get height(): number { + return this._height; + } + + set height(value: number) { + this._height = value; + } + + _color: RBTNColor = 'BLACK'; + + get color(): RBTNColor { + return this._color; + } + + set color(value: RBTNColor) { + this._color = value; + } + + _count: number = 1; + + get count(): number { + return this._count; + } + + set count(value: number) { + this._count = value; + } + get familyPosition(): FamilyPosition { const that = this as unknown as NODE; if (!this.parent) { @@ -104,10 +136,23 @@ export class BinaryTree< K = any, V = any, R = object, - NODE extends BinaryTreeNode = BinaryTreeNode> + MK = any, + MV = any, + MR = object, + NODE extends BinaryTreeNode = BinaryTreeNode>, + TREE extends BinaryTree = BinaryTree< + K, + V, + R, + MK, + MV, + MR, + NODE, + BinaryTreeNested + > > extends IterableEntryBase - implements IBinaryTree + implements IBinaryTree { iterationType: IterationType = 'ITERATIVE'; @@ -186,26 +231,63 @@ export class BinaryTree< } /** - * Time Complexity: O(1) - * Space Complexity: O(1) - * - * The `createTree` function creates a new binary tree based on the provided options. - * @param [options] - The `options` parameter in the `createTree` method is of type - * `BinaryTreeOptions`. This type likely contains configuration options for creating a - * binary tree, such as the iteration type, whether the tree is in map mode, and functions for - * converting entries. - * @returns The `createTree` method is returning an instance of the `BinaryTree` class with the - * provided options. The method is creating a new `BinaryTree` object with an empty array as the - * initial data, and then setting various options such as `iterationType`, `isMapMode`, and - * `toEntryFn` based on the current object's properties and the provided `options`. Finally, it + * The function creates a binary tree with the specified options. + * @param [options] - The `options` parameter in the `createTree` function is an optional parameter + * that allows you to provide partial configuration options for creating a binary tree. It is of type + * `Partial>`, which means you can pass in an object containing a subset + * of properties + * @returns A new instance of a binary tree with the specified options is being returned. */ - createTree(options?: BinaryTreeOptions): typeof this { - return new BinaryTree([], { + createTree(options?: BinaryTreeOptions): TREE { + return new BinaryTree([], { iterationType: this.iterationType, isMapMode: this._isMapMode, toEntryFn: this._toEntryFn, ...options - }) as unknown as typeof this; + }) as TREE; + } + + /** + * The function `keyValueNodeEntryRawToNodeAndValue` converts various input types into a node object + * or returns null. + * @param {BTNRep | R} keyNodeEntryOrRaw - The + * `keyValueNodeEntryRawToNodeAndValue` function takes in a parameter `keyNodeEntryOrRaw`, which + * can be of type `BTNRep` or `R`. This parameter represents either a key, a + * node, an entry + * @param {V} [value] - The `value` parameter in the `keyValueNodeEntryRawToNodeAndValue` function is + * an optional parameter of type `V`. It represents the value associated with the key in the node + * being created. If a `value` is provided, it will be used when creating the node. If + * @returns The `keyValueNodeEntryRawToNodeAndValue` function returns an optional node + * (`OptNodeOrNull`) based on the input parameters provided. The function checks the type of the + * input parameter (`keyNodeEntryOrRaw`) and processes it accordingly to return a node or null + * value. + */ + protected _keyValueNodeEntryRawToNodeAndValue( + keyNodeEntryOrRaw: BTNRep | R, + value?: V + ): [OptNodeOrNull, V | undefined] { + if (keyNodeEntryOrRaw === undefined) return [undefined, undefined]; + if (keyNodeEntryOrRaw === null) return [null, undefined]; + + if (this.isNode(keyNodeEntryOrRaw)) return [keyNodeEntryOrRaw, value]; + + if (this.isEntry(keyNodeEntryOrRaw)) { + const [key, entryValue] = keyNodeEntryOrRaw; + if (key === undefined) return [undefined, undefined]; + else if (key === null) return [null, undefined]; + const finalValue = value ?? entryValue; + return [this.createNode(key, finalValue), finalValue]; + } + + if (this.isRaw(keyNodeEntryOrRaw)) { + const [key, entryValue] = this._toEntryFn!(keyNodeEntryOrRaw); + const finalValue = value ?? entryValue; + if (this.isKey(key)) return [this.createNode(key, finalValue), finalValue]; + } + + if (this.isKey(keyNodeEntryOrRaw)) return [this.createNode(keyNodeEntryOrRaw, value), value]; + + return [undefined, undefined]; } /** @@ -490,7 +572,7 @@ export class BinaryTree< * elements from the other tree. * @param anotherTree - `BinaryTree` */ - merge(anotherTree: this) { + merge(anotherTree: BinaryTree) { this.addMany(anotherTree, []); } @@ -1599,7 +1681,7 @@ export class BinaryTree< * original tree using breadth-first search (bfs), and adds the nodes to the new tree. If a node in * the original tree is null, a null node is added to the cloned tree. If a node */ - clone() { + clone(): TREE { const cloned = this.createTree(); this.bfs( node => { @@ -1663,11 +1745,11 @@ export class BinaryTree< * @returns The `map` function is returning a new `BinaryTree` instance filled with entries that are * the result of applying the provided `callback` function to each entry in the original tree. */ - map( + map( callback: EntryCallback, options?: BinaryTreeOptions, thisArg?: any - ) { + ): BinaryTree { const newTree = new BinaryTree([], options); let index = 0; for (const [key, value] of this) { @@ -1736,49 +1818,6 @@ export class BinaryTree< console.log(this.toVisual(startNode, options)); } - /** - * The function `keyValueNodeEntryRawToNodeAndValue` converts various input types into a node object - * or returns null. - * @param {BTNRep | R} keyNodeEntryOrRaw - The - * `keyValueNodeEntryRawToNodeAndValue` function takes in a parameter `keyNodeEntryOrRaw`, which - * can be of type `BTNRep` or `R`. This parameter represents either a key, a - * node, an entry - * @param {V} [value] - The `value` parameter in the `keyValueNodeEntryRawToNodeAndValue` function is - * an optional parameter of type `V`. It represents the value associated with the key in the node - * being created. If a `value` is provided, it will be used when creating the node. If - * @returns The `keyValueNodeEntryRawToNodeAndValue` function returns an optional node - * (`OptNodeOrNull`) based on the input parameters provided. The function checks the type of the - * input parameter (`keyNodeEntryOrRaw`) and processes it accordingly to return a node or null - * value. - */ - protected _keyValueNodeEntryRawToNodeAndValue( - keyNodeEntryOrRaw: BTNRep | R, - value?: V - ): [OptNodeOrNull, V | undefined] { - if (keyNodeEntryOrRaw === undefined) return [undefined, undefined]; - if (keyNodeEntryOrRaw === null) return [null, undefined]; - - if (this.isNode(keyNodeEntryOrRaw)) return [keyNodeEntryOrRaw, value]; - - if (this.isEntry(keyNodeEntryOrRaw)) { - const [key, entryValue] = keyNodeEntryOrRaw; - if (key === undefined) return [undefined, undefined]; - else if (key === null) return [null, undefined]; - const finalValue = value ?? entryValue; - return [this.createNode(key, finalValue), finalValue]; - } - - if (this.isRaw(keyNodeEntryOrRaw)) { - const [key, entryValue] = this._toEntryFn!(keyNodeEntryOrRaw); - const finalValue = value ?? entryValue; - if (this.isKey(key)) return [this.createNode(key, finalValue), finalValue]; - } - - if (this.isKey(keyNodeEntryOrRaw)) return [this.createNode(keyNodeEntryOrRaw, value), value]; - - return [undefined, undefined]; - } - /** * Time complexity: O(n) * Space complexity: O(n) diff --git a/src/data-structures/binary-tree/bst.ts b/src/data-structures/binary-tree/bst.ts index cfbf55c..976dd6b 100644 --- a/src/data-structures/binary-tree/bst.ts +++ b/src/data-structures/binary-tree/bst.ts @@ -6,6 +6,7 @@ * @license MIT License */ import { + BSTNested, BSTNodeNested, BSTNOptKeyOrNode, BSTOptions, @@ -18,7 +19,8 @@ import { IterationType, NodeCallback, NodePredicate, - OptNode + OptNode, + OptNodeOrNull } from '../../types'; import { BinaryTree, BinaryTreeNode } from './binary-tree'; import { IBinaryTree } from '../../interfaces'; @@ -40,13 +42,13 @@ export class BSTNode = BSTNod this._right = undefined; } - protected override _left?: NODE; + override _left?: OptNodeOrNull; /** * The function returns the value of the `_left` property. * @returns The `_left` property of the current object is being returned. */ - override get left(): OptNode { + override get left(): OptNodeOrNull { return this._left; } @@ -55,21 +57,21 @@ export class BSTNode = BSTNod * @param {OptNode} v - The parameter `v` is of type `OptNode`. It can either be an * instance of the `NODE` class or `undefined`. */ - override set left(v: OptNode) { + override set left(v: OptNodeOrNull) { if (v) { v.parent = this as unknown as NODE; } this._left = v; } - protected override _right?: NODE; + override _right?: OptNodeOrNull; /** * The function returns the right node of a binary tree or undefined if there is no right node. * @returns The method is returning the value of the `_right` property, which is of type `NODE` or * `undefined`. */ - override get right(): OptNode { + override get right(): OptNodeOrNull { return this._right; } @@ -78,7 +80,7 @@ export class BSTNode = BSTNod * @param {OptNode} v - The parameter `v` is of type `OptNode`. It can either be a * `NODE` object or `undefined`. */ - override set right(v: OptNode) { + override set right(v: OptNodeOrNull) { if (v) { v.parent = this as unknown as NODE; } @@ -151,9 +153,27 @@ export class BSTNode = BSTNod * console.log(findLCA(5, 35)); // 15 * console.log(findLCA(20, 30)); // 25 */ -export class BST = BSTNode>> - extends BinaryTree - implements IBinaryTree +export class BST< + K = any, + V = any, + R = object, + MK = any, + MV = any, + MR = object, + NODE extends BSTNode = BSTNode>, + TREE extends BST = BST< + K, + V, + R, + MK, + MV, + MR, + NODE, + BSTNested + > + > + extends BinaryTree + implements IBinaryTree { /** * This is the constructor function for a Binary Search Tree class in TypeScript. @@ -196,45 +216,6 @@ export class BST return this._isReverse; } - protected _comparator: Comparator = (a: K, b: K): number => { - if (isComparable(a) && isComparable(b)) { - if (a > b) return 1; - if (a < b) return -1; - return 0; - } - if (this._specifyComparable) { - if (this._specifyComparable(a) > this._specifyComparable(b)) return 1; - if (this._specifyComparable(a) < this._specifyComparable(b)) return -1; - return 0; - } - if (typeof a === 'object' || typeof b === 'object') { - throw TypeError( - `When comparing object types, a custom specifyComparable must be defined in the constructor's options parameter.` - ); - } - - return 0; - }; - - /** - * The function returns the value of the _comparator property. - * @returns The `_comparator` property is being returned. - */ - get comparator() { - return this._comparator; - } - - protected _specifyComparable?: (key: K) => Comparable; - - /** - * This function returns the value of the `_specifyComparable` property. - * @returns The method `specifyComparable()` is being returned, which is a getter method for the - * `_specifyComparable` property. - */ - get specifyComparable() { - return this._specifyComparable; - } - /** * 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 @@ -248,26 +229,39 @@ export class BST } /** - * Time Complexity: O(1) - * Space Complexity: O(1) - * - * The `createTree` function in TypeScript overrides the default options with the provided options to - * create a new Binary Search Tree. - * @param [options] - The `options` parameter in the `createTree` method is an optional object that - * can contain the following properties: - * @returns A new instance of a Binary Search Tree (BST) is being returned with the specified options - * and properties inherited from the current instance. + * 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. */ - // @ts-ignore - override createTree(options?: BSTOptions) { - return new BST([], { + override createTree(options?: BSTOptions): TREE { + return new BST([], { iterationType: this.iterationType, isMapMode: this._isMapMode, specifyComparable: this._specifyComparable, toEntryFn: this._toEntryFn, isReverse: this._isReverse, ...options - }); + }) as TREE; + } + + /** + * The function overrides a method and converts a key, value pair or entry or raw element to a node. + * @param {BTNRep | R} keyNodeEntryOrRaw - A variable that can be of + * type R or BTNRep. 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 NODE object or undefined. + */ + protected override _keyValueNodeEntryRawToNodeAndValue( + keyNodeEntryOrRaw: BTNRep | R, + value?: V + ): [OptNode, V | undefined] { + const [node, entryValue] = super._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value); + if (node === null) return [undefined, undefined]; + return [node, value ?? entryValue]; } /** @@ -350,7 +344,7 @@ export class BST this._size++; return true; } - current = current.left; + if (current.left !== null) current = current.left; } else { if (current.right === undefined) { current.right = newNode; @@ -358,7 +352,7 @@ export class BST this._size++; return true; } - current = current.right; + if (current.right !== null) current = current.right; } } @@ -483,19 +477,6 @@ export class BST return inserted; } - /** - * Time Complexity: O(n) - * Space Complexity: O(1) - * - * The `merge` function overrides the base class method by adding elements from another - * binary search tree. - * @param anotherTree - `anotherTree` is an instance of a Binary Search Tree (BST) with key type `K`, - * value type `V`, return type `R`, node type `NODE`, and tree type `TREE`. - */ - override merge(anotherTree: this) { - this.addMany(anotherTree, [], false); - } - /** * Time Complexity: O(log n) * Space Complexity: O(k + log n) @@ -906,7 +887,7 @@ export class BST let balanced = true; if (iterationType === 'RECURSIVE') { - const _height = (cur: OptNode): number => { + const _height = (cur: OptNodeOrNull): number => { if (!cur) return 0; const leftHeight = _height(cur.left), rightHeight = _height(cur.right); @@ -923,7 +904,7 @@ export class BST while (stack.length > 0 || node) { if (node) { stack.push(node); - node = node.left; + if (node.left !== null) node = node.left; } else { node = stack[stack.length - 1]; if (!node.right || last === node.right) { @@ -944,36 +925,43 @@ export class BST return balanced; } - // @ts-ignore - override map( - callback: EntryCallback, - options?: BSTOptions, - thisArg?: any - ) { - const newTree = new BST([], options); - let index = 0; - for (const [key, value] of this) { - newTree.add(callback.call(thisArg, key, value, index++, this)); + protected _comparator: Comparator = (a: K, b: K): number => { + if (isComparable(a) && isComparable(b)) { + if (a > b) return 1; + if (a < b) return -1; + return 0; } - return newTree; - } + if (this._specifyComparable) { + if (this._specifyComparable(a) > this._specifyComparable(b)) return 1; + if (this._specifyComparable(a) < this._specifyComparable(b)) return -1; + return 0; + } + if (typeof a === 'object' || typeof b === 'object') { + throw TypeError( + `When comparing object types, a custom specifyComparable must be defined in the constructor's options parameter.` + ); + } + + return 0; + }; /** - * The function overrides a method and converts a key, value pair or entry or raw element to a node. - * @param {BTNRep | R} keyNodeEntryOrRaw - A variable that can be of - * type R or BTNRep. 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 NODE object or undefined. + * The function returns the value of the _comparator property. + * @returns The `_comparator` property is being returned. */ - protected override _keyValueNodeEntryRawToNodeAndValue( - keyNodeEntryOrRaw: BTNRep | R, - value?: V - ): [OptNode, V | undefined] { - const [node, entryValue] = super._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value); - if (node === null) return [undefined, undefined]; - return [node, value ?? entryValue]; + get comparator() { + return this._comparator; + } + + protected _specifyComparable?: (key: K) => Comparable; + + /** + * This function returns the value of the `_specifyComparable` property. + * @returns The method `specifyComparable()` is being returned, which is a getter method for the + * `_specifyComparable` property. + */ + get specifyComparable() { + return this._specifyComparable; } /** @@ -991,4 +979,17 @@ export class BST protected _compare(a: K, b: K) { return this._isReverse ? -this._comparator(a, b) : this._comparator(a, b); } + + override map( + callback: EntryCallback, + options?: BSTOptions, + thisArg?: any + ): BST { + const newTree = new BST([], options); + let index = 0; + for (const [key, value] of this) { + newTree.add(callback.call(thisArg, key, value, index++, this)); + } + return newTree; + } } diff --git a/src/data-structures/binary-tree/red-black-tree.ts b/src/data-structures/binary-tree/red-black-tree.ts index ef3ea87..c16d925 100644 --- a/src/data-structures/binary-tree/red-black-tree.ts +++ b/src/data-structures/binary-tree/red-black-tree.ts @@ -6,6 +6,7 @@ import type { OptNode, RBTNColor, RedBlackTreeOptions, + RedBlackTreeNested, RedBlackTreeNodeNested } from '../../types'; import { BST, BSTNode } from './bst'; @@ -31,24 +32,6 @@ export class RedBlackTreeNode< super(key, value); this._color = color; } - - protected _color: RBTNColor; - - /** - * The function returns the color value of a variable. - * @returns The color value stored in the private variable `_color`. - */ - get color(): RBTNColor { - return this._color; - } - - /** - * The function sets the color property to the specified value. - * @param {RBTNColor} value - The value parameter is of type RBTNColor. - */ - set color(value: RBTNColor) { - this._color = value; - } } /** @@ -108,16 +91,29 @@ export class RedBlackTree< K = any, V = any, R = object, - NODE extends RedBlackTreeNode = RedBlackTreeNode> + MK = any, + MV = any, + MR = object, + NODE extends RedBlackTreeNode = RedBlackTreeNode>, + TREE extends RedBlackTree = RedBlackTree< + K, + V, + R, + MK, + MV, + MR, + NODE, + RedBlackTreeNested + > > - extends BST - implements IBinaryTree + extends BST + implements IBinaryTree { /** * This is the constructor function for a Red-Black Tree data structure in TypeScript. * @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter is an * iterable object that can contain either keys, nodes, entries, or raw elements. It is used to - * initialize the RedBlackTree with the provided elements. + * initialize the RBTree with the provided elements. * @param [options] - The `options` parameter is an optional object that can be passed to the * constructor. It is of type `RedBlackTreeOptions`. This object can contain various options for * configuring the behavior of the Red-Black Tree. The specific properties and their meanings would @@ -162,23 +158,19 @@ export class RedBlackTree< } /** - * The function `createTree` overrides the default implementation to create a Red-Black Tree with - * specified options in TypeScript. - * @param [options] - The `options` parameter in the `createTree` method is of type `RedBlackTreeOptions`, which is a generic type with three type parameters `K`, `V`, and `R`. This parameter - * allows you to pass additional configuration options when creating a new Red- - * @returns A new instance of a RedBlackTree with the specified options and properties from the - * current object is being returned. + * The function creates a new Red-Black Tree with the specified options. + * @param [options] - The `options` parameter is an optional object that contains additional + * configuration options for creating the Red-Black Tree. It has the following properties: + * @returns a new instance of a RedBlackTree object. */ - // @ts-ignore - override createTree(options?: RedBlackTreeOptions) { - return new RedBlackTree([], { + override createTree(options?: RedBlackTreeOptions): TREE { + return new RedBlackTree([], { iterationType: this.iterationType, isMapMode: this._isMapMode, specifyComparable: this._specifyComparable, toEntryFn: this._toEntryFn, ...options - }); + }) as TREE; } /** @@ -276,8 +268,10 @@ export class RedBlackTree< let replacementNode: NODE | undefined; if (!this.isRealNode(nodeToDelete.left)) { - replacementNode = nodeToDelete.right; - this._transplant(nodeToDelete, nodeToDelete.right); + if (nodeToDelete.right !== null) { + replacementNode = nodeToDelete.right; + this._transplant(nodeToDelete, nodeToDelete.right); + } } else if (!this.isRealNode(nodeToDelete.right)) { replacementNode = nodeToDelete.left; this._transplant(nodeToDelete, nodeToDelete.left); @@ -285,15 +279,17 @@ export class RedBlackTree< const successor = this.getLeftMost(node => node, nodeToDelete.right); if (successor) { originalColor = successor.color; - replacementNode = successor.right; + if (successor.right !== null) replacementNode = successor.right; if (successor.parent === nodeToDelete) { if (this.isRealNode(replacementNode)) { replacementNode.parent = successor; } } else { - this._transplant(successor, successor.right); - successor.right = nodeToDelete.right; + if (successor.right !== null) { + this._transplant(successor, successor.right); + successor.right = nodeToDelete.right; + } if (this.isRealNode(successor.right)) { successor.right.parent = successor; } @@ -320,40 +316,6 @@ export class RedBlackTree< return results; } - /** - * Time Complexity: O(n) - * Space Complexity: O(n) - * - * The `map` function in TypeScript overrides the default behavior to create a new Red-Black Tree by - * applying a callback to each entry in the original tree. - * @param callback - A function that will be called for each entry in the tree, with parameters - * representing the key, value, index, and the tree itself. It should return an entry for the new - * tree. - * @param [options] - The `options` parameter in the `map` method is of type `RedBlackTreeOptions`. This parameter allows you to specify additional options or configurations for the Red-Black - * Tree that will be created during the mapping process. These options could include things like - * custom comparators - * @param {any} [thisArg] - The `thisArg` parameter in the `override map` function is used to specify - * the value of `this` when executing the `callback` function. It allows you to set the context - * (value of `this`) for the callback function. This can be useful when you want to access properties - * or - * @returns A new Red-Black Tree is being returned, where each entry has been transformed using the - * provided callback function. - */ - // @ts-ignore - override map( - callback: EntryCallback, - options?: RedBlackTreeOptions, - thisArg?: any - ) { - const newTree = new RedBlackTree([], options); - let index = 0; - for (const [key, value] of this) { - newTree.add(callback.call(thisArg, key, value, index++, this)); - } - return newTree; - } - /** * Time Complexity: O(1) * Space Complexity: O(1) @@ -498,7 +460,7 @@ export class RedBlackTree< } else { // Symmetric case for the right child (left and right exchanged) // Follow the same logic as above with left and right exchanged - const y: NODE | undefined = z?.parent?.parent?.left; + const y: NODE | undefined = z?.parent?.parent?.left ?? undefined; if (y?.color === 'RED') { z.parent.color = 'BLACK'; y.color = 'BLACK'; @@ -675,4 +637,37 @@ export class RedBlackTree< x.right = y; y.parent = x; } + + /** + * Time Complexity: O(n) + * Space Complexity: O(n) + * + * The `map` function in TypeScript overrides the default behavior to create a new Red-Black Tree by + * applying a callback to each entry in the original tree. + * @param callback - A function that will be called for each entry in the tree, with parameters + * representing the key, value, index, and the tree itself. It should return an entry for the new + * tree. + * @param [options] - The `options` parameter in the `map` method is of type `RedBlackTreeOptions`. This parameter allows you to specify additional options or configurations for the Red-Black + * Tree that will be created during the mapping process. These options could include things like + * custom comparators + * @param {any} [thisArg] - The `thisArg` parameter in the `override map` function is used to specify + * the value of `this` when executing the `callback` function. It allows you to set the context + * (value of `this`) for the callback function. This can be useful when you want to access properties + * or + * @returns A new Red-Black Tree is being returned, where each entry has been transformed using the + * provided callback function. + */ + override map( + callback: EntryCallback, + options?: RedBlackTreeOptions, + thisArg?: any + ): RedBlackTree { + const newTree = new RedBlackTree([], options); + let index = 0; + for (const [key, value] of this) { + newTree.add(callback.call(thisArg, key, value, index++, this)); + } + return newTree; + } } diff --git a/src/data-structures/binary-tree/tree-multi-map.ts b/src/data-structures/binary-tree/tree-multi-map.ts index 7099311..1e17a7d 100644 --- a/src/data-structures/binary-tree/tree-multi-map.ts +++ b/src/data-structures/binary-tree/tree-multi-map.ts @@ -13,6 +13,7 @@ import type { IterationType, OptNode, RBTNColor, + TreeMultiMapNested, TreeMultiMapNodeNested, TreeMultiMapOptions } from '../../types'; @@ -40,35 +41,29 @@ export class TreeMultiMapNode< super(key, value, color); this.count = count; } - - protected _count: number = 1; - - /** - * The function returns the value of the private variable _count. - * @returns The count property of the object, which is of type number. - */ - get count(): number { - return this._count; - } - - /** - * The above function sets the value of the count property. - * @param {number} value - The value parameter is of type number, which means it can accept any - * numeric value. - */ - set count(value: number) { - this._count = value; - } } export class TreeMultiMap< K = any, V = any, R = object, - NODE extends TreeMultiMapNode = TreeMultiMapNode> + MK = any, + MV = any, + MR = object, + NODE extends TreeMultiMapNode = TreeMultiMapNode>, + TREE extends TreeMultiMap = TreeMultiMap< + K, + V, + R, + MK, + MV, + MR, + NODE, + TreeMultiMapNested + > > - extends RedBlackTree - implements IBinaryTree + extends RedBlackTree + implements IBinaryTree { /** * The constructor function initializes a TreeMultiMap object with optional initial data. @@ -134,15 +129,53 @@ export class TreeMultiMap< * @returns a new instance of the `TreeMultiMap` class, with the provided options merged with the * existing `iterationType` property. The returned value is casted as `TREE`. */ - // @ts-ignore - override createTree(options?: TreeMultiMapOptions) { - return new TreeMultiMap([], { + override createTree(options?: TreeMultiMapOptions): TREE { + return new TreeMultiMap([], { iterationType: this.iterationType, isMapMode: this._isMapMode, specifyComparable: this._specifyComparable, toEntryFn: this._toEntryFn, ...options - }); + }) as TREE; + } + + /** + * The function `keyValueNodeEntryRawToNodeAndValue` takes in a key, value, and count and returns a + * node based on the input. + * @param {BTNRep | R} keyNodeEntryOrRaw - The parameter + * `keyNodeEntryOrRaw` can be of type `R` or `BTNRep`. + * @param {V} [value] - The `value` parameter is an optional value that represents the value + * associated with the key in the node. It is used when creating a new node or updating the value of + * an existing node. + * @param [count=1] - The `count` parameter is an optional parameter that specifies the number of + * times the key-value pair should be added to the data structure. If not provided, it defaults to 1. + * @returns either a NODE object or undefined. + */ + protected override _keyValueNodeEntryRawToNodeAndValue( + keyNodeEntryOrRaw: BTNRep | R, + value?: V, + count = 1 + ): [NODE | undefined, V | undefined] { + if (keyNodeEntryOrRaw === undefined || keyNodeEntryOrRaw === null) return [undefined, undefined]; + + if (this.isNode(keyNodeEntryOrRaw)) return [keyNodeEntryOrRaw, value]; + + if (this.isEntry(keyNodeEntryOrRaw)) { + const [key, entryValue] = keyNodeEntryOrRaw; + if (key === undefined || key === null) return [undefined, undefined]; + const finalValue = value ?? entryValue; + if (this.isKey(key)) return [this.createNode(key, finalValue, 'BLACK', count), finalValue]; + } + + if (this.isRaw(keyNodeEntryOrRaw)) { + const [key, entryValue] = this._toEntryFn!(keyNodeEntryOrRaw); + const finalValue = value ?? entryValue; + if (this.isKey(key)) return [this.createNode(key, finalValue, 'BLACK', count), finalValue]; + } + + if (this.isKey(keyNodeEntryOrRaw)) return [this.createNode(keyNodeEntryOrRaw, value, 'BLACK', count), value]; + + return [undefined, undefined]; } /** @@ -217,10 +250,12 @@ export class TreeMultiMap< let replacementNode: NODE | undefined; if (!this.isRealNode(nodeToDelete.left)) { - replacementNode = nodeToDelete.right; + if (nodeToDelete.right !== null) replacementNode = nodeToDelete.right; if (ignoreCount || nodeToDelete.count <= 1) { - this._transplant(nodeToDelete, nodeToDelete.right); - this._count -= nodeToDelete.count; + if (nodeToDelete.right !== null) { + this._transplant(nodeToDelete, nodeToDelete.right); + this._count -= nodeToDelete.count; + } } else { nodeToDelete.count--; this._count--; @@ -242,7 +277,7 @@ export class TreeMultiMap< const successor = this.getLeftMost(node => node, nodeToDelete.right); if (successor) { originalColor = successor.color; - replacementNode = successor.right; + if (successor.right !== null) replacementNode = successor.right; if (successor.parent === nodeToDelete) { if (this.isRealNode(replacementNode)) { @@ -250,8 +285,10 @@ export class TreeMultiMap< } } else { if (ignoreCount || nodeToDelete.count <= 1) { - this._transplant(successor, successor.right); - this._count -= nodeToDelete.count; + if (successor.right !== null) { + this._transplant(successor, successor.right); + this._count -= nodeToDelete.count; + } } else { nodeToDelete.count--; this._count--; @@ -363,82 +400,13 @@ export class TreeMultiMap< * The function overrides the clone method to create a deep copy of a tree object. * @returns The `clone()` method is returning a cloned instance of the `TREE` object. */ - // @ts-ignore - override clone() { + override clone(): TREE { const cloned = this.createTree(); this.bfs(node => cloned.add(node.key, undefined, node.count)); if (this._isMapMode) cloned._store = this._store; return cloned; } - /** - * The `map` function in TypeScript overrides the default behavior to create a new TreeMultiMap with - * modified entries based on a provided callback. - * @param callback - The `callback` parameter is a function that will be called for each entry in the - * map. It takes four arguments: - * @param [options] - The `options` parameter in the `override map` function is of type - * `TreeMultiMapOptions`. This parameter allows you to provide additional configuration - * options when creating a new `TreeMultiMap` instance within the `map` function. These options could - * include things like - * @param {any} [thisArg] - The `thisArg` parameter in the `override map` function is used to specify - * the value of `this` when executing the `callback` function. It allows you to set the context - * (value of `this`) for the callback function when it is called within the `map` function. This - * @returns A new TreeMultiMap instance is being returned, which is populated with entries generated - * by the provided callback function. - */ - // @ts-ignore - override map( - callback: EntryCallback, - options?: TreeMultiMapOptions, - thisArg?: any - ) { - const newTree = new TreeMultiMap([], options); - let index = 0; - for (const [key, value] of this) { - newTree.add(callback.call(thisArg, key, value, index++, this)); - } - return newTree; - } - - /** - * The function `keyValueNodeEntryRawToNodeAndValue` takes in a key, value, and count and returns a - * node based on the input. - * @param {BTNRep | R} keyNodeEntryOrRaw - The parameter - * `keyNodeEntryOrRaw` can be of type `R` or `BTNRep`. - * @param {V} [value] - The `value` parameter is an optional value that represents the value - * associated with the key in the node. It is used when creating a new node or updating the value of - * an existing node. - * @param [count=1] - The `count` parameter is an optional parameter that specifies the number of - * times the key-value pair should be added to the data structure. If not provided, it defaults to 1. - * @returns either a NODE object or undefined. - */ - protected override _keyValueNodeEntryRawToNodeAndValue( - keyNodeEntryOrRaw: BTNRep | R, - value?: V, - count = 1 - ): [NODE | undefined, V | undefined] { - if (keyNodeEntryOrRaw === undefined || keyNodeEntryOrRaw === null) return [undefined, undefined]; - - if (this.isNode(keyNodeEntryOrRaw)) return [keyNodeEntryOrRaw, value]; - - if (this.isEntry(keyNodeEntryOrRaw)) { - const [key, entryValue] = keyNodeEntryOrRaw; - if (key === undefined || key === null) return [undefined, undefined]; - const finalValue = value ?? entryValue; - if (this.isKey(key)) return [this.createNode(key, finalValue, 'BLACK', count), finalValue]; - } - - if (this.isRaw(keyNodeEntryOrRaw)) { - const [key, entryValue] = this._toEntryFn!(keyNodeEntryOrRaw); - const finalValue = value ?? entryValue; - if (this.isKey(key)) return [this.createNode(key, finalValue, 'BLACK', count), finalValue]; - } - - if (this.isKey(keyNodeEntryOrRaw)) return [this.createNode(keyNodeEntryOrRaw, value, 'BLACK', count), value]; - - return [undefined, undefined]; - } - /** * Time Complexity: O(1) * Space Complexity: O(1) @@ -496,4 +464,32 @@ export class TreeMultiMap< newNode.count = oldNode.count + newNode.count; return super._replaceNode(oldNode, newNode); } + + /** + * The `map` function in TypeScript overrides the default behavior to create a new TreeMultiMap with + * modified entries based on a provided callback. + * @param callback - The `callback` parameter is a function that will be called for each entry in the + * map. It takes four arguments: + * @param [options] - The `options` parameter in the `override map` function is of type + * `TreeMultiMapOptions`. This parameter allows you to provide additional configuration + * options when creating a new `TreeMultiMap` instance within the `map` function. These options could + * include things like + * @param {any} [thisArg] - The `thisArg` parameter in the `override map` function is used to specify + * the value of `this` when executing the `callback` function. It allows you to set the context + * (value of `this`) for the callback function when it is called within the `map` function. This + * @returns A new TreeMultiMap instance is being returned, which is populated with entries generated + * by the provided callback function. + */ + override map( + callback: EntryCallback, + options?: TreeMultiMapOptions, + thisArg?: any + ): TreeMultiMap { + const newTree = new TreeMultiMap([], options); + let index = 0; + for (const [key, value] of this) { + newTree.add(callback.call(thisArg, key, value, index++, this)); + } + return newTree; + } } diff --git a/src/interfaces/binary-tree.ts b/src/interfaces/binary-tree.ts index d45e87c..a5f8dad 100644 --- a/src/interfaces/binary-tree.ts +++ b/src/interfaces/binary-tree.ts @@ -1,14 +1,27 @@ -import { BinaryTreeNode } from '../data-structures'; -import type { BinaryTreeDeleteResult, BinaryTreeNodeNested, BTNRep, NodePredicate } from '../types'; +import { BinaryTree, BinaryTreeNode } from '../data-structures'; +import type { + BinaryTreeDeleteResult, + BinaryTreeNested, + BinaryTreeNodeNested, + BinaryTreeOptions, + BTNRep, + NodePredicate +} from '../types'; export interface IBinaryTree< K = any, V = any, R = object, - NODE extends BinaryTreeNode = BinaryTreeNodeNested + MK = any, + MV = any, + MR = object, + NODE extends BinaryTreeNode = BinaryTreeNodeNested, + TREE extends BinaryTree = BinaryTreeNested > { createNode(key: K, value?: NODE['value']): NODE; + createTree(options?: Partial>): TREE; + add(keyOrNodeOrEntryOrRawElement: BTNRep, value?: V, count?: number): boolean; addMany(nodes: Iterable>, values?: Iterable): boolean[]; diff --git a/src/types/data-structures/binary-tree/avl-tree-multi-map.ts b/src/types/data-structures/binary-tree/avl-tree-multi-map.ts index 1e6ab4a..059a76d 100644 --- a/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +++ b/src/types/data-structures/binary-tree/avl-tree-multi-map.ts @@ -1,6 +1,8 @@ -import { AVLTreeMultiMapNode } from '../../../data-structures'; +import { AVLTreeMultiMap, AVLTreeMultiMapNode } from '../../../data-structures'; import type { AVLTreeOptions } from './avl-tree'; -export type AVLTreeMultiMapNodeNested = AVLTreeMultiMapNode>>>>>>>>> +export type AVLTreeMultiMapNodeNested = AVLTreeMultiMapNode>> + +export type AVLTreeMultiMapNested> = AVLTreeMultiMap>> export type AVLTreeMultiMapOptions = AVLTreeOptions & {} diff --git a/src/types/data-structures/binary-tree/avl-tree.ts b/src/types/data-structures/binary-tree/avl-tree.ts index c8f0b54..1411764 100644 --- a/src/types/data-structures/binary-tree/avl-tree.ts +++ b/src/types/data-structures/binary-tree/avl-tree.ts @@ -1,6 +1,8 @@ -import { AVLTreeNode } from '../../../data-structures'; +import { AVLTree, AVLTreeNode } from '../../../data-structures'; import { BSTOptions } from './bst'; -export type AVLTreeNodeNested = AVLTreeNode>>>>>>>>> +export type AVLTreeNodeNested = AVLTreeNode>> + +export type AVLTreeNested> = AVLTree>> export type AVLTreeOptions = BSTOptions & {}; diff --git a/src/types/data-structures/binary-tree/binary-tree.ts b/src/types/data-structures/binary-tree/binary-tree.ts index cdd4a08..dfc05a9 100644 --- a/src/types/data-structures/binary-tree/binary-tree.ts +++ b/src/types/data-structures/binary-tree/binary-tree.ts @@ -1,10 +1,10 @@ -import { BinaryTreeNode } from '../../../data-structures'; +import { BinaryTree, BinaryTreeNode } from '../../../data-structures'; import { IterationType, OptValue } from '../../common'; import { DFSOperation } from '../../../common'; -export type BinaryTreeNodeNested = BinaryTreeNode>>>>>>>>> +export type BinaryTreeNodeNested = BinaryTreeNode>> -// export type BinaryTreeNested> = BinaryTree>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +export type BinaryTreeNested> = BinaryTree>> export type ToEntryFn = (rawElement: R) => BTNEntry; diff --git a/src/types/data-structures/binary-tree/bst.ts b/src/types/data-structures/binary-tree/bst.ts index ccc3042..5a40bf1 100644 --- a/src/types/data-structures/binary-tree/bst.ts +++ b/src/types/data-structures/binary-tree/bst.ts @@ -1,8 +1,10 @@ -import { BSTNode } from '../../../data-structures'; +import { BST, BSTNode } from '../../../data-structures'; import type { BinaryTreeOptions } from './binary-tree'; import { Comparable } from '../../utils'; -export type BSTNodeNested = BSTNode>>>>>>>>> +export type BSTNodeNested = BSTNode>> + +export type BSTNested> = BST>> export type BSTOptions = BinaryTreeOptions & { specifyComparable?: (key: K) => Comparable diff --git a/src/types/data-structures/binary-tree/rb-tree.ts b/src/types/data-structures/binary-tree/rb-tree.ts index 743fe3a..2f813b2 100644 --- a/src/types/data-structures/binary-tree/rb-tree.ts +++ b/src/types/data-structures/binary-tree/rb-tree.ts @@ -1,8 +1,10 @@ -import { RedBlackTreeNode } from '../../../data-structures'; -import type { BSTOptions } from './bst'; +import { RedBlackTree, RedBlackTreeNode } from '../../../data-structures'; +import type { BSTOptions } from "./bst"; export type RBTNColor = 'RED' | 'BLACK'; -export type RedBlackTreeNodeNested = RedBlackTreeNode>>>>>>>>> +export type RedBlackTreeNodeNested = RedBlackTreeNode>> -export type RedBlackTreeOptions = Omit, 'isReverse'> & {}; +export type RedBlackTreeNested> = RedBlackTree>> + +export type RedBlackTreeOptions = BSTOptions & {}; diff --git a/src/types/data-structures/binary-tree/tree-multi-map.ts b/src/types/data-structures/binary-tree/tree-multi-map.ts index ed7918c..47ee09d 100644 --- a/src/types/data-structures/binary-tree/tree-multi-map.ts +++ b/src/types/data-structures/binary-tree/tree-multi-map.ts @@ -1,6 +1,8 @@ -import { TreeMultiMapNode } from '../../../data-structures'; +import { TreeMultiMap, TreeMultiMapNode } from '../../../data-structures'; import type { RedBlackTreeOptions } from './rb-tree'; -export type TreeMultiMapNodeNested = TreeMultiMapNode>>>>>>>>> +export type TreeMultiMapNodeNested = TreeMultiMapNode>> + +export type TreeMultiMapNested> = TreeMultiMap>> export type TreeMultiMapOptions = RedBlackTreeOptions & {}