diff --git a/README.md b/README.md index f8df6be..cf56bb8 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ [//]: # (

English | 简体中文

) +> ***Our goal is to make every data structure as convenient and efficient as JavaScript's Array.*** + ## Installation and Usage ### npm @@ -212,6 +214,7 @@ Performance surpasses that of native JS/TS ### Conciseness and uniformity + In [java.utils](), you need to memorize a table for all sequential data structures(Queue, Deque, LinkedList), @@ -710,24 +713,24 @@ bst.print() const objBST = new BST(); -objBST.add(11, { "name": "Pablo", "age": 15 }); -objBST.add(3, { "name": "Kirk", "age": 1 }); +objBST.add(11, { "name": "Pablo", "size": 15 }); +objBST.add(3, { "name": "Kirk", "size": 1 }); objBST.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5], [ - { "name": "Alice", "age": 15 }, - { "name": "Bob", "age": 1 }, - { "name": "Charlie", "age": 8 }, - { "name": "David", "age": 13 }, - { "name": "Emma", "age": 16 }, - { "name": "Frank", "age": 2 }, - { "name": "Grace", "age": 6 }, - { "name": "Hannah", "age": 9 }, - { "name": "Isaac", "age": 12 }, - { "name": "Jack", "age": 14 }, - { "name": "Katie", "age": 4 }, - { "name": "Liam", "age": 7 }, - { "name": "Mia", "age": 10 }, - { "name": "Noah", "age": 5 } + { "name": "Alice", "size": 15 }, + { "name": "Bob", "size": 1 }, + { "name": "Charlie", "size": 8 }, + { "name": "David", "size": 13 }, + { "name": "Emma", "size": 16 }, + { "name": "Frank", "size": 2 }, + { "name": "Grace", "size": 6 }, + { "name": "Hannah", "size": 9 }, + { "name": "Isaac", "size": 12 }, + { "name": "Jack", "size": 14 }, + { "name": "Katie", "size": 4 }, + { "name": "Liam", "size": 7 }, + { "name": "Mia", "size": 10 }, + { "name": "Noah", "size": 5 } ] ); @@ -823,43 +826,43 @@ Version 11.7.9 [//]: # (No deletion!!! Start of Replace Section)
heap
-
test nametime taken (ms)executions per secsample deviation
100,000 add6.56152.371.86e-4
100,000 add & poll35.1528.457.98e-4
+
test nametime taken (ms)executions per secsample deviation
100,000 add6.49154.001.90e-4
100,000 add & poll35.7927.940.01
rb-tree
-
test nametime taken (ms)executions per secsample deviation
100,000 add83.5411.978.43e-4
100,000 add randomly85.5311.690.00
100,000 get115.178.680.00
100,000 iterator30.2033.110.00
100,000 add & delete orderly151.056.620.00
100,000 add & delete randomly239.324.180.01
+
test nametime taken (ms)executions per secsample deviation
100,000 add85.3011.727.38e-4
100,000 add randomly84.7711.800.00
100,000 get113.748.790.00
100,000 iterator24.5140.800.00
100,000 add & delete orderly152.176.570.01
100,000 add & delete randomly240.784.150.01
queue
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push44.3122.570.01
100,000 push & shift5.50181.720.00
Native JS Array 100,000 push & shift2451.350.410.39
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push44.1622.640.01
100,000 push & shift6.08164.580.00
Native JS Array 100,000 push & shift2240.740.450.17
deque
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push20.5648.650.00
1,000,000 push & pop25.7738.810.00
1,000,000 push & shift26.3537.950.00
100,000 push & shift2.54394.254.24e-4
Native JS Array 100,000 push & shift2109.720.470.12
100,000 unshift & shift2.43411.243.06e-4
Native JS Array 100,000 unshift & shift4275.220.230.35
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push20.7548.190.00
1,000,000 push & pop26.8537.240.00
1,000,000 push & shift27.5636.280.00
100,000 push & shift2.61382.754.11e-4
Native JS Array 100,000 push & shift2388.650.420.15
100,000 unshift & shift2.50399.533.59e-4
Native JS Array 100,000 unshift & shift4343.520.230.30
hash-map
-
test nametime taken (ms)executions per secsample deviation
1,000,000 set85.0911.750.02
Native JS Map 1,000,000 set211.604.730.03
Native JS Set 1,000,000 add165.566.040.01
1,000,000 set & get78.9312.670.02
Native JS Map 1,000,000 set & get273.563.660.00
Native JS Set 1,000,000 add & has241.874.130.03
1,000,000 ObjKey set & get339.572.940.04
Native JS Map 1,000,000 ObjKey set & get294.223.400.02
Native JS Set 1,000,000 ObjKey add & has268.413.730.03
+
test nametime taken (ms)executions per secsample deviation
1,000,000 set87.1211.480.02
Native JS Map 1,000,000 set211.634.730.03
Native JS Set 1,000,000 add167.625.970.01
1,000,000 set & get78.9112.670.02
Native JS Map 1,000,000 set & get295.473.380.03
Native JS Set 1,000,000 add & has267.223.740.07
1,000,000 ObjKey set & get378.262.640.06
Native JS Map 1,000,000 ObjKey set & get344.042.910.06
Native JS Set 1,000,000 ObjKey add & has277.873.600.04
trie
-
test nametime taken (ms)executions per secsample deviation
100,000 push43.8922.788.04e-4
100,000 getWords82.9012.060.00
+
test nametime taken (ms)executions per secsample deviation
100,000 push42.6723.448.55e-4
100,000 getWords82.5112.120.00
avl-tree
-
test nametime taken (ms)executions per secsample deviation
100,000 add281.553.550.00
100,000 add randomly353.662.830.02
100,000 get150.336.650.01
100,000 iterator33.2630.070.01
100,000 add & delete orderly465.242.150.00
100,000 add & delete randomly634.771.580.02
+
test nametime taken (ms)executions per secsample deviation
100,000 add307.423.259.13e-4
100,000 add randomly373.752.680.01
100,000 get172.235.810.00
100,000 iterator25.9038.610.00
100,000 add & delete orderly509.581.960.00
100,000 add & delete randomly690.441.450.02
binary-tree-overall
-
test nametime taken (ms)executions per secsample deviation
10,000 RBTree add randomly7.62131.298.51e-5
10,000 RBTree get randomly10.5095.205.32e-5
10,000 RBTree add & delete randomly20.6948.331.32e-4
10,000 AVLTree add randomly25.6838.942.47e-4
10,000 AVLTree get randomly10.9591.296.68e-5
10,000 AVLTree add & delete randomly48.3320.693.14e-4
+
test nametime taken (ms)executions per secsample deviation
10,000 RBTree add randomly7.45134.140.00
10,000 RBTree get randomly13.0376.741.43e-4
10,000 RBTree add & delete randomly22.6244.211.83e-4
10,000 AVLTree add randomly28.4435.162.71e-4
10,000 AVLTree get randomly13.0276.811.05e-4
10,000 AVLTree add & delete randomly54.4618.360.00
directed-graph
-
test nametime taken (ms)executions per secsample deviation
1,000 addVertex0.101.03e+41.01e-6
1,000 addEdge5.95168.011.05e-4
1,000 getVertex0.101.05e+41.10e-6
1,000 getEdge23.4442.670.00
tarjan194.665.140.00
topologicalSort151.886.580.01
+
test nametime taken (ms)executions per secsample deviation
1,000 addVertex0.101.01e+48.01e-7
1,000 addEdge6.06165.032.89e-4
1,000 getVertex0.101.05e+49.35e-7
1,000 getEdge23.8042.020.00
tarjan193.595.170.01
topologicalSort148.996.710.01
doubly-linked-list
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push191.435.220.04
1,000,000 unshift171.355.840.01
1,000,000 unshift & shift151.256.610.00
1,000,000 addBefore264.873.780.07
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push191.055.230.04
1,000,000 unshift186.385.370.06
1,000,000 unshift & shift151.276.610.00
1,000,000 addBefore267.573.740.07
singly-linked-list
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push & shift173.295.770.05
10,000 push & pop235.534.250.01
10,000 addBefore278.193.590.01
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push & shift163.016.130.03
10,000 push & pop246.054.060.04
10,000 addBefore275.543.630.01
priority-queue
-
test nametime taken (ms)executions per secsample deviation
100,000 add30.6432.640.00
100,000 add & poll89.2511.200.00
+
test nametime taken (ms)executions per secsample deviation
100,000 add30.5432.750.00
100,000 add & poll89.2011.210.00
stack
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push40.9224.440.00
1,000,000 push & pop46.8321.350.01
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push40.4224.740.00
1,000,000 push & pop47.9020.880.01
[//]: # (No deletion!!! End of Replace Section) @@ -1218,4 +1221,4 @@ const { AVLTree, MinHeap, SinglyLinkedList, DirectedGraph, TreeMultiMap, DirectedVertex, AVLTreeNode } = dataStructureTyped; -``` \ No newline at end of file +``` diff --git a/src/constants/index.ts b/src/constants/index.ts new file mode 100644 index 0000000..f91c437 --- /dev/null +++ b/src/constants/index.ts @@ -0,0 +1,4 @@ +export enum DFSOperation { + VISIT = 0, + PROCESS = 1 +} 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 06d7371..bdfc1ad 100644 --- a/src/data-structures/binary-tree/avl-tree-multi-map.ts +++ b/src/data-structures/binary-tree/avl-tree-multi-map.ts @@ -1,8 +1,8 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import type { @@ -11,11 +11,11 @@ import type { AVLTreeMultiMapOptions, BinaryTreeDeleteResult, BSTNKeyOrNode, - BTNCallback, BTNKeyOrNodeOrEntry, - IterationType + BTNPredicate, + IterationType, + BTNEntry } from '../../types'; -import { BTNEntry } from '../../types'; import { IBinaryTree } from '../../interfaces'; import { AVLTree, AVLTreeNode } from './avl-tree'; @@ -80,18 +80,18 @@ export class AVLTreeMultiMap< { /** * The constructor initializes a new AVLTreeMultiMap object with optional initial elements. - * @param keysOrNodesOrEntriesOrRawElements - The `keysOrNodesOrEntriesOrRawElements` parameter is an + * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter is an * iterable object that can contain either keys, nodes, entries, or raw elements. * @param [options] - The `options` parameter is an optional object that can be used to customize the * behavior of the AVLTreeMultiMap. It can include properties such as `compareKeys` and * `compareValues` functions to define custom comparison logic for keys and values, respectively. */ constructor( - keysOrNodesOrEntriesOrRawElements: Iterable> = [], + keysOrNodesOrEntriesOrRaws: Iterable> = [], options?: AVLTreeMultiMapOptions ) { super([], options); - if (keysOrNodesOrEntriesOrRawElements) this.addMany(keysOrNodesOrEntriesOrRawElements); + if (keysOrNodesOrEntriesOrRaws) this.addMany(keysOrNodesOrEntriesOrRaws); } protected _count = 0; @@ -144,29 +144,28 @@ export class AVLTreeMultiMap< override createTree(options?: AVLTreeMultiMapOptions): TREE { return new AVLTreeMultiMap([], { iterationType: this.iterationType, - comparator: this.comparator, + comparator: this._comparator, + toEntryFn: this._toEntryFn, ...options }) as TREE; } /** * The function checks if the input is an instance of AVLTreeMultiMapNode. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The parameter - * `keyOrNodeOrEntryOrRawElement` can be of type `R` or `BTNKeyOrNodeOrEntry`. - * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRawElement` is + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The parameter + * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry`. + * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is * an instance of the `AVLTreeMultiMapNode` class. */ - override isNode( - keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry - ): keyOrNodeOrEntryOrRawElement is NODE { - return keyOrNodeOrEntryOrRawElement instanceof AVLTreeMultiMapNode; + override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R): keyOrNodeOrEntryOrRaw is NODE { + return keyOrNodeOrEntryOrRaw instanceof AVLTreeMultiMapNode; } /** * The function `keyValueOrEntryOrRawElementToNode` converts a key, value, entry, or raw element into * a node object. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The - * `keyOrNodeOrEntryOrRawElement` parameter can be of type `R` or `BTNKeyOrNodeOrEntry`. + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The + * `keyOrNodeOrEntryOrRaw` parameter can be of type `R` or `BTNKeyOrNodeOrEntry`. * @param {V} [value] - The `value` parameter is an optional value that can be passed to the * `override` function. It represents the value associated with the key in the data structure. If no * value is provided, it will default to `undefined`. @@ -175,25 +174,25 @@ export class AVLTreeMultiMap< * @returns either a NODE object or undefined. */ override keyValueOrEntryOrRawElementToNode( - keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry, + keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R, value?: V, count = 1 ): NODE | undefined { - if (keyOrNodeOrEntryOrRawElement === undefined || keyOrNodeOrEntryOrRawElement === null) return; - if (this.isNode(keyOrNodeOrEntryOrRawElement)) return keyOrNodeOrEntryOrRawElement; + if (keyOrNodeOrEntryOrRaw === undefined || keyOrNodeOrEntryOrRaw === null) return; + if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw; - if (this.isEntry(keyOrNodeOrEntryOrRawElement)) { - const [key, entryValue] = keyOrNodeOrEntryOrRawElement; + if (this.isEntry(keyOrNodeOrEntryOrRaw)) { + const [key, entryValue] = keyOrNodeOrEntryOrRaw; if (key === undefined || key === null) return; if (this.isKey(key)) return this.createNode(key, value ?? entryValue, count); } - if (this.toEntryFn) { - const [key, entryValue] = this.toEntryFn(keyOrNodeOrEntryOrRawElement as R); + if (this._toEntryFn) { + const [key, entryValue] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R); if (this.isKey(key)) return this.createNode(key, value ?? entryValue, count); } - if (this.isKey(keyOrNodeOrEntryOrRawElement)) return this.createNode(keyOrNodeOrEntryOrRawElement, value, count); + if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.createNode(keyOrNodeOrEntryOrRaw, value, count); return; } @@ -204,8 +203,8 @@ export class AVLTreeMultiMap< * * The function overrides the add method of a TypeScript class to add a new node to a data structure * and update the count. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The - * `keyOrNodeOrEntryOrRawElement` parameter can accept a value of type `R`, which can be any type. It + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The + * `keyOrNodeOrEntryOrRaw` parameter can accept a value of type `R`, which can be any type. It * can also accept a value of type `BTNKeyOrNodeOrEntry`, which represents a key, node, * entry, or raw element * @param {V} [value] - The `value` parameter represents the value associated with the key in the @@ -215,8 +214,8 @@ export class AVLTreeMultiMap< * be added once. However, you can specify a different value for `count` if you want to add * @returns a boolean value. */ - override add(keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry, value?: V, count = 1): boolean { - const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement, value, count); + override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R, value?: V, count = 1): boolean { + const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value, count); if (newNode === undefined) return false; const orgNodeCount = newNode?.count || 0; @@ -231,31 +230,29 @@ export class AVLTreeMultiMap< * Time Complexity: O(log n) * Space Complexity: O(1) * - * The `delete` function in a binary tree data structure deletes a node based on its identifier and - * returns the deleted node along with the parent node that needs to be balanced. - * @param identifier - The identifier parameter is the value used to identify the node that needs to - * be deleted from the binary tree. It can be of any type and is the return type of the callback - * function. - * @param {C} callback - The `callback` parameter is a function that is used to determine the - * equality of nodes in the binary tree. It is optional and has a default value of - * `this._DEFAULT_CALLBACK`. The `callback` function takes a single argument, which is the identifier - * of a node, and returns a value that - * @param [ignoreCount=false] - A boolean flag indicating whether to ignore the count of the node - * being deleted. If set to true, the count of the node will not be considered and the node will be - * deleted regardless of its count. If set to false (default), the count of the node will be taken - * into account and the node - * @returns an array of `BinaryTreeDeleteResult`. + * The function overrides the delete method in a binary tree data structure, handling deletion of + * nodes and maintaining balance in the tree. + * @param {BTNKeyOrNodeOrEntry | R | BTNPredicate} predicate - The `predicate` + * parameter in the `delete` method is used to specify the condition for deleting a node from the + * binary tree. It can be a key, node, entry, or a custom predicate function that determines which + * node(s) should be deleted. + * @param [ignoreCount=false] - The `ignoreCount` parameter in the `override delete` method is a + * boolean flag that determines whether to ignore the count of the node being deleted. If + * `ignoreCount` is set to `true`, the method will delete the node regardless of its count. If + * `ignoreCount` is set to + * @returns The `delete` method overrides the default delete behavior in a binary tree data + * structure. It takes a predicate or node to be deleted and an optional flag to ignore count. The + * method returns an array of `BinaryTreeDeleteResult` objects, each containing information about the + * deleted node and whether balancing is needed in the tree. */ - override delete>( - identifier: ReturnType, - callback: C = this._DEFAULT_CALLBACK as C, + override delete( + predicate: BTNKeyOrNodeOrEntry | R | BTNPredicate, ignoreCount = false ): BinaryTreeDeleteResult[] { const deletedResult: BinaryTreeDeleteResult[] = []; if (!this.root) return deletedResult; - callback = this._ensureCallback(identifier, callback); - const curr: NODE | undefined = this.getNode(identifier, callback) ?? undefined; + const curr: NODE | undefined = this.getNode(predicate) ?? undefined; if (!curr) return deletedResult; const parent: NODE | undefined = curr?.parent ? curr.parent : undefined; @@ -293,7 +290,7 @@ export class AVLTreeMultiMap< } } } - this._size = this.size - 1; + this._size = this._size - 1; // TODO How to handle when the count of target node is lesser than current node's count if (orgCurrent) this._count -= orgCurrent.count; } diff --git a/src/data-structures/binary-tree/avl-tree.ts b/src/data-structures/binary-tree/avl-tree.ts index 1105495..f40030a 100644 --- a/src/data-structures/binary-tree/avl-tree.ts +++ b/src/data-structures/binary-tree/avl-tree.ts @@ -1,8 +1,8 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import { BST, BSTNode } from './bst'; @@ -12,10 +12,10 @@ import type { AVLTreeOptions, BinaryTreeDeleteResult, BSTNKeyOrNode, - BTNCallback, - BTNKeyOrNodeOrEntry + BTNKeyOrNodeOrEntry, + BTNPredicate, + BTNEntry } from '../../types'; -import { BTNEntry } from '../../types'; import { IBinaryTree } from '../../interfaces'; export class AVLTreeNode< @@ -78,7 +78,7 @@ export class AVLTree< /** * This is a constructor function for an AVLTree class that initializes the tree with keys, nodes, * entries, or raw elements. - * @param keysOrNodesOrEntriesOrRawElements - The `keysOrNodesOrEntriesOrRawElements` parameter is an + * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter is an * iterable object that can contain either keys, nodes, entries, or raw elements. These elements will * be used to initialize the AVLTree. * @param [options] - The `options` parameter is an optional object that can be used to customize the @@ -87,11 +87,11 @@ export class AVLTree< * `nodeBuilder` ( */ constructor( - keysOrNodesOrEntriesOrRawElements: Iterable> = [], + keysOrNodesOrEntriesOrRaws: Iterable> = [], options?: AVLTreeOptions ) { super([], options); - if (keysOrNodesOrEntriesOrRawElements) super.addMany(keysOrNodesOrEntriesOrRawElements); + if (keysOrNodesOrEntriesOrRaws) super.addMany(keysOrNodesOrEntriesOrRaws); } /** @@ -117,22 +117,21 @@ export class AVLTree< override createTree(options?: AVLTreeOptions): TREE { return new AVLTree([], { iterationType: this.iterationType, - comparator: this.comparator, + comparator: this._comparator, + toEntryFn: this._toEntryFn, ...options }) as TREE; } /** * The function checks if the input is an instance of AVLTreeNode. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The parameter - * `keyOrNodeOrEntryOrRawElement` can be of type `R` or `BTNKeyOrNodeOrEntry`. - * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRawElement` is + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The parameter + * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry`. + * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is * an instance of the `AVLTreeNode` class. */ - override isNode( - keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry - ): keyOrNodeOrEntryOrRawElement is NODE { - return keyOrNodeOrEntryOrRawElement instanceof AVLTreeNode; + override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R): keyOrNodeOrEntryOrRaw is NODE { + return keyOrNodeOrEntryOrRaw instanceof AVLTreeNode; } /** @@ -141,17 +140,17 @@ export class AVLTree< * * The function overrides the add method of a class and inserts a key-value pair into a data * structure, then balances the path. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The parameter - * `keyOrNodeOrEntryOrRawElement` can accept values of type `R`, `BTNKeyOrNodeOrEntry`, or + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The parameter + * `keyOrNodeOrEntryOrRaw` can accept values of type `R`, `BTNKeyOrNodeOrEntry`, or * `RawElement`. * @param {V} [value] - The `value` parameter is an optional value that you want to associate with * the key or node being added to the data structure. * @returns The method is returning a boolean value. */ - override add(keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry, value?: V): boolean { - if (keyOrNodeOrEntryOrRawElement === null) return false; - const inserted = super.add(keyOrNodeOrEntryOrRawElement, value); - if (inserted) this._balancePath(keyOrNodeOrEntryOrRawElement); + override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R, value?: V): boolean { + if (keyOrNodeOrEntryOrRaw === null) return false; + const inserted = super.add(keyOrNodeOrEntryOrRaw, value); + if (inserted) this._balancePath(keyOrNodeOrEntryOrRaw); return inserted; } @@ -159,20 +158,17 @@ export class AVLTree< * Time Complexity: O(log n) * Space Complexity: O(1) * - * The function overrides the delete method of a binary tree class and performs additional operations - * to balance the tree after deletion. - * @param identifier - The `identifier` parameter is the value or condition used to identify the - * node(s) to be deleted from the binary tree. It can be of any type that is compatible with the - * binary tree's node type. - * @param {C} callback - The `callback` parameter is a function that will be used to determine if a - * node should be deleted or not. It is optional and has a default value of `this._DEFAULT_CALLBACK`. - * @returns The method is returning an array of BinaryTreeDeleteResult objects. + * The function overrides the delete method in a TypeScript class, performs deletion, and then + * balances the tree if necessary. + * @param {BTNKeyOrNodeOrEntry | R | BTNPredicate} predicate - The `predicate` + * parameter in the `override delete` method can be one of the following types: + * @returns The `delete` method is being overridden in this code snippet. It first calls the `delete` + * method from the superclass (presumably a parent class) with the provided `predicate`, which could + * be a key, node, entry, or a custom predicate. The result of this deletion operation is stored in + * `deletedResults`, which is an array of `BinaryTreeDeleteResult` objects. */ - override delete>( - identifier: ReturnType, - callback: C = this._DEFAULT_CALLBACK as C - ): BinaryTreeDeleteResult[] { - const deletedResults = super.delete(identifier, callback); + override delete(predicate: BTNKeyOrNodeOrEntry | R | BTNPredicate): BinaryTreeDeleteResult[] { + const deletedResults = super.delete(predicate); for (const { needBalanced } of deletedResults) { if (needBalanced) { this._balancePath(needBalanced); @@ -437,10 +433,10 @@ export class AVLTree< * * The `_balancePath` function is used to update the heights of nodes and perform rotation operations * to restore balance in an AVL tree after inserting a node. - * @param {R | BTNKeyOrNodeOrEntry} node - The `node` parameter can be of type `R` or + * @param {BTNKeyOrNodeOrEntry | R} node - The `node` parameter can be of type `R` or * `BTNKeyOrNodeOrEntry`. */ - protected _balancePath(node: R | BTNKeyOrNodeOrEntry): void { + protected _balancePath(node: BTNKeyOrNodeOrEntry | R): void { node = this.ensureNode(node); const path = this.getPathToRoot(node => node, node, false); // first O(log n) + O(log n) for (let i = 0; i < path.length; i++) { diff --git a/src/data-structures/binary-tree/binary-indexed-tree.ts b/src/data-structures/binary-tree/binary-indexed-tree.ts index 0031430..ce722c8 100644 --- a/src/data-structures/binary-tree/binary-indexed-tree.ts +++ b/src/data-structures/binary-tree/binary-indexed-tree.ts @@ -1,8 +1,8 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import { getMSB } from '../../utils'; diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts index 001301a..12a7db0 100644 --- a/src/data-structures/binary-tree/binary-tree.ts +++ b/src/data-structures/binary-tree/binary-tree.ts @@ -1,8 +1,8 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ @@ -15,18 +15,20 @@ import type { BTNCallback, BTNEntry, BTNKeyOrNodeOrEntry, + BTNPredicate, DFSOrderPattern, + DFSStackItem, EntryCallback, FamilyPosition, IterationType, NodeDisplayLayout, OptBTNOrNull } from '../../types'; -import { DFSOperation, DFSStackItem } from '../../types'; import { IBinaryTree } from '../../interfaces'; import { isComparable, trampoline } from '../../utils'; import { Queue } from '../queue'; import { IterableEntryBase } from '../base'; +import { DFSOperation } from '../../constants'; /** * Represents a node in a binary tree. @@ -44,13 +46,6 @@ export class BinaryTreeNode< parent?: NODE; - /** - * The constructor function initializes an object with a key and an optional value. - * @param {K} key - The "key" parameter is of type K, which represents the type of the key for the - * constructor. It is used to set the key property of the object 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 constructor. - */ constructor(key: K, value?: V) { this.key = key; this.value = value; @@ -58,21 +53,10 @@ export class BinaryTreeNode< protected _left?: OptBTNOrNull; - /** - * The function returns the value of the `_left` property, which can be of type `NODE`, `null`, or - * `undefined`. - * @returns The left node of the current node is being returned. It can be either a NODE object, - * null, or undefined. - */ get left(): OptBTNOrNull { return this._left; } - /** - * The function sets the left child of a node and updates its parent reference. - * @param {OptBTNOrNull} v - The parameter `v` can be of type `NODE`, `null`, or - * `undefined`. - */ set left(v: OptBTNOrNull) { if (v) { v.parent = this as unknown as NODE; @@ -82,20 +66,10 @@ export class BinaryTreeNode< protected _right?: OptBTNOrNull; - /** - * The function returns the right node of a binary tree or null if it doesn't exist. - * @returns The method is returning the value of the `_right` property, which can be a `NODE` object, - * `null`, or `undefined`. - */ get right(): OptBTNOrNull { return this._right; } - /** - * The function sets the right child of a node and updates its parent. - * @param {OptBTNOrNull} v - The parameter `v` can be of type `NODE`, `null`, or - * `undefined`. - */ set right(v: OptBTNOrNull) { if (v) { v.parent = this as unknown as NODE; @@ -103,10 +77,6 @@ export class BinaryTreeNode< this._right = v; } - /** - * Get the position of the node within its family. - * @returns {FamilyPosition} - The family position of the node. - */ get familyPosition(): FamilyPosition { const that = this as unknown as NODE; if (!this.parent) { @@ -130,7 +100,6 @@ export class BinaryTreeNode< * 4. Subtrees: Each child of a node forms the root of a subtree. * 5. Leaf Nodes: Nodes without children are leaves. */ - export class BinaryTree< K = any, V = any, @@ -144,16 +113,16 @@ export class BinaryTree< iterationType: IterationType = 'ITERATIVE'; /** - * The constructor function initializes a binary tree object with optional keysOrNodesOrEntriesOrRawElements and options. - * @param [keysOrNodesOrEntriesOrRawElements] - Optional iterable of BTNKeyOrNodeOrEntry objects. These objects represent the - * nodes to be added to the binary tree. - * @param [options] - The `options` parameter is an optional object that can contain additional - * configuration options for the binary tree. In this case, it is of type - * `Partial`, which means that not all properties of `BinaryTreeOptions` are - * required. + * The constructor initializes a binary tree with optional options and adds keys, nodes, entries, or + * raw data if provided. + * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter in the constructor + * is an iterable that can contain elements of type `BTNKeyOrNodeOrEntry` or `R`. It is + * initialized with an empty array `[]` by default. + * @param [options] - The `options` parameter in the constructor is an object that can contain the + * following properties: */ constructor( - keysOrNodesOrEntriesOrRawElements: Iterable> = [], + keysOrNodesOrEntriesOrRaws: Iterable | R> = [], options?: BinaryTreeOptions ) { super(); @@ -164,105 +133,100 @@ export class BinaryTree< else if (toEntryFn) throw TypeError('toEntryFn must be a function type'); } - if (keysOrNodesOrEntriesOrRawElements) this.addMany(keysOrNodesOrEntriesOrRawElements); + if (keysOrNodesOrEntriesOrRaws) this.addMany(keysOrNodesOrEntriesOrRaws); } protected _root?: OptBTNOrNull; - /** - * The function returns the root node, which can be of type NODE, null, or undefined. - * @returns The method is returning the value of the `_root` property, which can be of type `NODE`, - * `null`, or `undefined`. - */ get root(): OptBTNOrNull { return this._root; } protected _size: number = 0; - /** - * The function returns the size of an object. - * @returns The size of the object, which is a number. - */ get size(): number { return this._size; } protected _NIL: NODE = new BinaryTreeNode(NaN as K) as unknown as NODE; - /** - * The function returns the value of the _NIL property. - * @returns The method is returning the value of the `_NIL` property. - */ get NIL(): NODE { return this._NIL; } protected _toEntryFn?: (rawElement: R) => BTNEntry; - /** - * The function returns the value of the _toEntryFn property. - * @returns The function being returned is `this._toEntryFn`. - */ get toEntryFn() { return this._toEntryFn; } /** - * Creates a new instance of BinaryTreeNode with the given key and value. - * @param {K} key - The key for the new node. - * @param {V} value - The value for the new node. - * @returns {NODE} - The newly created BinaryTreeNode. + * The function creates a new binary tree node with a specified key and optional value. + * @param {K} key - The `key` parameter is the key of the node being created in the binary tree. + * @param {V} [value] - The `value` parameter in the `createNode` function is optional, meaning it is + * not required to be provided when calling the function. If a `value` is provided, it should be of + * type `V`, which is the type of the value associated with the node. + * @returns A new BinaryTreeNode instance with the provided key and value is being returned, casted + * as NODE. */ createNode(key: K, value?: V): NODE { return new BinaryTreeNode(key, value) as NODE; } /** - * The function creates a binary tree with the given options. - * @param [options] - The `options` parameter is an optional object that allows you to customize the - * behavior of the `BinaryTree` class. It is of type `Partial`, which means that - * you can provide only a subset of the properties defined in the `BinaryTreeOptions` interface. - * @returns a new instance of a binary tree. + * 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?: Partial>): TREE { - return new BinaryTree([], { iterationType: this.iterationType, ...options }) as TREE; + createTree(options?: BinaryTreeOptions): TREE { + return new BinaryTree([], { + iterationType: this.iterationType, + toEntryFn: this._toEntryFn, + ...options + }) as TREE; } /** - * The function `keyValueOrEntryOrRawElementToNode` converts a key-value pair, entry, or raw element - * into a node object. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The parameter - * `keyOrNodeOrEntryOrRawElement` can be of type `R` or `BTNKeyOrNodeOrEntry`. - * @param {V} [value] - The `value` parameter is an optional value that can be passed to the - * `keyValueOrEntryOrRawElementToNode` function. It represents the value associated with a key in a - * key-value pair. If provided, it will be used to create a node with the specified key and value. - * @returns The function `keyValueOrEntryOrRawElementToNode` returns either a `NODE` object, `null`, - * or `undefined`. + * The function `keyValueOrEntryOrRawElementToNode` converts various input types into a node object + * or returns null. + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The + * `keyValueOrEntryOrRawElementToNode` function takes in a parameter `keyOrNodeOrEntryOrRaw`, which + * can be of type `BTNKeyOrNodeOrEntry` or `R`. This parameter represents either a key, a + * node, an entry + * @param {V} [value] - The `value` parameter in the `keyValueOrEntryOrRawElementToNode` 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 `keyValueOrEntryOrRawElementToNode` function returns an optional node + * (`OptBTNOrNull`) based on the input parameters provided. The function checks the type of the + * input parameter (`keyOrNodeOrEntryOrRaw`) and processes it accordingly to return a node or null + * value. */ keyValueOrEntryOrRawElementToNode( - keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry, + keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R, value?: V ): OptBTNOrNull { - if (keyOrNodeOrEntryOrRawElement === undefined) return; - if (keyOrNodeOrEntryOrRawElement === null) return null; + if (keyOrNodeOrEntryOrRaw === undefined) return; + if (keyOrNodeOrEntryOrRaw === null) return null; - if (this.isNode(keyOrNodeOrEntryOrRawElement)) return keyOrNodeOrEntryOrRawElement; + if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw; - if (this.isEntry(keyOrNodeOrEntryOrRawElement)) { - const [key, entryValue] = keyOrNodeOrEntryOrRawElement; + if (this.isEntry(keyOrNodeOrEntryOrRaw)) { + const [key, entryValue] = keyOrNodeOrEntryOrRaw; if (key === undefined) return; else if (key === null) return null; if (this.isKey(key)) return this.createNode(key, value ?? entryValue); } - if (this.toEntryFn) { - const [key, entryValue] = this.toEntryFn(keyOrNodeOrEntryOrRawElement as R); + if (this._toEntryFn) { + const [key, entryValue] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R); if (this.isKey(key)) return this.createNode(key, value ?? entryValue); else return; } - if (this.isKey(keyOrNodeOrEntryOrRawElement)) return this.createNode(keyOrNodeOrEntryOrRawElement, value); + if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.createNode(keyOrNodeOrEntryOrRaw, value); return; } @@ -271,110 +235,126 @@ export class BinaryTree< * Time Complexity: O(n) * Space Complexity: O(log n) * - * The `ensureNode` function checks if the input is a valid node and returns it, or converts it to a - * node if it is a key or entry. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The parameter - * `keyOrNodeOrEntryOrRawElement` can accept a value of type `R`, `BTNKeyOrNodeOrEntry`, or - * a raw element. - * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional - * parameter that specifies the type of iteration to be used when searching for a node. It has a - * default value of `'ITERATIVE'`. - * @returns The function `ensureNode` returns either a `NODE` object, `null`, or `undefined`. + * The function `ensureNode` in TypeScript checks if a given input is a node, entry, key, or raw + * value and returns the corresponding node or null. + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The `keyOrNodeOrEntryOrRaw` + * parameter in the `ensureNode` function can be of type `BTNKeyOrNodeOrEntry` or `R`. It + * is used to determine whether the input is a key, node, entry, or raw data. The + * @param {IterationType} iterationType - The `iterationType` parameter in the `ensureNode` function + * is used to specify the type of iteration to be performed. It has a default value of + * `this.iterationType` if not explicitly provided. + * @returns The `ensureNode` function returns either a node, `null`, or `undefined` based on the + * conditions specified in the code snippet. */ ensureNode( - keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry, + keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R, iterationType: IterationType = this.iterationType ): OptBTNOrNull { - if (keyOrNodeOrEntryOrRawElement === null) return null; - if (keyOrNodeOrEntryOrRawElement === undefined) return; - if (keyOrNodeOrEntryOrRawElement === this.NIL) return; - if (this.isNode(keyOrNodeOrEntryOrRawElement)) return keyOrNodeOrEntryOrRawElement; + if (keyOrNodeOrEntryOrRaw === null) return null; + if (keyOrNodeOrEntryOrRaw === undefined) return; + if (keyOrNodeOrEntryOrRaw === this._NIL) return; + if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw; - if (this.toEntryFn) { - const [key] = this.toEntryFn(keyOrNodeOrEntryOrRawElement as R); - if (this.isKey(key)) return this.getNodeByKey(key); - } - - if (this.isEntry(keyOrNodeOrEntryOrRawElement)) { - const key = keyOrNodeOrEntryOrRawElement[0]; + if (this.isEntry(keyOrNodeOrEntryOrRaw)) { + const key = keyOrNodeOrEntryOrRaw[0]; if (key === null) return null; if (key === undefined) return; return this.getNodeByKey(key, iterationType); } - if (this.isKey(keyOrNodeOrEntryOrRawElement)) return this.getNodeByKey(keyOrNodeOrEntryOrRawElement, iterationType); + if (this._toEntryFn) { + const [key] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R); + if (this.isKey(key)) return this.getNodeByKey(key); + } + + if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.getNodeByKey(keyOrNodeOrEntryOrRaw, iterationType); return; } /** - * The function checks if the input is an instance of the BinaryTreeNode class. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The parameter - * `keyOrNodeOrEntryOrRawElement` can be of type `R` or `BTNKeyOrNodeOrEntry`. - * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRawElement` is - * an instance of the `BinaryTreeNode` class. + * The function isNode checks if the input is an instance of BinaryTreeNode. + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The parameter + * `keyOrNodeOrEntryOrRaw` can be either a key, a node, an entry, or raw data. The function is + * checking if the input is an instance of a `BinaryTreeNode` and returning a boolean value + * accordingly. + * @returns The function `isNode` is checking if the input `keyOrNodeOrEntryOrRaw` is an instance of + * `BinaryTreeNode`. If it is, the function returns `true`, indicating that the input is a node. If + * it is not an instance of `BinaryTreeNode`, the function returns `false`, indicating that the input + * is not a node. */ - isNode(keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry): keyOrNodeOrEntryOrRawElement is NODE { - return keyOrNodeOrEntryOrRawElement instanceof BinaryTreeNode; + isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R): keyOrNodeOrEntryOrRaw is NODE { + return keyOrNodeOrEntryOrRaw instanceof BinaryTreeNode; } /** - * The function checks if a given node is a valid node in a binary search tree. - * @param {R | BTNKeyOrNodeOrEntry} node - The parameter `node` can be of type `R` or - * `BTNKeyOrNodeOrEntry`. - * @returns a boolean value. + * The function `isRealNode` checks if a given input is a valid node in a binary tree. + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The `keyOrNodeOrEntryOrRaw` + * parameter in the `isRealNode` function can be of type `BTNKeyOrNodeOrEntry` or `R`. + * The function checks if the input parameter is a `NODE` type by verifying if it is not equal + * @returns The function `isRealNode` is checking if the input `keyOrNodeOrEntryOrRaw` is a valid + * node by comparing it to `this._NIL`, `null`, and `undefined`. If the input is not one of these + * values, it then calls the `isNode` method to further determine if the input is a node. The + * function will return a boolean value indicating whether the */ - isRealNode(node: R | BTNKeyOrNodeOrEntry): node is NODE { - if (node === this.NIL || node === null || node === undefined) return false; - return this.isNode(node); + isRealNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R): keyOrNodeOrEntryOrRaw is NODE { + if (keyOrNodeOrEntryOrRaw === this._NIL || keyOrNodeOrEntryOrRaw === null || keyOrNodeOrEntryOrRaw === undefined) + return false; + return this.isNode(keyOrNodeOrEntryOrRaw); } /** - * The function checks if a given node is a real node or null. - * @param {R | BTNKeyOrNodeOrEntry} node - The parameter `node` can be of type `R` or - * `BTNKeyOrNodeOrEntry`. - * @returns a boolean value. + * The function checks if a given input is a valid node or null. + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The parameter + * `keyOrNodeOrEntryOrRaw` in the `isRealNodeOrNull` function can be of type `BTNKeyOrNodeOrEntry` or `R`. It is a union type that can either be a key, a node, an entry, or + * @returns The function `isRealNodeOrNull` is returning a boolean value. It checks if the input + * `keyOrNodeOrEntryOrRaw` is either `null` or a real node, and returns `true` if it is a node or + * `null`, and `false` otherwise. */ - isRealNodeOrNull(node: R | BTNKeyOrNodeOrEntry): node is NODE | null { - return node === null || this.isRealNode(node); + isRealNodeOrNull(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R): keyOrNodeOrEntryOrRaw is NODE | null { + return keyOrNodeOrEntryOrRaw === null || this.isRealNode(keyOrNodeOrEntryOrRaw); } /** - * The function checks if a given node is equal to the NIL value. - * @param {R | BTNKeyOrNodeOrEntry} node - The parameter `node` can be of type `R` or - * `BTNKeyOrNodeOrEntry`. - * @returns a boolean value. + * The function isNIL checks if a given key, node, entry, or raw value is equal to the _NIL value. + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - BTNKeyOrNodeOrEntry | R + * @returns The function is checking if the `keyOrNodeOrEntryOrRaw` parameter is equal to the `_NIL` + * property of the current object and returning a boolean value based on that comparison. */ - isNIL(node: R | BTNKeyOrNodeOrEntry): boolean { - return node === this.NIL; + isNIL(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R): boolean { + return keyOrNodeOrEntryOrRaw === this._NIL; } /** - * The function `isLeaf` determines whether a given node is a leaf node in a binary tree structure. - * @param {R | BTNKeyOrNodeOrEntry} node - The `node` parameter in the `isLeaf` function - * can be either a regular node (`R`) or a `BTNKeyOrNodeOrEntry`. - * @returns The `isLeaf` function is checking if the provided node is a leaf node in a binary tree. - * If the node is `undefined`, it returns `false`. If the node is `null`, it returns `true`. - * Otherwise, it checks if both the left and right children of the node are not real nodes, and - * returns `true` if they are not, indicating that the node is a + * The function determines whether a given key, node, entry, or raw data is a leaf node in a binary + * tree. + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The parameter + * `keyOrNodeOrEntryOrRaw` can be of type `BTNKeyOrNodeOrEntry` or `R`. It represents a + * key, node, entry, or raw data in a binary tree structure. The function `isLeaf` checks whether the + * provided + * @returns The function `isLeaf` returns a boolean value indicating whether the input + * `keyOrNodeOrEntryOrRaw` is a leaf node in a binary tree. */ - isLeaf(node: R | BTNKeyOrNodeOrEntry): boolean { - node = this.ensureNode(node); - if (node === undefined) return false; - if (node === null) return true; - return !this.isRealNode(node.left) && !this.isRealNode(node.right); + isLeaf(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R): boolean { + keyOrNodeOrEntryOrRaw = this.ensureNode(keyOrNodeOrEntryOrRaw); + if (keyOrNodeOrEntryOrRaw === undefined) return false; + if (keyOrNodeOrEntryOrRaw === null) return true; + return !this.isRealNode(keyOrNodeOrEntryOrRaw.left) && !this.isRealNode(keyOrNodeOrEntryOrRaw.right); } /** - * The function checks if the input is an array with two elements, indicating it is a binary tree - * node entry. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The parameter - * `keyOrNodeOrEntryOrRawElement` can be of type `R` or `BTNKeyOrNodeOrEntry`. - * @returns a boolean value. + * The function `isEntry` checks if the input is a BTNEntry object by verifying if it is an array + * with a length of 2. + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The `keyOrNodeOrEntryOrRaw` + * parameter in the `isEntry` function can be of type `BTNKeyOrNodeOrEntry` or type `R`. + * The function checks if the provided `keyOrNodeOrEntryOrRaw` is of type `BTN + * @returns The `isEntry` function is checking if the `keyOrNodeOrEntryOrRaw` parameter is an array + * with a length of 2. If it is, then it returns `true`, indicating that the parameter is of type + * `BTNEntry`. If the condition is not met, it returns `false`. */ - isEntry( - keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry - ): keyOrNodeOrEntryOrRawElement is BTNEntry { - return Array.isArray(keyOrNodeOrEntryOrRawElement) && keyOrNodeOrEntryOrRawElement.length === 2; + isEntry(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R): keyOrNodeOrEntryOrRaw is BTNEntry { + return Array.isArray(keyOrNodeOrEntryOrRaw) && keyOrNodeOrEntryOrRaw.length === 2; } /** @@ -397,30 +377,31 @@ export class BinaryTree< * Time Complexity O(n) * Space Complexity O(1) * - * The `add` function is used to insert a new node into a binary tree, checking for duplicate keys - * and finding the appropriate insertion position. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The - * `keyOrNodeOrEntryOrRawElement` parameter can accept a value of type `R`, which represents the key, - * node, entry, or raw element to be added to the tree. It can also accept a value of type - * `BTNKeyOrNodeOrEntry - * @param {V} [value] - The `value` parameter is an optional value that can be associated with the - * key being added to the tree. It represents the value that will be stored in the tree for the given - * key. - * @returns a boolean value. It returns `true` if the insertion is successful, and `false` if the - * insertion position cannot be found or if there are duplicate keys. + * The `add` function in TypeScript adds a new node to a binary tree while handling duplicate keys + * and finding the correct insertion position. + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The `add` method you provided + * seems to be for adding a new node to a binary tree structure. The `keyOrNodeOrEntryOrRaw` + * parameter in the method can accept different types of values: + * @param {V} [value] - The `value` parameter in the `add` method represents the value associated + * with the key that you want to add to the binary tree. When adding a key-value pair to the binary + * tree, you provide the key and its corresponding value. The `add` method then creates a new node + * with this + * @returns The `add` method returns a boolean value. It returns `true` if the insertion of the new + * node was successful, and `false` if the insertion position could not be found or if a duplicate + * key was found and the node was replaced instead of inserted. */ - add(keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry, value?: V): boolean { - const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement, value); + add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R, value?: V): boolean { + const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value); if (newNode === undefined) return false; // If the tree is empty, directly set the new node as the root node - if (!this.root) { + if (!this._root) { this._setRoot(newNode); this._size = 1; return true; } - const queue = new Queue([this.root]); + const queue = new Queue([this._root]); let potentialParent: NODE | undefined; // Record the parent node of the potential insertion location while (queue.size > 0) { @@ -466,18 +447,22 @@ export class BinaryTree< * Time Complexity: O(k * n) * Space Complexity: O(1) * - * The `addMany` function takes in an iterable of keys or nodes or entries or raw elements, and an - * optional iterable of values, and adds each key or node or entry with its corresponding value to a - * data structure, returning an array of booleans indicating whether each insertion was successful. - * @param keysOrNodesOrEntriesOrRawElements - An iterable containing keys, nodes, entries, or raw - * elements. These elements will be added to the data structure. - * @param [values] - An optional iterable of values that correspond to the keys or nodes or entries - * in the `keysOrNodesOrEntriesOrRawElements` parameter. - * @returns The function `addMany` returns an array of booleans indicating whether each element was - * successfully added to the data structure. + * The `addMany` function takes in multiple keys or nodes or entries or raw values along with + * optional values, and adds them to a data structure while returning an array indicating whether + * each insertion was successful. + * @param keysOrNodesOrEntriesOrRaws - `keysOrNodesOrEntriesOrRaws` is an iterable that can contain a + * mix of keys, nodes, entries, or raw values. Each element in this iterable can be of type + * `BTNKeyOrNodeOrEntry` or `R`. + * @param [values] - The `values` parameter in the `addMany` function is an optional parameter that + * accepts an iterable of values. These values correspond to the keys or nodes being added in the + * `keysOrNodesOrEntriesOrRaws` parameter. If provided, the function will iterate over the values and + * assign them + * @returns The `addMany` method returns an array of boolean values indicating whether each key, + * node, entry, or raw value was successfully added to the data structure. Each boolean value + * corresponds to the success of adding the corresponding key or value in the input iterable. */ addMany( - keysOrNodesOrEntriesOrRawElements: Iterable>, + keysOrNodesOrEntriesOrRaws: Iterable | R>, values?: Iterable ): boolean[] { // TODO not sure addMany not be run multi times @@ -488,7 +473,7 @@ export class BinaryTree< valuesIterator = values[Symbol.iterator](); } - for (const keyOrNodeOrEntryOrRawElement of keysOrNodesOrEntriesOrRawElements) { + for (const keyOrNodeOrEntryOrRaw of keysOrNodesOrEntriesOrRaws) { let value: V | undefined | null = undefined; if (valuesIterator) { @@ -498,7 +483,7 @@ export class BinaryTree< } } - inserted.push(this.add(keyOrNodeOrEntryOrRawElement, value)); + inserted.push(this.add(keyOrNodeOrEntryOrRaw, value)); } return inserted; @@ -508,54 +493,44 @@ export class BinaryTree< * Time Complexity: O(k * n) * Space Complexity: O(1) * - * The `refill` function clears the current data and adds new data to the collection. - * @param keysOrNodesOrEntriesOrRawElements - An iterable collection of keys, nodes, entries, or raw - * elements. These can be of any type (R) or a specific type (BTNKeyOrNodeOrEntry). - * @param [values] - The `values` parameter is an optional iterable of values that will be associated - * with the keys or nodes being added. If provided, the values will be assigned to the corresponding - * keys or nodes. If not provided, the values will be set to `undefined`. + * The `refill` function clears the existing data structure and then adds new key-value pairs based + * on the provided input. + * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter in the `refill` + * method can accept an iterable containing a mix of `BTNKeyOrNodeOrEntry` objects or `R` + * objects. + * @param [values] - The `values` parameter in the `refill` method is an optional parameter that + * accepts an iterable of values of type `V` or `undefined`. */ refill( - keysOrNodesOrEntriesOrRawElements: Iterable>, + keysOrNodesOrEntriesOrRaws: Iterable | R>, values?: Iterable ): void { this.clear(); - this.addMany(keysOrNodesOrEntriesOrRawElements, values); + this.addMany(keysOrNodesOrEntriesOrRaws, values); } - delete>(identifier: K, callback?: C): BinaryTreeDeleteResult[]; - - delete>( - identifier: OptBTNOrNull, - callback?: C - ): BinaryTreeDeleteResult[]; - - delete>(identifier: ReturnType, callback: C): BinaryTreeDeleteResult[]; - /** * Time Complexity: O(n) * Space Complexity: O(1) * - * The above function is a TypeScript implementation of deleting a node from a binary tree, returning - * the deleted node and the node that needs to be balanced. - * @param {ReturnType | null | undefined} identifier - The `identifier` parameter is the value - * used to identify the node that needs to be deleted from the binary tree. It can be of any type - * that is returned by the callback function. - * @param {C} callback - The `callback` parameter is a function that is used to determine the - * identifier of the node to be deleted. It is of type `C`, which extends the `BTNCallback` - * interface. The `BTNCallback` interface represents a callback function that takes a node of - * type `NODE - * @returns an array of `BinaryTreeDeleteResult`. + * The function `delete` in TypeScript implements the deletion of a node in a binary tree and returns + * the deleted node along with information for tree balancing. + * @param {BTNKeyOrNodeOrEntry | R | BTNPredicate} keyOrNodeOrEntryOrRawOrPredicate + * - The `delete` method you provided is used to delete a node from a binary tree based on the key, + * node, entry, raw data, or a custom predicate. The method returns an array of + * `BinaryTreeDeleteResult` objects containing information about the deleted node and whether + * balancing is needed. + * @returns The `delete` method returns an array of `BinaryTreeDeleteResult` objects. Each object in + * the array contains information about the node that was deleted (`deleted`) and the node that may + * need to be balanced (`needBalanced`). */ - delete>( - identifier: ReturnType | null | undefined, - callback: C = this._DEFAULT_CALLBACK as C + delete( + keyOrNodeOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry | R | BTNPredicate ): BinaryTreeDeleteResult[] { const deletedResult: BinaryTreeDeleteResult[] = []; - if (!this.root) return deletedResult; - callback = this._ensureCallback(identifier, callback); + if (!this._root) return deletedResult; - const curr = this.getNode(identifier, callback); + const curr = this.getNode(keyOrNodeOrEntryOrRawOrPredicate); if (!curr) return deletedResult; const parent: NODE | undefined = curr?.parent; @@ -589,78 +564,50 @@ export class BinaryTree< curr.right = undefined; } - this._size = this.size - 1; + this._size = this._size - 1; deletedResult.push({ deleted: orgCurrent, needBalanced }); return deletedResult; } - getNodes>( - identifier: K, - callback?: C, - onlyOne?: boolean, - beginRoot?: R | BTNKeyOrNodeOrEntry, - iterationType?: IterationType - ): NODE[]; - - getNodes>( - identifier: OptBTNOrNull, - callback?: C, - onlyOne?: boolean, - beginRoot?: R | BTNKeyOrNodeOrEntry, - iterationType?: IterationType - ): NODE[]; - - getNodes>( - identifier: ReturnType, - callback: C, - onlyOne?: boolean, - beginRoot?: R | BTNKeyOrNodeOrEntry, - iterationType?: IterationType - ): NODE[]; - /** * Time Complexity: O(n) * Space Complexity: O(k + log n) * - * The function `getNodes` returns an array of nodes that match a given identifier, using either a - * recursive or iterative approach. - * @param {ReturnType | null | undefined} identifier - The `identifier` parameter is the value - * that is used to identify the nodes. It can be of any type and is used to match against the result - * of the callback function for each node. - * @param {C} callback - The `callback` parameter is a function that takes a node as input and - * returns a value. This value is used to identify the nodes that match the given identifier. The - * `callback` function is optional and defaults to a default callback function - * (`this._DEFAULT_CALLBACK`) if not provided. - * @param [onlyOne=false] - A boolean value indicating whether to return only one node that matches - * the identifier or all nodes that match the identifier. If set to true, only the first matching - * node will be returned. If set to false, all matching nodes will be returned. The default value is - * false. - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter is the starting - * point for the search. It can be either a node object, a key-value pair, or a key. If it is not - * provided, the `root` of the data structure is used as the starting point. - * @param {IterationType} iterationType - The `iterationType` parameter determines the type of - * iteration to be performed on the nodes of a binary tree. It can have two possible values: - * @returns an array of NODE objects. + * The function `getNodes` retrieves nodes from a binary tree based on a key, node, entry, raw data, + * or predicate, with options for recursive or iterative traversal. + * @param {BTNKeyOrNodeOrEntry | R | BTNPredicate} keyOrNodeOrEntryOrRawOrPredicate + * - The `getNodes` function you provided takes several parameters: + * @param [onlyOne=false] - The `onlyOne` parameter in the `getNodes` function is a boolean flag that + * determines whether to return only the first node that matches the criteria specified by the + * `keyOrNodeOrEntryOrRawOrPredicate` parameter. If `onlyOne` is set to `true`, the function will + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the + * `getNodes` function is used to specify the starting point for traversing the binary tree. It + * represents the root node of the binary tree or the node from which the traversal should begin. If + * not provided, the default value is set to `this._root + * @param {IterationType} iterationType - The `iterationType` parameter in the `getNodes` function + * determines the type of iteration to be performed when traversing the nodes of a binary tree. It + * can have two possible values: + * @returns The `getNodes` function returns an array of nodes that satisfy the provided condition + * based on the input parameters and the iteration type specified. */ - getNodes>( - identifier: ReturnType | null | undefined, - callback: C = this._DEFAULT_CALLBACK as C, + getNodes( + keyOrNodeOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry | R | BTNPredicate, onlyOne = false, - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType ): NODE[] { - if (identifier === undefined) return []; - if (identifier === null) return []; + if (keyOrNodeOrEntryOrRawOrPredicate === undefined) return []; + if (keyOrNodeOrEntryOrRawOrPredicate === null) return []; beginRoot = this.ensureNode(beginRoot); if (!beginRoot) return []; - callback = this._ensureCallback(identifier, callback); + const callback = this._ensurePredicate(keyOrNodeOrEntryOrRawOrPredicate); const ans: NODE[] = []; if (iterationType === 'RECURSIVE') { const dfs = (cur: NODE) => { - if (callback(cur) === identifier) { + if (callback(cur)) { ans.push(cur); if (onlyOne) return; } @@ -675,7 +622,7 @@ export class BinaryTree< while (stack.length > 0) { const cur = stack.pop(); if (this.isRealNode(cur)) { - if (callback(cur) === identifier) { + if (callback(cur)) { ans.push(cur); if (onlyOne) return ans; } @@ -688,178 +635,115 @@ export class BinaryTree< return ans; } - getNode>( - identifier: K, - callback?: C, - beginRoot?: R | BTNKeyOrNodeOrEntry, - iterationType?: IterationType - ): OptBTNOrNull; - - getNode>( - identifier: OptBTNOrNull, - callback?: C, - beginRoot?: R | BTNKeyOrNodeOrEntry, - iterationType?: IterationType - ): OptBTNOrNull; - - getNode>( - identifier: ReturnType, - callback: C, - beginRoot?: R | BTNKeyOrNodeOrEntry, - iterationType?: IterationType - ): OptBTNOrNull; - /** * Time Complexity: O(n) * Space Complexity: O(log n). * - * The function `getNode` returns the first node that matches the given identifier and callback, - * starting from the specified root node and using the specified iteration type. - * @param {ReturnType | null | undefined} identifier - The `identifier` parameter is the value - * used to identify the node you want to retrieve. It can be of any type that is the return type of - * the `C` callback function, or it can be `null` or `undefined`. - * @param {C} callback - The `callback` parameter is a function that will be used to determine if a - * node matches the desired criteria. It should return a value that can be used to identify the node. - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter is the starting - * point for searching nodes in a tree structure. It can be either a root node, a key-value pair, or - * a node entry. If not provided, the search will start from the root of the tree. - * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type - * of iteration to be performed when searching for nodes. It can have one of the following values: - * @returns The method is returning a NODE object, or null, or undefined. + * The `getNode` function retrieves a node based on the provided key, node, entry, raw data, or + * predicate. + * @param {BTNKeyOrNodeOrEntry | R | BTNPredicate} keyOrNodeOrEntryOrRawOrPredicate + * - The `keyOrNodeOrEntryOrRawOrPredicate` parameter in the `getNode` function can accept a key, + * node, entry, raw data, or a predicate function. + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the + * `getNode` function is used to specify the starting point for searching for a node in a binary + * tree. If no specific starting point is provided, the default value is set to `this._root`, which + * is typically the root node of the binary tree. + * @param {IterationType} iterationType - The `iterationType` parameter in the `getNode` method is + * used to specify the type of iteration to be performed when searching for a node. It has a default + * value of `this.iterationType`, which means it will use the iteration type defined in the current + * context if no specific value is provided + * @returns The `getNode` function is returning the first node that matches the specified criteria, + * or `null` if no matching node is found. */ - getNode>( - identifier: ReturnType | null | undefined, - callback: C = this._DEFAULT_CALLBACK as C, - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + getNode( + keyOrNodeOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry | R | BTNPredicate, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType ): OptBTNOrNull { - return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null; + return this.getNodes(keyOrNodeOrEntryOrRawOrPredicate, true, beginRoot, iterationType)[0] ?? null; } /** * Time Complexity: O(n) * Space Complexity: O(log n) * - * The function `getNodeByKey` returns a node with a specific key value from a tree structure. - * @param {K} key - The key parameter is the value that you want to search for in the tree. It is - * used to find the node with the matching key value. - * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional - * parameter that specifies the type of iteration to be used when searching for a node in the tree. - * It has a default value of `'ITERATIVE'`. - * @returns a value of type NODE, null, or undefined. + * The function `getNodeByKey` retrieves a node by its key from a binary tree structure. + * @param {K} key - The `key` parameter is the value used to search for a specific node in a data + * structure. + * @param {IterationType} iterationType - The `iterationType` parameter is a type of iteration that + * specifies how the tree nodes should be traversed when searching for a node with the given key. It + * is an optional parameter with a default value of `this.iterationType`. + * @returns The `getNodeByKey` function is returning an optional binary tree node + * (`OptBTNOrNull`). */ getNodeByKey(key: K, iterationType: IterationType = this.iterationType): OptBTNOrNull { - return this.getNode(key, this._DEFAULT_CALLBACK, this.root, iterationType); + return this.getNode(key, this._root, iterationType); } - override get>( - identifier: K, - callback?: C, - beginRoot?: R | BTNKeyOrNodeOrEntry, - iterationType?: IterationType - ): V | undefined; - - override get>( - identifier: OptBTNOrNull, - callback?: C, - beginRoot?: R | BTNKeyOrNodeOrEntry, - iterationType?: IterationType - ): V | undefined; - - override get>( - identifier: ReturnType, - callback: C, - beginRoot?: R | BTNKeyOrNodeOrEntry, - iterationType?: IterationType - ): V | undefined; - /** * Time Complexity: O(n) * Space Complexity: O(log n) * - * The function `get` in TypeScript overrides the base class method and returns the value associated - * with the given identifier. - * @param {ReturnType | null | undefined} identifier - The `identifier` parameter is the value - * used to identify the node in the binary tree. It can be of any type that is returned by the - * callback function `C`. It can also be `null` or `undefined` if no identifier is provided. - * @param {C} callback - The `callback` parameter is a function that will be used to determine if a - * node matches the given identifier. It is optional and defaults to `this._DEFAULT_CALLBACK`. - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter is the starting - * point for the search in the binary tree. It can be either a root node of the tree or a key, node, - * or entry object that exists in the tree. If no specific starting point is provided, the search - * will begin from the root of the - * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type - * of iteration to be performed when searching for a node in the tree. It can have one of the - * following values: - * @returns The method is returning the value associated with the specified identifier in the binary - * tree. + * This function overrides the `get` method to retrieve the value associated with a specified key, + * node, entry, raw data, or predicate in a data structure. + * @param {BTNKeyOrNodeOrEntry | R | BTNPredicate} keyOrNodeOrEntryOrRawOrPredicate + * - The `keyOrNodeOrEntryOrRawOrPredicate` parameter in the `get` method can accept one of the + * following types: + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the `get` + * method is used to specify the starting point for searching for a key or node in the binary tree. + * If no specific starting point is provided, the default starting point is the root of the binary + * tree (`this._root`). + * @param {IterationType} iterationType - The `iterationType` parameter in the `get` method is used + * to specify the type of iteration to be performed when searching for a key in the binary tree. It + * is an optional parameter with a default value of `this.iterationType`, which means it will use the + * iteration type defined in the + * @returns The `get` method is returning the value associated with the specified key, node, entry, + * raw data, or predicate in the binary tree map. If the specified key or node is found in the tree, + * the method returns the corresponding value. If the key or node is not found, it returns + * `undefined`. */ - override get>( - identifier: ReturnType | null | undefined, - callback: C = this._DEFAULT_CALLBACK as C, - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + override get( + keyOrNodeOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry | R | BTNPredicate, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType ): V | undefined { - return this.getNode(identifier, callback, beginRoot, iterationType)?.value; + return this.getNode(keyOrNodeOrEntryOrRawOrPredicate, beginRoot, iterationType)?.value; } - override has>( - identifier: K, - callback?: C, - beginRoot?: R | BTNKeyOrNodeOrEntry, - iterationType?: IterationType - ): boolean; - - override has>( - identifier: OptBTNOrNull, - callback?: C, - beginRoot?: R | BTNKeyOrNodeOrEntry, - iterationType?: IterationType - ): boolean; - - override has>( - identifier: ReturnType | null | undefined, - callback: C, - beginRoot?: R | BTNKeyOrNodeOrEntry, - iterationType?: IterationType - ): boolean; - /** * Time Complexity: O(n) * Space Complexity: O(log n) * - * The `has` function checks if a given identifier exists in the data structure and returns a boolean - * value. - * @param {ReturnType | null | undefined} identifier - The `identifier` parameter is the value - * used to identify a specific node or entry in the data structure. It can be of any type that is - * returned by the callback function `C`. It can also be `null` or `undefined` if no specific - * identifier is provided. - * @param {C} callback - The `callback` parameter is a function that will be used to determine - * whether a node should be included in the result or not. It is of type `C`, which extends the - * `BTNCallback` type. - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter is the starting - * point for the iteration in the data structure. It can be either a root node, a key-value pair, or - * a node entry. If not specified, it defaults to the root of the data structure. - * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type - * of iteration to be performed. It is an optional parameter with a default value of `IterationType`. - * @returns The method is returning a boolean value. + * The `has` function in TypeScript checks if a specified key, node, entry, raw data, or predicate + * exists in the data structure. + * @param {BTNKeyOrNodeOrEntry | R | BTNPredicate} keyOrNodeOrEntryOrRawOrPredicate + * - The `keyOrNodeOrEntryOrRawOrPredicate` parameter in the `override has` method can accept one of + * the following types: + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the + * `override` method is used to specify the starting point for the search operation within the data + * structure. It defaults to `this._root` if not provided explicitly. + * @param {IterationType} iterationType - The `iterationType` parameter in the `override has` method + * is used to specify the type of iteration to be performed. It has a default value of + * `this.iterationType`, which means it will use the iteration type defined in the current context if + * no value is provided when calling the method. + * @returns The `override has` method is returning a boolean value. It checks if there are any nodes + * that match the provided key, node, entry, raw data, or predicate in the tree structure. If there + * are matching nodes, it returns `true`, indicating that the tree contains the specified element. + * Otherwise, it returns `false`. */ - override has>( - identifier: ReturnType | null | undefined, - callback: C = this._DEFAULT_CALLBACK as C, - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + override has( + keyOrNodeOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry | R | BTNPredicate, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType ): boolean { - callback = this._ensureCallback(identifier, callback); - - return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0; + return this.getNodes(keyOrNodeOrEntryOrRawOrPredicate, true, beginRoot, iterationType).length > 0; } /** * Time Complexity: O(1) * Space Complexity: O(1) * - * Clear the binary tree, removing all nodes. + * The `clear` function resets the root node and size of a data structure to empty. */ clear() { this._setRoot(undefined); @@ -870,26 +754,31 @@ export class BinaryTree< * Time Complexity: O(1) * Space Complexity: O(1) * - * Check if the binary tree is empty. - * @returns {boolean} - True if the binary tree is empty, false otherwise. + * The `isEmpty` function in TypeScript checks if a data structure has no elements and returns a + * boolean value. + * @returns The `isEmpty()` method is returning a boolean value, specifically `true` if the `_size` + * property is equal to 0, indicating that the data structure is empty, and `false` otherwise. */ isEmpty(): boolean { - return this.size === 0; + return this._size === 0; } /** * Time Complexity: O(n) * Space Complexity: O(log n) * - * The function checks if a binary tree is perfectly balanced by comparing the minimum height and the - * height of the tree. - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The parameter `beginRoot` is optional and - * has a default value of `this.root`. It represents the starting point for checking if the tree is - * perfectly balanced. It can be either a root node (`R`), a key or node or entry - * (`BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter is the starting + * point for checking if the binary tree is perfectly balanced. It represents the root node of the + * binary tree or a specific node from which the balance check should begin. + * @returns The method `isPerfectlyBalanced` is returning a boolean value, which indicates whether + * the tree starting from the `beginRoot` node is perfectly balanced or not. The return value is + * determined by comparing the minimum height of the tree with the height of the tree. If the minimum + * height plus 1 is greater than or equal to the height of the tree, then it is considered perfectly + * balanced and */ - isPerfectlyBalanced(beginRoot: R | BTNKeyOrNodeOrEntry = this.root): boolean { + isPerfectlyBalanced(beginRoot: BTNKeyOrNodeOrEntry | R = this._root): boolean { return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot); } @@ -897,18 +786,22 @@ export class BinaryTree< * Time Complexity: O(n) * Space Complexity: O(1) * - * The function `isBST` checks if a binary search tree is valid, either recursively or iteratively. - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter represents the - * starting point for checking if a binary search tree (BST) is valid. It can be either a root node - * of the BST, a key value of a node in the BST, or an entry object containing both the key and value - * of a node in the BST - * @param {IterationType} iterationType - The `iterationType` parameter is used to determine the type - * of iteration to be performed while checking if the binary search tree (BST) is valid. It can have - * two possible values: - * @returns a boolean value. + * The function `isBST` in TypeScript checks if a binary search tree is valid using either recursive + * or iterative methods. + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the `isBST` + * function represents the starting point for checking whether a binary search tree (BST) is valid. + * It can be a node in the BST or a reference to the root of the BST. If no specific node is + * provided, the function will default to + * @param {IterationType} iterationType - The `iterationType` parameter in the `isBST` function + * determines whether the function should use a recursive approach or an iterative approach to check + * if the binary search tree (BST) is valid. + * @returns The `isBST` method is returning a boolean value, which indicates whether the binary + * search tree (BST) represented by the given root node is a valid BST or not. The method checks if + * the tree satisfies the BST property, where for every node, all nodes in its left subtree have keys + * less than the node's key, and all nodes in its right subtree have keys greater than the node's */ isBST( - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType ): boolean { // TODO there is a bug @@ -955,19 +848,21 @@ export class BinaryTree< * Time Complexity: O(n) * Space Complexity: O(1) * - * The function calculates the depth of a given node or key in a tree-like data structure. - * @param {R | BTNKeyOrNodeOrEntry} dist - The `dist` parameter can be either a `R` - * (representing a root node), or a `BTNKeyOrNodeOrEntry` (representing a key, node, or - * entry). - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter is optional and - * represents the starting point from which to calculate the depth. It can be either a reference to a - * node in the tree or a key-value pair or an entry object. If not provided, the default value is - * `this.root`, which refers to the root node - * @returns the depth of a node in a tree structure. + * The `getDepth` function calculates the depth between two nodes in a binary tree. + * @param {BTNKeyOrNodeOrEntry | R} dist - The `dist` parameter in the `getDepth` + * function represents the node or entry in a binary tree map, or a reference to a node in the tree. + * It is the target node for which you want to calculate the depth from the `beginRoot` node. + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the + * `getDepth` function represents the starting point from which you want to calculate the depth of a + * given node or entry in a binary tree. If no specific starting point is provided, the default value + * for `beginRoot` is set to the root of the binary + * @returns The `getDepth` method returns the depth of a given node `dist` relative to the + * `beginRoot` node in a binary tree. If the `dist` node is not found in the path to the `beginRoot` + * node, it returns the depth of the `dist` node from the root of the tree. */ getDepth( - dist: R | BTNKeyOrNodeOrEntry, - beginRoot: R | BTNKeyOrNodeOrEntry = this.root + dist: BTNKeyOrNodeOrEntry | R, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root ): number { let distEnsured = this.ensureNode(dist); const beginRootEnsured = this.ensureNode(beginRoot); @@ -987,16 +882,20 @@ export class BinaryTree< * Space Complexity: O(1) * * The `getHeight` function calculates the maximum height of a binary tree using either a recursive - * or iterative approach. - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter represents the - * starting point for calculating the height of a tree. It can be either a root node (`R`), a key or - * node or entry (`BTNKeyOrNodeOrEntry`), or it defaults to the root of the current tree. - * @param {IterationType} iterationType - The `iterationType` parameter determines the type of - * iteration used to calculate the height of the tree. It can have two possible values: - * @returns the maximum height of the binary tree. + * or iterative approach in TypeScript. + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter is the starting + * point from which the height of the binary tree will be calculated. It can be a node in the binary + * tree or a reference to the root of the tree. If not provided, it defaults to the root of the + * binary tree data structure. + * @param {IterationType} iterationType - The `iterationType` parameter is used to determine the type + * of iteration to be performed while calculating the height of the binary tree. It can have two + * possible values: + * @returns The `getHeight` method returns the height of the binary tree starting from the specified + * root node. The height is calculated based on the maximum depth of the tree, considering either a + * recursive approach or an iterative approach depending on the `iterationType` parameter. */ getHeight( - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType ): number { beginRoot = this.ensureNode(beginRoot); @@ -1033,19 +932,21 @@ export class BinaryTree< * Space Complexity: O(log n) * * The `getMinHeight` function calculates the minimum height of a binary tree using either a - * recursive or iterative approach. - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter represents the - * starting point for calculating the minimum height of a tree. It can be either a root node (`R`), a - * key or node or entry (`BTNKeyOrNodeOrEntry`), or it defaults to the root of the current - * tree. - * @param {IterationType} iterationType - The `iterationType` parameter determines the type of - * iteration to be used when calculating the minimum height of the tree. It can have two possible - * values: - * @returns The function `getMinHeight` returns a number, which represents the minimum height of the - * binary tree. + * recursive or iterative approach in TypeScript. + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the + * `getMinHeight` function represents the starting node from which the minimum height of the binary + * tree will be calculated. It is either a node in the binary tree or a reference to the root of the + * tree. If not provided, the default value is the root + * @param {IterationType} iterationType - The `iterationType` parameter in the `getMinHeight` method + * specifies the type of iteration to use when calculating the minimum height of a binary tree. It + * can have two possible values: + * @returns The `getMinHeight` method returns the minimum height of the binary tree starting from the + * specified root node. The height is calculated based on the shortest path from the root node to a + * leaf node in the tree. The method uses either a recursive approach or an iterative approach (using + * a stack) based on the `iterationType` parameter. */ getMinHeight( - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType ): number { beginRoot = this.ensureNode(beginRoot); @@ -1094,26 +995,25 @@ export class BinaryTree< * Time Complexity: O(log n) * Space Complexity: O(log n) * - * The function `getPathToRoot` in TypeScript retrieves the path from a given node to the root node - * in a tree structure, applying a specified callback function along the way. - * @param {C} callback - The `callback` parameter is a function that is expected to be of type - * `BTNCallback>`. It is used to process each node as the function traverses up - * the tree from the `beginNode`. - * @param {R | BTNKeyOrNodeOrEntry} beginNode - The `beginNode` parameter in the - * `getPathToRoot` function represents the starting node from which you want to traverse up to the - * root node in a tree structure. It can be either a reference to a node (`NODE`), a key-value pair - * (`K, V`), or an entry + * The function `getPathToRoot` in TypeScript retrieves the path from a given node to the root of a + * tree structure, applying a specified callback function along the way. + * @param {C} callback - The `callback` parameter is a function that is used to process each node in + * the path to the root. It is expected to be a function that takes a node as an argument and returns + * a value based on that node. The return type of the callback function is determined by the generic + * type `C + * @param {BTNKeyOrNodeOrEntry | R} beginNode - The `beginNode` parameter in the + * `getPathToRoot` function can be either a key, a node, an entry, or any other value of type `R`. * @param [isReverse=true] - The `isReverse` parameter in the `getPathToRoot` function determines - * whether the resulting path from the given node to the root should be reversed before returning it. - * If `isReverse` is set to `true`, the path will be reversed; otherwise, it will be returned as is. - * @returns The function `getPathToRoot` returns an array of the return type of the callback function - * `C`. The array contains the results of invoking the callback function on each node starting from - * the `beginNode` up to the root node in the tree structure. The order of nodes in the array can be - * reversed based on the `isReverse` parameter. + * whether the resulting path from the given `beginNode` to the root should be in reverse order or + * not. If `isReverse` is set to `true`, the path will be reversed before being returned. If `is + * @returns The function `getPathToRoot` returns an array of the return values of the callback + * function `callback` applied to each node in the path from the `beginNode` to the root node. The + * array is either in reverse order or in the original order based on the value of the `isReverse` + * parameter. */ getPathToRoot>>( - callback: C = this._DEFAULT_CALLBACK as C, - beginNode: R | BTNKeyOrNodeOrEntry, + callback: C = this._DEFAULT_BTN_CALLBACK as C, + beginNode: BTNKeyOrNodeOrEntry | R, isReverse = true ): ReturnType[] { const result: ReturnType[] = []; @@ -1137,23 +1037,23 @@ export class BinaryTree< * The function `getLeftMost` retrieves the leftmost node in a binary tree using either recursive or * tail-recursive iteration. * @param {C} callback - The `callback` parameter is a function that will be called with the leftmost - * node of a binary tree or null if the tree is empty. It has a default value of `_DEFAULT_CALLBACK` - * if not provided explicitly. - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter in the + * node of a binary tree or with `undefined` if the tree is empty. It is provided with a default + * value of `_DEFAULT_BTN_CALLBACK` if not specified. + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the * `getLeftMost` function represents the starting point for finding the leftmost node in a binary - * tree. It can be either a reference to the root node of the tree (`R`), or a key, node, or entry in - * the binary tree structure (` + * tree. It can be either a key, a node, or an entry in the binary tree structure. If no specific + * starting point is provided, the function will default * @param {IterationType} iterationType - The `iterationType` parameter in the `getLeftMost` function * specifies the type of iteration to be used when traversing the binary tree nodes. It can have two * possible values: * @returns The `getLeftMost` function returns the result of the callback function `C` applied to the - * leftmost node in the binary tree starting from the `beginRoot` node. If the `beginRoot` is `NIL`, - * it returns the result of the callback function applied to `undefined`. If the `beginRoot` is not a - * real node, it returns the result of the callback function applied + * leftmost node in the binary tree starting from the `beginRoot` node. If the `beginRoot` node is + * `NIL`, it returns the result of the callback function applied to `undefined`. If the `beginRoot` + * node is not a real node, it returns the result of the callback */ getLeftMost>>( - callback: C = this._DEFAULT_CALLBACK as C, - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + callback: C = this._DEFAULT_BTN_CALLBACK as C, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType ): ReturnType { if (this.isNIL(beginRoot)) return callback(undefined); @@ -1186,24 +1086,24 @@ export class BinaryTree< * The function `getRightMost` retrieves the rightmost node in a binary tree using either recursive * or iterative traversal methods. * @param {C} callback - The `callback` parameter is a function that will be called with the result - * of the operation. It has a generic type `C` which extends `BTNCallback>`. The - * default value for `callback` is `this._DEFAULT_CALLBACK` if it is not provided. - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter in the + * of finding the rightmost node in a binary tree. It is of type `BTNCallback>`, + * which means it is a callback function that can accept either an optional binary tree node or null + * as + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the * `getRightMost` function represents the starting point for finding the rightmost node in a binary - * tree. It can be either a reference to the root node of the tree (`this.root`) or a specific key, - * node, or entry in the tree. If + * tree. It can be either a key, a node, or an entry in the binary tree structure. If no specific + * starting point is provided, the function will default * @param {IterationType} iterationType - The `iterationType` parameter in the `getRightMost` - * function specifies the type of iteration to be used when finding the rightmost node in a binary - * tree. It can have two possible values: - * @returns The `getRightMost` function returns the result of the callback function `C` applied to - * the rightmost node in the binary tree. The rightmost node is found either through a recursive - * depth-first search (if `iterationType` is 'RECURSIVE') or through an indirect implementation of - * iteration using tail recursion optimization. The result of the callback function applied to the - * rightmost node is returned + * function specifies the type of iteration to be used when traversing the binary tree nodes. It can + * have two possible values: + * @returns The `getRightMost` function returns the result of the callback function `C`, which is + * passed as a parameter to the function. The callback function is called with the rightmost node in + * the binary tree structure, determined based on the specified iteration type ('RECURSIVE' or + * other). */ getRightMost>>( - callback: C = this._DEFAULT_CALLBACK as C, - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + callback: C = this._DEFAULT_BTN_CALLBACK as C, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType ): ReturnType { if (this.isNIL(beginRoot)) return callback(undefined); @@ -1233,10 +1133,14 @@ export class BinaryTree< * Time Complexity: O(log n) * Space Complexity: O(1) * - * The function returns the predecessor node of a given node in a binary tree. - * @param {NODE} node - The parameter "node" is of type "NODE", which represents a node in a binary - * tree. - * @returns the predecessor node of the given node. + * The function `getPredecessor` in TypeScript returns the predecessor node of a given node in a + * binary tree. + * @param {NODE} node - The `getPredecessor` function you provided seems to be attempting to find the + * predecessor of a given node in a binary tree. However, there seems to be a logical issue in the + * while loop condition that might cause an infinite loop. + * @returns The `getPredecessor` function returns the predecessor node of the input `NODE` parameter. + * If the left child of the input node exists, it traverses to the rightmost node of the left subtree + * to find the predecessor. If the left child does not exist, it returns the input node itself. */ getPredecessor(node: NODE): NODE { if (this.isRealNode(node.left)) { @@ -1256,10 +1160,14 @@ export class BinaryTree< * Time Complexity: O(log n) * Space Complexity: O(1) * - * The function `getSuccessor` returns the next node in a binary tree given a current node. - * @param {K | NODE | null} [x] - The parameter `x` can be of type `K`, `NODE`, or `null`. - * @returns The function `getSuccessor` returns a `NODE` object if a successor exists, `null` if - * there is no successor, and `undefined` if the input `x` is not a valid node. + * The function `getSuccessor` in TypeScript returns the next node in an in-order traversal of a + * binary tree. + * @param {K | NODE | null} [x] - The `getSuccessor` function takes a parameter `x`, which can be of + * type `K`, `NODE`, or `null`. + * @returns The `getSuccessor` function returns the successor node of the input node `x`. If `x` has + * a right child, the function returns the leftmost node in the right subtree of `x`. If `x` does not + * have a right child, the function traverses up the parent nodes until it finds a node that is not + * the right child of its parent, and returns that node */ getSuccessor(x?: K | NODE | null): OptBTNOrNull { x = this.ensureNode(x); @@ -1280,14 +1188,14 @@ export class BinaryTree< dfs>( callback?: C, pattern?: DFSOrderPattern, - beginRoot?: R | BTNKeyOrNodeOrEntry, + beginRoot?: BTNKeyOrNodeOrEntry | R, iterationType?: IterationType ): ReturnType[]; dfs>( callback?: C, pattern?: DFSOrderPattern, - beginRoot?: R | BTNKeyOrNodeOrEntry, + beginRoot?: BTNKeyOrNodeOrEntry | R, iterationType?: IterationType, includeNull?: boolean ): ReturnType[]; @@ -1296,29 +1204,32 @@ export class BinaryTree< * Time complexity: O(n) * Space complexity: O(n) * - * The `dfs` function performs a depth-first search traversal on a binary tree, executing a callback - * function on each node according to a specified pattern and iteration type. - * @param {C} callback - The `callback` parameter is a function that will be called for each node - * visited during the depth-first search. It takes a node as an argument and returns a value. The - * return type of the callback function is determined by the generic type `C`. - * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter determines the order in which the - * nodes are visited during the depth-first search. It can have one of the following values: - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter is the starting - * point of the depth-first search. It can be either a node object, a key-value pair, or a key. If it - * is a key or key-value pair, the method will find the corresponding node in the tree and start the - * search from there. - * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter determines the - * type of iteration to use during the depth-first search. It can have two possible values: - * @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines - * whether or not to include null values in the depth-first search traversal. If `includeNull` is set - * to `true`, null values will be included in the traversal. If `includeNull` is set to `false`, null - * values will - * @returns an array of the return types of the callback function. + * The function `dfs` performs a depth-first search traversal on a binary tree structure based on the + * specified parameters. + * @param {C} callback - The `callback` parameter is a generic type `C` that extends the + * `BTNCallback` interface with a type parameter of `OptBTNOrNull`. It has a default value of + * `this._DEFAULT_BTN_CALLBACK as C`. + * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `dfs` method specifies the + * order in which the Depth-First Search (DFS) algorithm should traverse the nodes in the tree. The + * possible values for the `pattern` parameter are: + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the `dfs` + * method is used to specify the starting point for the Depth-First Search traversal. It can be + * either a `BTNKeyOrNodeOrEntry` object representing a key, node, or entry in the binary tree map, + * or it can be a + * @param {IterationType} iterationType - The `iterationType` parameter in the `dfs` method specifies + * the type of iteration to be performed during the depth-first search traversal. It is used to + * determine the order in which nodes are visited during the traversal. + * @param [includeNull=false] - The `includeNull` parameter in the `dfs` method is a boolean flag + * that determines whether null values should be included in the traversal or not. If `includeNull` + * is set to `true`, then null values will be included in the traversal process. If it is set to + * `false`, + * @returns The `dfs` method is returning an array of the return type specified by the generic type + * parameter `C`. The return type is determined by the callback function provided to the method. */ dfs>>( - callback: C = this._DEFAULT_CALLBACK as C, + callback: C = this._DEFAULT_BTN_CALLBACK as C, pattern: DFSOrderPattern = 'IN', - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType, includeNull = false ): ReturnType[] { @@ -1329,14 +1240,14 @@ export class BinaryTree< bfs>( callback?: C, - beginRoot?: R | BTNKeyOrNodeOrEntry, + beginRoot?: BTNKeyOrNodeOrEntry | R, iterationType?: IterationType, includeNull?: false ): ReturnType[]; bfs>( callback?: C, - beginRoot?: R | BTNKeyOrNodeOrEntry, + beginRoot?: BTNKeyOrNodeOrEntry | R, iterationType?: IterationType, includeNull?: true ): ReturnType[]; @@ -1345,27 +1256,28 @@ export class BinaryTree< * Time complexity: O(n) * Space complexity: O(n) * - * The `bfs` function performs a breadth-first search on a binary tree, calling a callback function - * on each node and returning an array of the results. - * @param {C} callback - The `callback` parameter is a function that will be called for each node in - * the breadth-first search traversal. It takes a single argument, which is the current node being - * visited, and returns a value of any type. - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter represents the - * starting point of the breadth-first search. It can be either a root node of a tree or a key, node, - * or entry object. If no value is provided, the `root` property of the class is used as the default - * starting point. - * @param {IterationType} iterationType - The `iterationType` parameter determines the type of - * iteration to be performed. It can have two possible values: - * @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines - * whether or not to include null values in the breadth-first search (BFS) traversal. If - * `includeNull` is set to `true`, null values will be included in the traversal. If `includeNull` is - * set to `false - * @returns The function `bfs` returns an array of values that are the result of invoking the - * `callback` function on each node in the breadth-first order traversal of the binary tree. + * The `bfs` function performs a breadth-first search traversal on a binary tree or binary search + * tree, executing a specified callback function on each node visited. + * @param {C} callback - The `callback` parameter in the `bfs` function is a function that will be + * called on each node visited during the breadth-first search traversal. It is a generic type `C` + * that extends the `BTNCallback` type, which takes a parameter of type `NODE` or `null`. + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the `bfs` + * function represents the starting point for the breadth-first search traversal in a binary tree. It + * can be specified as a key, node, or entry in the binary tree structure. If not provided, the + * default value is the root node of the binary + * @param {IterationType} iterationType - The `iterationType` parameter in the `bfs` function + * determines the type of iteration to be performed on the binary tree nodes. It can have two + * possible values: + * @param [includeNull=false] - The `includeNull` parameter in the `bfs` function determines whether + * to include `null` values in the breadth-first search traversal of a binary tree. If `includeNull` + * is set to `true`, the traversal will include `null` values for nodes that do not have children + * (left + * @returns The `bfs` function returns an array of values that are the result of applying the + * provided callback function to each node in the binary tree in a breadth-first search manner. */ bfs>( - callback: C = this._DEFAULT_CALLBACK as C, - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + callback: C = this._DEFAULT_BTN_CALLBACK as C, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType, includeNull = false ): ReturnType[] { @@ -1421,24 +1333,23 @@ export class BinaryTree< * Time complexity: O(n) * Space complexity: O(n) * - * The `leaves` function in TypeScript iterates through a binary tree to find and return the leaf - * nodes based on a specified callback and iteration type. + * The `leaves` function in TypeScript returns an array of values from leaf nodes in a binary tree + * structure based on a specified callback and iteration type. * @param {C} callback - The `callback` parameter is a function that will be called on each leaf node - * in the binary tree. It is a generic type `C` that extends `BTNCallback`, where `NODE` - * represents a node in the binary tree. The default value for `callback` is - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter in the `leaves` + * in the binary tree. It is optional and defaults to a default callback function if not provided. + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the `leaves` * method is used to specify the starting point for finding and processing the leaves of a binary - * tree. It represents the root node of the binary tree or a specific key, node, or entry within the - * tree from which the search for leaves should begin + * tree. It can be provided as either a key, a node, or an entry in the binary tree structure. If not + * explicitly provided, the default value * @param {IterationType} iterationType - The `iterationType` parameter in the `leaves` method * specifies the type of iteration to be performed when collecting the leaves of a binary tree. It * can have two possible values: * @returns The `leaves` method returns an array of values that are the result of applying the - * provided callback function to the leaf nodes in the binary tree structure. + * provided callback function to each leaf node in the binary tree. */ leaves>( - callback: C = this._DEFAULT_CALLBACK as C, - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + callback: C = this._DEFAULT_BTN_CALLBACK as C, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType ): ReturnType[] { beginRoot = this.ensureNode(beginRoot); @@ -1475,14 +1386,14 @@ export class BinaryTree< listLevels>( callback?: C, - beginRoot?: R | BTNKeyOrNodeOrEntry, + beginRoot?: BTNKeyOrNodeOrEntry | R, iterationType?: IterationType, includeNull?: false ): ReturnType[][]; listLevels>( callback?: C, - beginRoot?: R | BTNKeyOrNodeOrEntry, + beginRoot?: BTNKeyOrNodeOrEntry | R, iterationType?: IterationType, includeNull?: true ): ReturnType[][]; @@ -1491,26 +1402,29 @@ export class BinaryTree< * Time complexity: O(n) * Space complexity: O(n) * - * The `listLevels` function returns an array of arrays, where each inner array represents a level in - * a binary tree and contains the results of applying a callback function to the nodes at that level. - * @param {C} callback - The `callback` parameter is a function that will be called for each node in - * the tree. It takes a node as an argument and returns a value. The return type of the callback - * function is determined by the generic type `C` which extends `BTNCallback`. - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter represents the - * starting point for traversing the tree. It can be either a root node, a key-value pair, or a node - * entry. If no value is provided, the `root` property of the class is used as the default starting - * point. - * @param {IterationType} iterationType - The `iterationType` parameter determines the type of - * iteration to be performed on the binary tree. It can have two possible values: - * @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines - * whether or not to include null values in the resulting levels. If `includeNull` is set to `true`, - * null values will be included in the levels. If `includeNull` is set to `false`, null values will - * be excluded - * @returns The function `listLevels` returns a two-dimensional array of type `ReturnType[][]`. + * The `listLevels` function in TypeScript generates a list of nodes at each level of a binary tree, + * using either recursive or iterative traversal based on the specified iteration type. + * @param {C} callback - The `callback` parameter is a function that will be applied to each node in + * the binary tree during the traversal. It is used to process each node and determine what + * information to include in the output for each level of the tree. + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the + * `listLevels` function represents the starting point for traversing the binary tree. It can be + * either a key, a node, or an entry in the binary tree. If not provided, the default value is the + * root of the binary tree. + * @param {IterationType} iterationType - The `iterationType` parameter in the `listLevels` function + * determines the type of iteration to be performed on the binary tree nodes. It can have two + * possible values: + * @param [includeNull=false] - The `includeNull` parameter in the `listLevels` method determines + * whether or not to include null nodes in the traversal of the binary tree. If `includeNull` is set + * to `true`, the traversal will include null nodes in the levels of the tree. If set to `false`, + * null + * @returns The `listLevels` method returns an array of arrays, where each inner array represents a + * level in a binary tree. Each inner array contains the return value of the provided callback + * function applied to the nodes at that level. */ listLevels>( - callback: C = this._DEFAULT_CALLBACK as C, - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + callback: C = this._DEFAULT_BTN_CALLBACK as C, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType, includeNull = false ): ReturnType[][] { @@ -1559,25 +1473,26 @@ export class BinaryTree< * Time complexity: O(n) * Space complexity: O(n) * - * The `morris` function performs a depth-first traversal on a binary tree using the Morris traversal - * algorithm. - * @param {C} callback - The `callback` parameter is a function that will be called for each node in - * the tree. It takes a single argument, which is the current node, and can return any value. The - * return type of the `callback` function is determined by the `ReturnType` type, which represents - * the return - * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `morris` function is used - * to specify the order in which the nodes of a binary tree are traversed. It can take one of the - * following values: - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter is the starting - * point for the traversal. It can be either a node object, a key, or an entry object. If no value is - * provided, the `root` of the tree is used as the starting point. - * @returns The function `morris` returns an array of values that are the return values of the - * callback function `callback`. + * The `morris` function in TypeScript performs a Depth-First Search traversal on a binary tree using + * Morris Traversal algorithm with different order patterns. + * @param {C} callback - The `callback` parameter in the `morris` function is a function that will be + * called on each node in the binary tree during the traversal. It is of type `C`, which extends the + * `BTNCallback` type. The default value for `callback` is `this._DEFAULT + * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `morris` function specifies + * the type of Depth-First Search (DFS) order pattern to traverse the binary tree. The possible + * values for the `pattern` parameter are: + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the `morris` + * function is the starting point for the Morris traversal algorithm. It represents the root node of + * the binary tree or the node from which the traversal should begin. It can be provided as either a + * key, a node, an entry, or a reference + * @returns The `morris` function is returning an array of values that are the result of applying the + * provided callback function to each node in the binary tree in the specified order pattern (IN, + * PRE, or POST). */ morris>( - callback: C = this._DEFAULT_CALLBACK as C, + callback: C = this._DEFAULT_BTN_CALLBACK as C, pattern: DFSOrderPattern = 'IN', - beginRoot: R | BTNKeyOrNodeOrEntry = this.root + beginRoot: BTNKeyOrNodeOrEntry | R = this._root ): ReturnType[] { beginRoot = this.ensureNode(beginRoot); if (!beginRoot) return []; @@ -1664,8 +1579,12 @@ export class BinaryTree< * Time complexity: O(n) * Space complexity: O(n) * - * The `clone` function creates a deep copy of a tree object. - * @returns The `clone()` method is returning a cloned instance of the `TREE` object. + * The `clone` function creates a deep copy of a tree structure by traversing it using breadth-first + * search. + * @returns The `clone()` method is returning a cloned copy of the tree with the same structure and + * values as the original tree. The method creates a new tree, iterates over the nodes of the + * 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(): TREE { const cloned = this.createTree(); @@ -1674,7 +1593,7 @@ export class BinaryTree< if (node === null) cloned.add(null); else cloned.add([node.key, node.value]); }, - this.root, + this._root, this.iterationType, true ); @@ -1685,16 +1604,17 @@ export class BinaryTree< * Time Complexity: O(n) * Space Complexity: O(n) * - * The `filter` function creates a new tree with entries that pass a given predicate function. - * @param predicate - The `predicate` parameter is a callback function that is used to test each - * element in the tree. It takes three arguments: `value`, `key`, and `index`. The `value` argument - * represents the value of the current element being processed, the `key` argument represents the key - * of the - * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to - * specify the value of `this` within the `predicate` function. When the `predicate` function is - * called, `thisArg` will be used as the value of `this` within the function. If `thisArg` - * @returns The `filter` method is returning a new tree object that contains the entries that pass - * the given predicate function. + * The `filter` function iterates over key-value pairs in a tree data structure and creates a new + * tree with elements that satisfy a given predicate. + * @param predicate - The `predicate` parameter in the `filter` method is a function that will be + * called with four arguments: the `value` of the current entry, the `key` of the current entry, the + * `index` of the current entry in the iteration, and the reference to the tree itself (` + * @param {any} [thisArg] - The `thisArg` parameter in the `filter` method allows you to specify the + * value of `this` that should be used when executing the `predicate` function. This is useful when + * the `predicate` function relies on the context of a specific object or value. By providing a + * `thisArg + * @returns The `filter` method is returning a new tree that contains entries that pass the provided + * predicate function. */ filter(predicate: EntryCallback, thisArg?: any) { const newTree = this.createTree(); @@ -1711,16 +1631,16 @@ export class BinaryTree< * Time Complexity: O(n) * Space Complexity: O(n) * - * The `map` function creates a new tree by applying a callback function to each entry in the current - * tree. - * @param callback - The callback parameter is a function that will be called for each entry in the - * tree. It takes three arguments: value, key, and index. The value argument represents the value of - * the current entry, the key argument represents the key of the current entry, and the index - * argument represents the index of the - * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value - * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be - * passed as the `this` value to the `callback` function. If `thisArg` is - * @returns The `map` method is returning a new tree object. + * The `map` function iterates over key-value pairs in a tree data structure, applies a callback + * function to each value, and returns a new tree with the updated values. + * @param callback - The `callback` parameter in the `map` method is a function that will be called + * on each entry in the tree. It takes four arguments: + * @param {any} [thisArg] - The `thisArg` parameter in the `map` function is an optional parameter + * that specifies the value to be passed as `this` when executing the callback function. If provided, + * the `thisArg` value will be used as the `this` value within the callback function. If `thisArg + * @returns The `map` method is returning a new tree with the entries modified by the provided + * callback function. Each entry in the original tree is passed to the callback function, and the + * result of the callback function is added to the new tree. */ map(callback: EntryCallback, thisArg?: any) { const newTree = this.createTree(); @@ -1745,18 +1665,22 @@ export class BinaryTree< * Time Complexity: O(n) * Space Complexity: O(n) * - * The `toVisual` function in TypeScript prints the binary tree structure with customizable options. - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter is the starting - * point for printing the binary tree. It can be either a node of the binary tree or a key or entry - * that exists in the binary tree. If no value is provided, the root of the binary tree will be used - * as the starting point. - * @param {BinaryTreePrintOptions} [options] - The `options` parameter is an optional object that - * allows you to customize the printing behavior. It has the following properties: - * @returns Nothing is being returned. The function has a return type of `void`, which means it does - * not return any value. + * The function `toVisual` in TypeScript overrides the visual representation of a binary tree with + * customizable options for displaying undefined, null, and sentinel nodes. + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the + * `toVisual` method is used to specify the starting point for visualizing the binary tree structure. + * It can be a node, key, entry, or the root of the tree. If no specific starting point is provided, + * the default is set to the root + * @param {BinaryTreePrintOptions} [options] - The `options` parameter in the `toVisual` method is an + * object that contains the following properties: + * @returns The `override toVisual` method returns a string that represents the visual display of the + * binary tree based on the provided options for showing undefined, null, and Red-Black NIL nodes. + * The method constructs the visual representation by calling the `_displayAux` method and appending + * the lines to the output string. The final output string contains the visual representation of the + * binary tree with the specified options. */ override toVisual( - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, options?: BinaryTreePrintOptions ): string { const opts = { isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false, ...options }; @@ -1790,14 +1714,14 @@ export class BinaryTree< protected _dfs>( callback?: C, pattern?: DFSOrderPattern, - beginRoot?: R | BTNKeyOrNodeOrEntry, + beginRoot?: BTNKeyOrNodeOrEntry | R, iterationType?: IterationType ): ReturnType[]; protected _dfs>( callback?: C, pattern?: DFSOrderPattern, - beginRoot?: R | BTNKeyOrNodeOrEntry, + beginRoot?: BTNKeyOrNodeOrEntry | R, iterationType?: IterationType, includeNull?: boolean ): ReturnType[]; @@ -1806,49 +1730,48 @@ export class BinaryTree< * Time complexity: O(n) * Space complexity: O(n) * - * The function `_dfs` performs a depth-first search traversal on a binary tree structure based on + * The `_dfs` function performs a depth-first search traversal on a binary tree structure based on * the specified order pattern and callback function. - * @param {C} callback - The `callback` parameter is a function that will be called on each node - * visited during the depth-first search. It is of type `C`, which extends - * `BTNCallback>`. The default value is set to `this._DEFAULT_CALLBACK` if not - * provided. + * @param {C} callback - The `callback` parameter in the `_dfs` method is a function that will be + * called on each node visited during the depth-first search traversal. It is of type `C`, which + * extends `BTNCallback>`. The default value for this parameter is `this._DEFAULT * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `_dfs` method specifies the - * order in which the Depth-First Search (DFS) algorithm should traverse the nodes in a binary tree. - * It can have one of the following values: - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter in the `_dfs` + * order in which the nodes are visited during the Depth-First Search traversal. It can have one of + * the following values: + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the `_dfs` * method is used to specify the starting point for the depth-first search traversal in a binary - * tree. It can be provided as either the root node of the tree or a key, node, or entry that exists - * in the tree. If no specific ` + * tree. It can be provided as either a `BTNKeyOrNodeOrEntry` object or a reference to the root node + * of the tree. If no specific * @param {IterationType} iterationType - The `iterationType` parameter in the `_dfs` method - * specifies the type of iteration to be performed during the Depth-First Search (DFS) traversal. It - * can have two possible values: + * specifies the type of iteration to be performed during the Depth-First Search (DFS) traversal of a + * binary tree. It can have two possible values: * @param [includeNull=false] - The `includeNull` parameter in the `_dfs` method is a boolean flag * that determines whether null nodes should be included in the depth-first search traversal. If - * `includeNull` is set to `true`, the traversal will consider null nodes as valid nodes to visit and - * process. If set to ` + * `includeNull` is set to `true`, null nodes will be considered during the traversal process. If it + * is set to `false`, * @param shouldVisitLeft - The `shouldVisitLeft` parameter is a function that takes a node as input * and returns a boolean value. It is used to determine whether the left child of a node should be * visited during the depth-first search traversal. By default, it checks if the node is truthy (not * null or undefined - * @param shouldVisitRight - The `shouldVisitRight` parameter is a function that takes a node as - * input and returns a boolean value. It is used to determine whether the right child of a node + * @param shouldVisitRight - The `shouldVisitRight` parameter is a function that takes a node as an + * argument and returns a boolean value. It is used to determine whether the right child of a node * should be visited during the depth-first search traversal. The default implementation checks if - * the node is truthy before visiting the right child. + * the node is truthy before visiting the right child * @param shouldVisitRoot - The `shouldVisitRoot` parameter is a function that takes a node as an - * argument and returns a boolean value. It is used to determine whether a given node should be + * argument and returns a boolean value. It is used to determine whether the root node should be * visited during the depth-first search traversal based on certain conditions. The default * implementation checks if the node is a real node or null based - * @param shouldProcessRoot - The `shouldProcessRoot` parameter is a function that takes a node as - * input and returns a boolean value indicating whether the node should be processed during the - * depth-first search traversal. The default implementation of this function simply returns `true`, - * meaning that by default all nodes will be processed. However, you can - * @returns The `_dfs` method returns an array of the return type of the callback function provided + * @param shouldProcessRoot - The `shouldProcessRoot` parameter is a function that takes a node as an + * argument and returns a boolean value indicating whether the node should be processed during the + * depth-first search traversal. The default implementation checks if the node is a real node or null + * based on the `includeNull` flag. If ` + * @returns The function `_dfs` returns an array of the return type of the callback function provided * as input. */ protected _dfs>>( - callback: C = this._DEFAULT_CALLBACK as C, + callback: C = this._DEFAULT_BTN_CALLBACK as C, pattern: DFSOrderPattern = 'IN', - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType, includeNull = false, shouldVisitLeft: (node: OptBTNOrNull) => boolean = node => !!node, @@ -1942,13 +1865,18 @@ export class BinaryTree< * Time Complexity: O(1) * Space Complexity: O(1) * - * The function `_getIterator` is a generator function that returns an iterator for the key-value - * pairs in a binary search tree. - * @param node - The `node` parameter represents the current node in the binary search tree. It is - * initially set to the root node of the tree. - * @returns an IterableIterator<[K, V | undefined]>. + * The function `_getIterator` returns an iterable iterator for a binary tree data structure, either + * using an iterative approach or a recursive approach based on the specified iteration type. + * @param node - The `node` parameter in the `_getIterator` method represents the current node being + * processed during iteration. It is initially set to the root node of the data structure (or the + * node passed as an argument), and then it is traversed through the data structure based on the + * iteration type specified (`ITER + * @returns The `_getIterator` method returns an IterableIterator containing key-value pairs of nodes + * in a binary tree structure. The method uses an iterative approach to traverse the tree based on + * the `iterationType` property. If the `iterationType` is set to 'ITERATIVE', the method uses a + * stack to perform an in-order traversal of the tree. If the `iterationType` is not 'ITERATIVE */ - protected *_getIterator(node = this.root): IterableIterator<[K, V | undefined]> { + protected *_getIterator(node = this._root): IterableIterator<[K, V | undefined]> { if (!node) return; if (this.iterationType === 'ITERATIVE') { @@ -1983,18 +1911,16 @@ export class BinaryTree< * Time Complexity: O(n) * Space Complexity: O(n) * - * The `_displayAux` function is responsible for generating the display layout of a binary tree node, - * taking into account various options such as whether to show null, undefined, or NaN nodes. - * @param {OptBTNOrNull} node - The `node` parameter represents a node in a binary tree. - * It can be of type `NODE`, `null`, or `undefined`. - * @param {BinaryTreePrintOptions} options - The `options` parameter is an object that contains the - * following properties: - * @returns The function `_displayAux` returns a `NodeDisplayLayout` which is an array containing the - * following elements: - * 1. `mergedLines`: An array of strings representing the lines of the node display. - * 2. `totalWidth`: The total width of the node display. - * 3. `totalHeight`: The total height of the node display. - * 4. `middleIndex`: The index of the middle character + * The function `_displayAux` in TypeScript is responsible for generating the display layout of nodes + * in a binary tree based on specified options. + * @param node - The `node` parameter in the `_displayAux` function represents a node in a binary + * tree. It can be either a valid node containing a key or a special type of node like null, + * undefined, or a Red-Black tree NIL node. The function checks the type of the node and its + * @param {BinaryTreePrintOptions} options - The `options` parameter in the `_displayAux` function + * contains the following properties: + * @returns The `_displayAux` function returns a `NodeDisplayLayout`, which is an array containing + * information about how to display a node in a binary tree. The `NodeDisplayLayout` consists of four + * elements: */ protected _displayAux(node: OptBTNOrNull, options: BinaryTreePrintOptions): NodeDisplayLayout { const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options; @@ -2064,24 +1990,26 @@ export class BinaryTree< } } - protected _DEFAULT_CALLBACK = (node: OptBTNOrNull) => (node ? node.key : undefined); + protected _DEFAULT_BTN_CALLBACK = (node: OptBTNOrNull) => (node ? node.key : undefined); /** * Time Complexity: O(1) * Space Complexity: O(1) * - * The function `_swapProperties` swaps the key-value properties between two nodes. - * @param {R | BTNKeyOrNodeOrEntry} srcNode - The source node that will be swapped with the - * destination node. It can be either an instance of the class `R`, or an object of type - * `BTNKeyOrNodeOrEntry`. - * @param {R | BTNKeyOrNodeOrEntry} destNode - The `destNode` parameter is the node where - * the properties will be swapped with the `srcNode`. - * @returns either the `destNode` object with its properties swapped with the `srcNode` object's - * properties, or `undefined` if either `srcNode` or `destNode` is falsy. + * The _swapProperties function swaps key and value properties between two nodes in a binary tree. + * @param {BTNKeyOrNodeOrEntry | R} srcNode - The `srcNode` parameter in the + * `_swapProperties` method can be either a BTNKeyOrNodeOrEntry object containing key and value + * properties, or it can be of type R. + * @param {BTNKeyOrNodeOrEntry | R} destNode - The `destNode` parameter in the + * `_swapProperties` method represents the node or entry where the properties will be swapped with + * the `srcNode`. It can be of type `BTNKeyOrNodeOrEntry` or `R`. The method ensures that + * both `srcNode + * @returns The `_swapProperties` method returns either the `destNode` with its key and value swapped + * with the `srcNode`, or `undefined` if either `srcNode` or `destNode` is falsy. */ protected _swapProperties( - srcNode: R | BTNKeyOrNodeOrEntry, - destNode: R | BTNKeyOrNodeOrEntry + srcNode: BTNKeyOrNodeOrEntry | R, + destNode: BTNKeyOrNodeOrEntry | R ): NODE | undefined { srcNode = this.ensureNode(srcNode); destNode = this.ensureNode(destNode); @@ -2107,13 +2035,15 @@ export class BinaryTree< * Time Complexity: O(1) * Space Complexity: O(1) * - * The function replaces a node in a binary tree with a new node, updating the parent, left child, - * right child, and root if necessary. - * @param {NODE} oldNode - The oldNode parameter represents the node that needs to be replaced in the - * tree. - * @param {NODE} newNode - The `newNode` parameter is the node that will replace the `oldNode` in the - * tree. - * @returns the newNode. + * The _replaceNode function replaces an old node with a new node in a binary tree structure. + * @param {NODE} oldNode - The `oldNode` parameter represents the node that you want to replace in a + * tree data structure. + * @param {NODE} newNode - The `newNode` parameter in the `_replaceNode` function represents the node + * that will replace the `oldNode` in a tree data structure. This function is responsible for + * updating the parent, left child, right child, and root (if necessary) references when replacing a + * node in the tree. + * @returns The method `_replaceNode` is returning the `newNode` that was passed as a parameter after + * replacing the `oldNode` with it in the binary tree structure. */ protected _replaceNode(oldNode: NODE, newNode: NODE): NODE { if (oldNode.parent) { @@ -2126,7 +2056,7 @@ export class BinaryTree< newNode.left = oldNode.left; newNode.right = oldNode.right; newNode.parent = oldNode.parent; - if (this.root === oldNode) { + if (this._root === oldNode) { this._setRoot(newNode); } @@ -2137,10 +2067,10 @@ export class BinaryTree< * Time Complexity: O(1) * Space Complexity: O(1) * - * The function sets the root property of an object to the provided value, and also updates the - * parent property of the new root. - * @param {OptBTNOrNull} v - The parameter `v` is of type `OptBTNOrNull`. This - * means that it can accept a value of type `NODE`, `null`, or `undefined`. + * The function _setRoot sets the root node of a data structure while updating the parent reference + * of the previous root node. + * @param v - The parameter `v` in the `_setRoot` method is of type `OptBTNOrNull`, which means + * it can either be an optional `NODE` type or `null`. */ protected _setRoot(v: OptBTNOrNull) { if (v) { @@ -2153,23 +2083,51 @@ export class BinaryTree< * Time Complexity: O(1) * Space Complexity: O(1) * - * The function `_ensureCallback` ensures that a callback function is provided and returns it. - * @param {ReturnType | null | undefined} identifier - The `identifier` parameter is of type - * `ReturnType | null | undefined`. This means it can accept a value that is the return type of - * the generic type `C`, or it can be `null` or `undefined`. - * @param {C} callback - The `callback` parameter is a function that takes a `node` as an argument - * and returns a value. It is of type `C`, which is a generic type that extends the - * `BTNCallback` type. - * @returns the callback parameter. + * The function `_ensurePredicate` in TypeScript ensures that the input is converted into a valid + * predicate function for a binary tree node. + * @param {BTNKeyOrNodeOrEntry | R | BTNPredicate} keyOrEntryOrRawOrPredicate - The + * `_ensurePredicate` method in the provided code snippet is responsible for ensuring that the input + * parameter `keyOrEntryOrRawOrPredicate` is transformed into a valid predicate function that can be + * used for filtering nodes in a binary tree. + * @returns A BTNPredicate function is being returned. */ - protected _ensureCallback>( - identifier: ReturnType | null | undefined, - callback: C = this._DEFAULT_CALLBACK as C - ): C { - if ((!callback || callback === this._DEFAULT_CALLBACK) && this.isNode(identifier)) { - callback = (node => node) as C; + protected _ensurePredicate( + keyOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry | R | BTNPredicate + ): BTNPredicate { + if (keyOrEntryOrRawOrPredicate === null || keyOrEntryOrRawOrPredicate === undefined) + return (node: NODE) => (node ? false : false); + + if (this._isPredicated(keyOrEntryOrRawOrPredicate)) return keyOrEntryOrRawOrPredicate; + + if (this.isRealNode(keyOrEntryOrRawOrPredicate)) return (node: NODE) => node === keyOrEntryOrRawOrPredicate; + + if (this.isEntry(keyOrEntryOrRawOrPredicate)) { + const [key] = keyOrEntryOrRawOrPredicate; + return (node: NODE) => node.key === key; } - return callback; + if (this.isKey(keyOrEntryOrRawOrPredicate)) return (node: NODE) => node.key === keyOrEntryOrRawOrPredicate; + + if (this._toEntryFn) { + const [key] = this._toEntryFn(keyOrEntryOrRawOrPredicate); + return (node: NODE) => node.key === key; + } + return (node: NODE) => node.key === keyOrEntryOrRawOrPredicate; + } + + /** + * Time Complexity: O(1) + * Space Complexity: O(1) + * + * The function `_isPredicated` checks if a given parameter is a function. + * @param {any} p - The parameter `p` is a variable of type `any`, which means it can hold any type + * of value. In this context, the function `_isPredicated` is checking if `p` is a function that + * satisfies the type `BTNPredicate`. + * @returns The function is checking if the input `p` is a function and returning a boolean value + * based on that check. If `p` is a function, it will return `true`, indicating that `p` is a + * predicate function for a binary tree node. If `p` is not a function, it will return `false`. + */ + protected _isPredicated(p: any): p is BTNPredicate { + return typeof p === 'function'; } } diff --git a/src/data-structures/binary-tree/bst.ts b/src/data-structures/binary-tree/bst.ts index 31d1066..d3d00ab 100644 --- a/src/data-structures/binary-tree/bst.ts +++ b/src/data-structures/binary-tree/bst.ts @@ -1,8 +1,8 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import type { @@ -11,7 +11,9 @@ import type { BSTNodeNested, BSTOptions, BTNCallback, + BTNEntry, BTNKeyOrNodeOrEntry, + BTNPredicate, BTNPureKeyOrNodeOrEntry, Comparator, CP, @@ -19,7 +21,6 @@ import type { IterationType, OptBSTN } from '../../types'; -import { BTNEntry } from '../../types'; import { BinaryTree, BinaryTreeNode } from './binary-tree'; import { IBinaryTree } from '../../interfaces'; import { Queue } from '../queue'; @@ -106,14 +107,14 @@ export class BST< { /** * This is the constructor function for a Binary Search Tree class in TypeScript. - * @param keysOrNodesOrEntriesOrRawElements - The `keysOrNodesOrEntriesOrRawElements` parameter is an + * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter is an * iterable that can contain either keys, nodes, entries, or raw elements. These elements will be * added to the binary search tree during the construction of the object. * @param [options] - An optional object that contains additional options for the Binary Search Tree. * It can include a comparator function that defines the order of the elements in the tree. */ constructor( - keysOrNodesOrEntriesOrRawElements: Iterable> = [], + keysOrNodesOrEntriesOrRaws: Iterable> = [], options?: BSTOptions ) { super([], options); @@ -123,7 +124,7 @@ export class BST< if (comparator) this._comparator = comparator; } - if (keysOrNodesOrEntriesOrRawElements) this.addMany(keysOrNodesOrEntriesOrRawElements); + if (keysOrNodesOrEntriesOrRaws) this.addMany(keysOrNodesOrEntriesOrRaws); } protected override _root?: NODE = undefined; @@ -155,17 +156,18 @@ export class BST< * following properties: * @returns a new instance of the BST class with the provided options. */ - override createTree(options?: Partial>): TREE { + override createTree(options?: BSTOptions): TREE { return new BST([], { iterationType: this.iterationType, - comparator: this.comparator, + comparator: this._comparator, + toEntryFn: this._toEntryFn, ...options }) as TREE; } /** * The function overrides a method and converts a key, value pair or entry or raw element to a node. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - A variable that can be of + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - A variable that can be of * type R or BTNKeyOrNodeOrEntry. 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 @@ -173,10 +175,10 @@ export class BST< * @returns either a NODE object or undefined. */ override keyValueOrEntryOrRawElementToNode( - keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry, + keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R, value?: V ): OptBSTN { - return super.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement, value) ?? undefined; + return super.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value) ?? undefined; } /** @@ -185,8 +187,8 @@ export class BST< * * The function ensures the existence of a node in a data structure and returns it, or undefined if * it doesn't exist. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The parameter - * `keyOrNodeOrEntryOrRawElement` can accept a value of type `R`, which represents the key, node, + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The parameter + * `keyOrNodeOrEntryOrRaw` 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 @@ -195,25 +197,31 @@ export class BST< * not be ensured. */ override ensureNode( - keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry, + keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R, iterationType: IterationType = this.iterationType ): OptBSTN { - return super.ensureNode(keyOrNodeOrEntryOrRawElement, iterationType) ?? undefined; + return super.ensureNode(keyOrNodeOrEntryOrRaw, iterationType) ?? undefined; } /** * The function checks if the input is an instance of the BSTNode class. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The parameter - * `keyOrNodeOrEntryOrRawElement` can be of type `R` or `BTNKeyOrNodeOrEntry`. - * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRawElement` is + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The parameter + * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry`. + * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is * an instance of the `BSTNode` class. */ - override isNode( - keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry - ): keyOrNodeOrEntryOrRawElement is NODE { - return keyOrNodeOrEntryOrRawElement instanceof BSTNode; + override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R): keyOrNodeOrEntryOrRaw is NODE { + return keyOrNodeOrEntryOrRaw instanceof BSTNode; } + /** + * The function "override isKey" 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 isKey(key: any): key is K` function is returning a boolean value based on + * the result of the `isComparable` function with the condition `this.comparator !== + * this._DEFAULT_COMPARATOR`. + */ override isKey(key: any): key is K { return isComparable(key, this.comparator !== this._DEFAULT_COMPARATOR); } @@ -223,23 +231,23 @@ export class BST< * Space Complexity: O(1) * * The `add` function in TypeScript adds a new node to a binary search tree based on the key value. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The parameter - * `keyOrNodeOrEntryOrRawElement` can accept a value of type `R` or `BTNKeyOrNodeOrEntry`. + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The parameter + * `keyOrNodeOrEntryOrRaw` can accept a value of type `R` or `BTNKeyOrNodeOrEntry`. * @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. */ - override add(keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry, value?: V): boolean { - const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement, value); + override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R, value?: V): boolean { + const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value); if (newNode === undefined) return false; - if (this.root === undefined) { + if (this._root === undefined) { this._setRoot(newNode); this._size++; return true; } - let current = this.root; + let current = this._root; while (current !== undefined) { if (this.comparator(current.key, newNode.key) === 0) { this._replaceNode(current, newNode); @@ -270,7 +278,7 @@ export class BST< * * 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 keysOrNodesOrEntriesOrRawElements - An iterable containing keys, nodes, entries, or raw + * @param keysOrNodesOrEntriesOrRaws - 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 @@ -286,7 +294,7 @@ export class BST< * successfully inserted into the data structure. */ override addMany( - keysOrNodesOrEntriesOrRawElements: Iterable>, + keysOrNodesOrEntriesOrRaws: Iterable>, values?: Iterable, isBalanceAdd = true, iterationType: IterationType = this.iterationType @@ -300,7 +308,7 @@ export class BST< } if (!isBalanceAdd) { - for (const kve of keysOrNodesOrEntriesOrRawElements) { + for (const kve of keysOrNodesOrEntriesOrRaws) { const value = valuesIterator?.next().value; const nn = this.add(kve, value); inserted.push(nn); @@ -311,13 +319,13 @@ export class BST< const realBTNExemplars: (R | BTNPureKeyOrNodeOrEntry)[] = []; const isRealBTNExemplar = ( - kve: R | BTNKeyOrNodeOrEntry + kve: BTNKeyOrNodeOrEntry | R ): kve is BTNPureKeyOrNodeOrEntry => { if (kve === undefined || kve === null) return false; return !(this.isEntry(kve) && (kve[0] === undefined || kve[0] === null)); }; - for (const kve of keysOrNodesOrEntriesOrRawElements) { + for (const kve of keysOrNodesOrEntriesOrRaws) { if (isRealBTNExemplar(kve)) realBTNExemplars.push(kve); } @@ -327,16 +335,16 @@ export class BST< let keyA: K | undefined | null, keyB: K | undefined | null; if (this.isEntry(a)) keyA = a[0]; else if (this.isRealNode(a)) keyA = a.key; - else if (this.toEntryFn) { - keyA = this.toEntryFn(a as R)[0]; + else if (this._toEntryFn) { + keyA = this._toEntryFn(a as R)[0]; } else { keyA = a as K; } if (this.isEntry(b)) keyB = b[0]; else if (this.isRealNode(b)) keyB = b.key; - else if (this.toEntryFn) { - keyB = this.toEntryFn(b as R)[0]; + else if (this._toEntryFn) { + keyB = this._toEntryFn(b as R)[0]; } else { keyB = b as K; } @@ -388,51 +396,49 @@ export class BST< * Time Complexity: O(log n) * Space Complexity: O(k + log n) * - * The `getNodes` function in TypeScript retrieves nodes from a binary tree based on a given - * identifier and callback function. - * @param {ReturnType | undefined} identifier - The `identifier` parameter is the value that you - * want to search for in the binary tree. It can be of any type that is returned by the callback - * function. - * @param {C} callback - The `callback` parameter is a function that takes a node as input and - * returns a value. This value is used to identify the nodes that match the given identifier. The - * `callback` function is optional and defaults to `this._DEFAULT_CALLBACK`. - * @param [onlyOne=false] - A boolean value indicating whether to return only the first matching node - * or all matching nodes. If set to true, only the first matching node will be returned. If set to - * false, all matching nodes will be returned. The default value is false. - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter is the starting - * point for the search in the binary tree. It can be either a node object, a key-value pair, or an - * entry object. If it is not provided, the `root` of the binary tree is used as the starting point. - * @param {IterationType} iterationType - The `iterationType` parameter determines the type of - * iteration to be performed. It can have two possible values: - * @returns The method `getNodes` returns an array of `NODE` objects. + * The function `getNodes` in TypeScript overrides the base class method to retrieve nodes based on a + * given predicate and iteration type. + * @param {BTNKeyOrNodeOrEntry | R | BTNPredicate} predicate - The `predicate` + * parameter in the `getNodes` method is used to filter the nodes that will be returned. It can be a + * key, a node, an entry, or a custom predicate function that determines whether a node should be + * included in the result. + * @param [onlyOne=false] - The `onlyOne` parameter in the `getNodes` method is a boolean flag that + * determines whether to return only the first node that matches the predicate (`true`) or all nodes + * that match the predicate (`false`). If `onlyOne` is set to `true`, the method will stop iterating + * and + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter in the + * `getNodes` method is used to specify the starting point for traversing the tree when searching for + * nodes that match a given predicate. It represents the root node of the subtree where the search + * should begin. If not explicitly provided, the default value for `begin + * @param {IterationType} iterationType - The `iterationType` parameter in the `getNodes` method + * specifies the type of iteration to be performed when traversing the nodes of a binary tree. It can + * have two possible values: + * @returns The `getNodes` method returns an array of nodes that satisfy the given predicate. */ - override getNodes>( - identifier: ReturnType | undefined, - callback: C = this._DEFAULT_CALLBACK as C, + override getNodes( + predicate: BTNKeyOrNodeOrEntry | R | BTNPredicate, onlyOne = false, - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType ): NODE[] { - if (identifier === undefined) return []; - if (identifier === null) return []; + if (predicate === undefined) return []; + if (predicate === null) return []; beginRoot = this.ensureNode(beginRoot); if (!beginRoot) return []; - callback = this._ensureCallback(identifier, callback); + const callback = this._ensurePredicate(predicate); const ans: NODE[] = []; if (iterationType === 'RECURSIVE') { const dfs = (cur: NODE) => { - const callbackResult = callback(cur); - if (callbackResult === identifier) { + if (callback(cur)) { ans.push(cur); if (onlyOne) return; } if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return; - // TODO potential bug - if (callback === this._DEFAULT_CALLBACK) { - if (this.isRealNode(cur.left) && this.comparator(cur.key, identifier as K) > 0) dfs(cur.left); - if (this.isRealNode(cur.right) && this.comparator(cur.key, identifier as K) < 0) dfs(cur.right); + if (this.isKey(predicate)) { + if (this.isRealNode(cur.left) && this.comparator(cur.key, predicate) > 0) dfs(cur.left); + if (this.isRealNode(cur.right) && this.comparator(cur.key, predicate) < 0) dfs(cur.right); } else { if (this.isRealNode(cur.left)) dfs(cur.left); if (this.isRealNode(cur.right)) dfs(cur.right); @@ -444,23 +450,13 @@ export class BST< const stack = [beginRoot]; while (stack.length > 0) { const cur = stack.pop()!; - const callbackResult = callback(cur); - if (callbackResult === identifier) { + if (callback(cur)) { ans.push(cur); if (onlyOne) return ans; } - // TODO potential bug - if (callback === this._DEFAULT_CALLBACK) { - if (this.isRealNode(cur.right) && this.comparator(cur.key, identifier as K) < 0) stack.push(cur.right); - if (this.isRealNode(cur.left) && this.comparator(cur.key, identifier as K) > 0) stack.push(cur.left); - - // if (this.isRealNode(cur.right) && this._lt(cur.key, identifier as K)) stack.push(cur.right); - // if (this.isRealNode(cur.left) && this._gt(cur.key, identifier as K)) stack.push(cur.left); - - // // @ts-ignore - // if (this.isRealNode(cur.right) && cur.key > identifier) stack.push(cur.right); - // // @ts-ignore - // if (this.isRealNode(cur.left) && cur.key < identifier) stack.push(cur.left); + if (this.isKey(predicate)) { + if (this.isRealNode(cur.right) && this.comparator(cur.key, predicate) < 0) stack.push(cur.right); + if (this.isRealNode(cur.left) && this.comparator(cur.key, predicate) > 0) stack.push(cur.left); } else { if (this.isRealNode(cur.right)) stack.push(cur.right); if (this.isRealNode(cur.left)) stack.push(cur.left); @@ -475,30 +471,28 @@ export class BST< * Time Complexity: O(log n) * Space Complexity: O(1) * - * The function `getNode` returns the first node that matches the given identifier and callback - * function in a binary search tree. - * @param {ReturnType | undefined} identifier - The `identifier` parameter is the value that you - * want to search for in the binary search tree. It can be of any type that is compatible with the - * type returned by the callback function. - * @param {C} callback - The `callback` parameter is a function that will be used to determine if a - * node matches the desired criteria. It should be a function that takes a node as an argument and - * returns a boolean value indicating whether the node matches the criteria or not. If no callback is - * provided, the default callback will be - * @param beginRoot - The `beginRoot` parameter is the starting point for the search in the binary - * search tree. It can be either a key or a node. If it is a key, the search will start from the node - * with that key. If it is a node, the search will start from that node. - * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type - * of iteration to be performed when searching for nodes in the binary search tree. It can have one - * of the following values: - * @returns The method is returning a NODE object or undefined. + * This function retrieves a node based on a given predicate within a binary search tree structure. + * @param {BTNKeyOrNodeOrEntry | R | BTNPredicate} predicate - The `predicate` + * parameter can be of type `BTNKeyOrNodeOrEntry`, `R`, or `BTNPredicate`. + * @param {R | BSTNKeyOrNode} beginRoot - The `beginRoot` 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 (`OptBSTN`). + * It is using the `getNodes` method to find the node based on the provided predicate, beginning at + * the specified root node (`beginRoot`) and using the specified iteration type. The method then + * returns the first node found or `undefined` if no node is found. */ - override getNode>( - identifier: ReturnType | undefined, - callback: C = this._DEFAULT_CALLBACK as C, - beginRoot: R | BSTNKeyOrNode = this.root, + override getNode( + predicate: BTNKeyOrNodeOrEntry | R | BTNPredicate, + beginRoot: R | BSTNKeyOrNode = this._root, iterationType: IterationType = this.iterationType ): OptBSTN { - return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined; + return this.getNodes(predicate, true, beginRoot, iterationType)[0] ?? undefined; } /** @@ -515,7 +509,7 @@ export class BST< * @returns The method is returning a NODE object or undefined. */ override getNodeByKey(key: K, iterationType: IterationType = this.iterationType): OptBSTN { - return this.getNode(key, this._DEFAULT_CALLBACK, this.root, iterationType); + return this.getNode(key, this._root, iterationType); } /** @@ -526,11 +520,11 @@ export class BST< * the callback function. * @param {C} callback - The `callback` parameter is a function that will be called for each node * during the depth-first search traversal. It is an optional parameter and defaults to - * `this._DEFAULT_CALLBACK`. The type `C` represents the type of the callback function. + * `this._DEFAULT_BTN_CALLBACK`. The type `C` represents the type of the callback function. * @param {DFSOrderPattern} [pattern=IN] - The "pattern" parameter in the code snippet refers to the * order in which the Depth-First Search (DFS) algorithm visits the nodes in a tree or graph. It can * take one of the following values: - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter is the starting + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` parameter is the starting * point for the depth-first search traversal. It can be either a root node, a key-value pair, or a * node entry. If not specified, the default value is the root of the tree. * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter specifies the @@ -539,9 +533,9 @@ export class BST< * @returns The method is returning an array of the return type of the callback function. */ override dfs>( - callback: C = this._DEFAULT_CALLBACK as C, + callback: C = this._DEFAULT_BTN_CALLBACK as C, pattern: DFSOrderPattern = 'IN', - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType ): ReturnType[] { return super.dfs(callback, pattern, beginRoot, iterationType); @@ -556,7 +550,7 @@ export class BST< * @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 {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter is the starting + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` 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 @@ -565,8 +559,8 @@ export class BST< * @returns an array of the return type of the callback function. */ override bfs>( - callback: C = this._DEFAULT_CALLBACK as C, - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + callback: C = this._DEFAULT_BTN_CALLBACK as C, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType ): ReturnType[] { return super.bfs(callback, beginRoot, iterationType, false); @@ -581,7 +575,7 @@ export class BST< * @param {C} callback - The `callback` parameter is a generic type `C` that extends * `BTNCallback`. It represents a callback function that will be called for each node in the * tree during the iteration process. - * @param {R | BTNKeyOrNodeOrEntry} beginRoot - The `beginRoot` parameter is the starting + * @param {BTNKeyOrNodeOrEntry | R} beginRoot - The `beginRoot` 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 @@ -591,8 +585,8 @@ export class BST< * function. */ override listLevels>( - callback: C = this._DEFAULT_CALLBACK as C, - beginRoot: R | BTNKeyOrNodeOrEntry = this.root, + callback: C = this._DEFAULT_BTN_CALLBACK as C, + beginRoot: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType ): ReturnType[][] { return super.listLevels(callback, beginRoot, iterationType, false); @@ -610,7 +604,7 @@ export class BST< * @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 {R | BTNKeyOrNodeOrEntry} targetNode - The `targetNode` parameter is the node in + * @param {BTNKeyOrNodeOrEntry | R} 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, @@ -620,14 +614,14 @@ export class BST< * `ReturnType`, which is the return type of the callback function passed as an argument. */ lesserOrGreaterTraverse>( - callback: C = this._DEFAULT_CALLBACK as C, + callback: C = this._DEFAULT_BTN_CALLBACK as C, lesserOrGreater: CP = -1, - targetNode: R | BTNKeyOrNodeOrEntry = this.root, + targetNode: BTNKeyOrNodeOrEntry | R = this._root, iterationType: IterationType = this.iterationType ): ReturnType[] { const targetNodeEnsured = this.ensureNode(targetNode); const ans: ReturnType>[] = []; - if (!this.root) return ans; + if (!this._root) return ans; if (!targetNodeEnsured) return ans; const targetKey = targetNodeEnsured.key; @@ -641,10 +635,10 @@ export class BST< if (this.isRealNode(cur.right)) dfs(cur.right); }; - dfs(this.root); + dfs(this._root); return ans; } else { - const queue = new Queue([this.root]); + const queue = new Queue([this._root]); while (queue.size > 0) { const cur = queue.shift(); if (this.isRealNode(cur)) { @@ -721,7 +715,7 @@ export class BST< * @returns a boolean value. */ isAVLBalanced(iterationType: IterationType = this.iterationType): boolean { - if (!this.root) return true; + if (!this._root) return true; let balanced = true; @@ -733,10 +727,10 @@ export class BST< if (Math.abs(leftHeight - rightHeight) > 1) balanced = false; return Math.max(leftHeight, rightHeight) + 1; }; - _height(this.root); + _height(this._root); } else { const stack: NODE[] = []; - let node: OptBSTN = this.root, + let node: OptBSTN = this._root, last: OptBSTN = undefined; const depths: Map = new Map(); diff --git a/src/data-structures/binary-tree/rb-tree.ts b/src/data-structures/binary-tree/rb-tree.ts index d662f05..18da22a 100644 --- a/src/data-structures/binary-tree/rb-tree.ts +++ b/src/data-structures/binary-tree/rb-tree.ts @@ -1,14 +1,15 @@ import type { BinaryTreeDeleteResult, - BTNCallback, BTNKeyOrNodeOrEntry, + BTNPredicate, CRUD, + OptBSTN, RBTNColor, RBTreeOptions, RedBlackTreeNested, - RedBlackTreeNodeNested + RedBlackTreeNodeNested, + BTNEntry } from '../../types'; -import { BTNEntry } from '../../types'; import { BST, BSTNode } from './bst'; import { IBinaryTree } from '../../interfaces'; @@ -64,7 +65,7 @@ export class RedBlackTree< { /** * This is the constructor function for a Red-Black Tree data structure in TypeScript. - * @param keysOrNodesOrEntriesOrRawElements - The `keysOrNodesOrEntriesOrRawElements` parameter is an + * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter is an * iterable object that can contain either keys, nodes, entries, or raw elements. It is used to * initialize the RBTree with the provided elements. * @param [options] - The `options` parameter is an optional object that can be passed to the @@ -73,15 +74,15 @@ export class RedBlackTree< * depend on the implementation */ constructor( - keysOrNodesOrEntriesOrRawElements: Iterable> = [], + keysOrNodesOrEntriesOrRaws: Iterable> = [], options?: RBTreeOptions ) { super([], options); this._root = this.NIL; - if (keysOrNodesOrEntriesOrRawElements) { - this.addMany(keysOrNodesOrEntriesOrRawElements); + if (keysOrNodesOrEntriesOrRaws) { + this.addMany(keysOrNodesOrEntriesOrRaws); } } @@ -122,6 +123,8 @@ export class RedBlackTree< override createTree(options?: RBTreeOptions): TREE { return new RedBlackTree([], { iterationType: this.iterationType, + comparator: this._comparator, + toEntryFn: this._toEntryFn, ...options }) as TREE; } @@ -131,15 +134,13 @@ export class RedBlackTree< * Space Complexity: O(1) * * The function checks if the input is an instance of the RedBlackTreeNode class. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The parameter - * `keyOrNodeOrEntryOrRawElement` can be of type `R` or `BTNKeyOrNodeOrEntry`. - * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRawElement` is + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The parameter + * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry`. + * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is * an instance of the `RedBlackTreeNode` class. */ - override isNode( - keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry - ): keyOrNodeOrEntryOrRawElement is NODE { - return keyOrNodeOrEntryOrRawElement instanceof RedBlackTreeNode; + override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R): keyOrNodeOrEntryOrRaw is NODE { + return keyOrNodeOrEntryOrRaw instanceof RedBlackTreeNode; } // /** @@ -153,27 +154,27 @@ export class RedBlackTree< // * // * The function `keyValueOrEntryOrRawElementToNode` takes a key, value, or entry and returns a node if it is // * valid, otherwise it returns undefined. - // * @param {BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The key, value, or entry to convert. - // * @param {V} [value] - The value associated with the key (if `keyOrNodeOrEntryOrRawElement` is a key). + // * @param {BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRaw - The key, value, or entry to convert. + // * @param {V} [value] - The value associated with the key (if `keyOrNodeOrEntryOrRaw` is a key). // * @returns {NODE | undefined} - The corresponding Red-Black Tree node, or `undefined` if conversion fails. // */ - // override keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry, value?: V): NODE | undefined { + // override keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R, value?: V): NODE | undefined { // - // if (keyOrNodeOrEntryOrRawElement === null || keyOrNodeOrEntryOrRawElement === undefined) return; - // if (this.isNode(keyOrNodeOrEntryOrRawElement)) return keyOrNodeOrEntryOrRawElement; + // if (keyOrNodeOrEntryOrRaw === null || keyOrNodeOrEntryOrRaw === undefined) return; + // if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw; // - // if (this.toEntryFn) { - // const [key, entryValue] = this.toEntryFn(keyOrNodeOrEntryOrRawElement as R); + // if (this._toEntryFn) { + // const [key, entryValue] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R); // if (this.isKey(key)) return this.createNode(key, entryValue ?? value, 'RED'); // } // - // if (this.isEntry(keyOrNodeOrEntryOrRawElement)) { - // const [key, value] = keyOrNodeOrEntryOrRawElement; + // if (this.isEntry(keyOrNodeOrEntryOrRaw)) { + // const [key, value] = keyOrNodeOrEntryOrRaw; // if (key === undefined || key === null) return; // else return this.createNode(key, value, 'RED'); // } // - // if (this.isKey(keyOrNodeOrEntryOrRawElement)) return this.createNode(keyOrNodeOrEntryOrRawElement, value, 'RED'); + // if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.createNode(keyOrNodeOrEntryOrRaw, value, 'RED'); // // return ; // } @@ -196,8 +197,8 @@ export class RedBlackTree< * * The function adds a new node to a binary search tree and returns true if the node was successfully * added. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The parameter - * `keyOrNodeOrEntryOrRawElement` can accept a value of type `R` or `BTNKeyOrNodeOrEntry`. + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The parameter + * `keyOrNodeOrEntryOrRaw` can accept a value of type `R` or `BTNKeyOrNodeOrEntry`. * @param {V} [value] - The `value` parameter is an optional value that you want to associate with * the key in the data structure. It represents the value that you want to add or update in the data * structure. @@ -205,8 +206,8 @@ export class RedBlackTree< * the method returns true. If the node already exists and its value is updated, the method also * returns true. If the node cannot be added or updated, the method returns false. */ - override add(keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry, value?: V): boolean { - const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement, value); + override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R, value?: V): boolean { + const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value); if (!this.isRealNode(newNode)) return false; const insertStatus = this._insert(newNode); @@ -227,26 +228,23 @@ export class RedBlackTree< * Time Complexity: O(log n) * Space Complexity: O(1) * - * The function overrides the delete method of a binary tree data structure, allowing for the - * deletion of a node and maintaining the balance of the tree. - * @param {ReturnType | null | undefined} identifier - The `identifier` parameter is the value - * that identifies the node to be deleted from the binary tree. It can be of any type that is - * returned by the callback function `C`. It can also be `null` or `undefined` if there is no node to - * delete. - * @param {C} callback - The `callback` parameter is a function that is used to determine the - * equality of nodes in the binary tree. It is optional and has a default value of - * `this._DEFAULT_CALLBACK`. The type of the `callback` parameter is `C`, which is a generic type - * that extends the `BTNCallback - * @returns an array of BinaryTreeDeleteResult objects. + * The function overrides the delete method in a binary tree data structure to remove a node based on + * a given predicate and maintain the binary search tree properties. + * @param {BTNKeyOrNodeOrEntry | R | BTNPredicate} predicate - The `predicate` + * parameter in the `override delete` method is used to specify the condition or key based on which a + * node should be deleted from the binary tree. It can be a key, a node, an entry, or a predicate + * function that determines which node(s) should be deleted. + * @returns The `override delete` method is returning an array of `BinaryTreeDeleteResult` + * objects. Each object in the array contains information about the deleted node and whether + * balancing is needed. */ - override delete>( - identifier: ReturnType | null | undefined, - callback: C = this._DEFAULT_CALLBACK as C - ): BinaryTreeDeleteResult[] { - if (identifier === null) return []; + override delete(predicate: BTNKeyOrNodeOrEntry | R | BTNPredicate): BinaryTreeDeleteResult[] { + if (predicate === null) return []; + const results: BinaryTreeDeleteResult[] = []; - callback = this._ensureCallback(identifier, callback); - const nodeToDelete = this.isRealNode(identifier) ? identifier : this.getNode(identifier, callback); + let nodeToDelete: OptBSTN; + if (this._isPredicated(predicate)) nodeToDelete = this.getNode(predicate); + else nodeToDelete = this.isRealNode(predicate) ? predicate : this.getNode(predicate); if (!nodeToDelete) { return results; diff --git a/src/data-structures/binary-tree/segment-tree.ts b/src/data-structures/binary-tree/segment-tree.ts index 2ad1cc3..614b2fa 100644 --- a/src/data-structures/binary-tree/segment-tree.ts +++ b/src/data-structures/binary-tree/segment-tree.ts @@ -1,8 +1,8 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ diff --git a/src/data-structures/binary-tree/tree-multi-map.ts b/src/data-structures/binary-tree/tree-multi-map.ts index d7388e2..c381ba5 100644 --- a/src/data-structures/binary-tree/tree-multi-map.ts +++ b/src/data-structures/binary-tree/tree-multi-map.ts @@ -1,22 +1,23 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import type { BinaryTreeDeleteResult, BSTNKeyOrNode, - BTNCallback, BTNKeyOrNodeOrEntry, + BTNPredicate, IterationType, + OptBSTN, RBTNColor, TreeMultiMapNested, TreeMultiMapNodeNested, - TreeMultiMapOptions + TreeMultiMapOptions, + BTNEntry } from '../../types'; -import { BTNEntry } from '../../types'; import { IBinaryTree } from '../../interfaces'; import { RedBlackTree, RedBlackTreeNode } from './rb-tree'; @@ -74,7 +75,7 @@ export class TreeMultiMap< { /** * The constructor function initializes a TreeMultiMap object with optional initial data. - * @param keysOrNodesOrEntriesOrRawElements - The parameter `keysOrNodesOrEntriesOrRawElements` is an + * @param keysOrNodesOrEntriesOrRaws - The parameter `keysOrNodesOrEntriesOrRaws` is an * iterable that can contain keys, nodes, entries, or raw elements. It is used to initialize the * TreeMultiMap with initial data. * @param [options] - The `options` parameter is an optional object that can be used to customize the @@ -82,11 +83,11 @@ export class TreeMultiMap< * `compareValues`, which are functions used to compare keys and values respectively. */ constructor( - keysOrNodesOrEntriesOrRawElements: Iterable> = [], + keysOrNodesOrEntriesOrRaws: Iterable> = [], options?: TreeMultiMapOptions ) { super([], options); - if (keysOrNodesOrEntriesOrRawElements) this.addMany(keysOrNodesOrEntriesOrRawElements); + if (keysOrNodesOrEntriesOrRaws) this.addMany(keysOrNodesOrEntriesOrRaws); } protected _count = 0; @@ -142,6 +143,8 @@ export class TreeMultiMap< override createTree(options?: TreeMultiMapOptions): TREE { return new TreeMultiMap([], { iterationType: this.iterationType, + comparator: this._comparator, + toEntryFn: this._toEntryFn, ...options }) as TREE; } @@ -149,8 +152,8 @@ export class TreeMultiMap< /** * The function `keyValueOrEntryOrRawElementToNode` takes in a key, value, and count and returns a * node based on the input. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The parameter - * `keyOrNodeOrEntryOrRawElement` can be of type `R` or `BTNKeyOrNodeOrEntry`. + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The parameter + * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry`. * @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. @@ -159,42 +162,39 @@ export class TreeMultiMap< * @returns either a NODE object or undefined. */ override keyValueOrEntryOrRawElementToNode( - keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry, + keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R, value?: V, count = 1 ): NODE | undefined { - if (keyOrNodeOrEntryOrRawElement === undefined || keyOrNodeOrEntryOrRawElement === null) return; + if (keyOrNodeOrEntryOrRaw === undefined || keyOrNodeOrEntryOrRaw === null) return; - if (this.isNode(keyOrNodeOrEntryOrRawElement)) return keyOrNodeOrEntryOrRawElement; + if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw; - if (this.isEntry(keyOrNodeOrEntryOrRawElement)) { - const [key, entryValue] = keyOrNodeOrEntryOrRawElement; + if (this.isEntry(keyOrNodeOrEntryOrRaw)) { + const [key, entryValue] = keyOrNodeOrEntryOrRaw; if (key === undefined || key === null) return; if (this.isKey(key)) return this.createNode(key, value ?? entryValue, 'BLACK', count); } - if (this.toEntryFn) { - const [key, entryValue] = this.toEntryFn(keyOrNodeOrEntryOrRawElement as R); + if (this._toEntryFn) { + const [key, entryValue] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R); if (this.isKey(key)) return this.createNode(key, value ?? entryValue, 'BLACK', count); } - if (this.isKey(keyOrNodeOrEntryOrRawElement)) - return this.createNode(keyOrNodeOrEntryOrRawElement, value, 'BLACK', count); + if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.createNode(keyOrNodeOrEntryOrRaw, value, 'BLACK', count); return; } /** * The function checks if the input is an instance of the TreeMultiMapNode class. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The parameter - * `keyOrNodeOrEntryOrRawElement` can be of type `R` or `BTNKeyOrNodeOrEntry`. - * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRawElement` is + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The parameter + * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry`. + * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is * an instance of the `TreeMultiMapNode` class. */ - override isNode( - keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry - ): keyOrNodeOrEntryOrRawElement is NODE { - return keyOrNodeOrEntryOrRawElement instanceof TreeMultiMapNode; + override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R): keyOrNodeOrEntryOrRaw is NODE { + return keyOrNodeOrEntryOrRaw instanceof TreeMultiMapNode; } /** @@ -203,8 +203,8 @@ export class TreeMultiMap< * * The function overrides the add method of a class and adds a new node to a data structure, updating * the count and returning a boolean indicating success. - * @param {R | BTNKeyOrNodeOrEntry} keyOrNodeOrEntryOrRawElement - The - * `keyOrNodeOrEntryOrRawElement` parameter can accept one of the following types: + * @param {BTNKeyOrNodeOrEntry | R} keyOrNodeOrEntryOrRaw - The + * `keyOrNodeOrEntryOrRaw` parameter can accept one of the following types: * @param {V} [value] - The `value` parameter represents the value associated with the key in the * data structure. It is an optional parameter, so it can be omitted if not needed. * @param [count=1] - The `count` parameter represents the number of times the key-value pair should @@ -213,8 +213,8 @@ export class TreeMultiMap< * @returns The method is returning a boolean value. It returns true if the addition of the new node * was successful, and false otherwise. */ - override add(keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry, value?: V, count = 1): boolean { - const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement, value, count); + override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry | R, value?: V, count = 1): boolean { + const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value, count); const orgCount = newNode?.count || 0; const isSuccessAdded = super.add(newNode); @@ -230,30 +230,29 @@ export class TreeMultiMap< * Time Complexity: O(log n) * Space Complexity: O(1) * - * The function `delete` is used to remove a node from a binary tree and fix the tree if necessary. - * @param {ReturnType | null | undefined} identifier - The `identifier` parameter is the value or - * key that is used to identify the node that needs to be deleted from the binary tree. It can be of - * any type that is returned by the callback function `C`. It can also be `null` or `undefined` if - * the node to be deleted - * @param {C} callback - The `callback` parameter is a function that is used to determine the - * equality of nodes in the binary tree. It is optional and has a default value of - * `this._DEFAULT_CALLBACK`. The `callback` function is used to compare nodes when searching for a - * specific node or when performing other operations on the - * @param [ignoreCount=false] - A boolean flag indicating whether to ignore the count of the node - * being deleted. If set to true, the count of the node will not be taken into account when deleting - * it. If set to false, the count of the node will be decremented by 1 before deleting it. - * @returns an array of BinaryTreeDeleteResult objects. + * The function `delete` in TypeScript overrides the deletion operation in a binary tree data + * structure, handling cases where nodes have children and maintaining balance in the tree. + * @param {BTNKeyOrNodeOrEntry | R | BTNPredicate} predicate - The `predicate` + * parameter in the `delete` method is used to specify the condition or key based on which a node + * should be deleted from the binary tree. It can be a key, a node, an entry, or a predicate + * function. + * @param [ignoreCount=false] - The `ignoreCount` parameter in the `override delete` method is a + * boolean flag that determines whether to ignore the count of nodes when performing deletion. If + * `ignoreCount` is set to `true`, the method will delete the node regardless of its count. If + * `ignoreCount` is `false + * @returns The `override delete` method returns an array of `BinaryTreeDeleteResult` objects. */ - override delete>( - identifier: ReturnType | null | undefined, - callback: C = this._DEFAULT_CALLBACK as C, + override delete( + predicate: BTNKeyOrNodeOrEntry | R | BTNPredicate, ignoreCount = false ): BinaryTreeDeleteResult[] { - if (identifier === null) return []; - const results: BinaryTreeDeleteResult[] = []; - callback = this._ensureCallback(identifier, callback); + if (predicate === null) return []; - const nodeToDelete = this.isRealNode(identifier) ? identifier : this.getNode(identifier, callback); + const results: BinaryTreeDeleteResult[] = []; + + let nodeToDelete: OptBSTN; + if (this._isPredicated(predicate)) nodeToDelete = this.getNode(predicate); + else nodeToDelete = this.isRealNode(predicate) ? predicate : this.getNode(predicate); if (!nodeToDelete) { return results; diff --git a/src/data-structures/graph/abstract-graph.ts b/src/data-structures/graph/abstract-graph.ts index a9823d1..542ea06 100644 --- a/src/data-structures/graph/abstract-graph.ts +++ b/src/data-structures/graph/abstract-graph.ts @@ -1,8 +1,8 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import type { DijkstraResult, EntryCallback, VertexKey } from '../../types'; diff --git a/src/data-structures/graph/directed-graph.ts b/src/data-structures/graph/directed-graph.ts index 007589f..8648b90 100644 --- a/src/data-structures/graph/directed-graph.ts +++ b/src/data-structures/graph/directed-graph.ts @@ -1,8 +1,8 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import type { TopologicalStatus, VertexKey } from '../../types'; diff --git a/src/data-structures/graph/undirected-graph.ts b/src/data-structures/graph/undirected-graph.ts index 8223150..56ac8ef 100644 --- a/src/data-structures/graph/undirected-graph.ts +++ b/src/data-structures/graph/undirected-graph.ts @@ -1,8 +1,8 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import type { VertexKey } from '../../types'; diff --git a/src/data-structures/hash/hash-map.ts b/src/data-structures/hash/hash-map.ts index f89d79c..580deee 100644 --- a/src/data-structures/hash/hash-map.ts +++ b/src/data-structures/hash/hash-map.ts @@ -1,8 +1,8 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import type { @@ -111,7 +111,7 @@ export class HashMap extends IterableEntryBase { * @returns The top element or undefined if the heap is empty. */ pop(): E | undefined { - if (this.size === 0) return undefined; + if (this._size === 0) return undefined; const z = this.min!; if (z.child) { @@ -770,7 +770,7 @@ export class FibonacciHeap { * @protected */ protected _consolidate(): void { - const A: (FibonacciHeapNode | undefined)[] = new Array(this.size); + const A: (FibonacciHeapNode | undefined)[] = new Array(this._size); const elements = this.consumeLinkedList(this.root); let x: FibonacciHeapNode | undefined, y: FibonacciHeapNode | undefined, @@ -798,7 +798,7 @@ export class FibonacciHeap { A[d] = x; } - for (let i = 0; i < this.size; i++) { + for (let i = 0; i < this._size; i++) { if (A[i] && this.comparator(A[i]!.element, this.min!.element) <= 0) { this._min = A[i]!; } diff --git a/src/data-structures/linked-list/doubly-linked-list.ts b/src/data-structures/linked-list/doubly-linked-list.ts index 18fd125..431cb0a 100644 --- a/src/data-structures/linked-list/doubly-linked-list.ts +++ b/src/data-structures/linked-list/doubly-linked-list.ts @@ -1,8 +1,8 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import type { DoublyLinkedListOptions, ElementCallback } from '../../types'; @@ -267,7 +267,7 @@ export class DoublyLinkedList extends IterableElementBase= this.size) return undefined; + if (index < 0 || index >= this._size) return undefined; let current = this.head; for (let i = 0; i < index; i++) { current = current!.next; @@ -287,7 +287,7 @@ export class DoublyLinkedList extends IterableElementBase | undefined { - if (index < 0 || index >= this.size) return undefined; + if (index < 0 || index >= this._size) return undefined; let current = this.head; for (let i = 0; i < index; i++) { current = current!.next; @@ -331,12 +331,12 @@ export class DoublyLinkedList extends IterableElementBase this.size) return false; + if (index < 0 || index > this._size) return false; if (index === 0) { this.unshift(value); return true; } - if (index === this.size) { + if (index === this._size) { this.push(value); return true; } @@ -442,12 +442,12 @@ export class DoublyLinkedList extends IterableElementBase= this.size) return false; + if (index < 0 || index >= this._size) return false; if (index === 0) { this.shift(); return true; } - if (index === this.size - 1) { + if (index === this._size - 1) { this.pop(); return true; } @@ -505,7 +505,7 @@ export class DoublyLinkedList extends IterableElementBase + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import type { ElementCallback, SinglyLinkedListOptions } from '../../types'; @@ -237,7 +237,7 @@ export class SinglyLinkedList extends IterableElementBase= this.size) return undefined; + if (index < 0 || index >= this._size) return undefined; let current = this.head; for (let i = 0; i < index; i++) { current = current!.next; @@ -274,12 +274,12 @@ export class SinglyLinkedList extends IterableElementBase= this.size) return false; + if (index < 0 || index >= this._size) return false; if (index === 0) { this.shift(); return true; } - if (index === this.size - 1) { + if (index === this._size - 1) { this.pop(); return true; } @@ -348,12 +348,12 @@ export class SinglyLinkedList extends IterableElementBase this.size) return false; + if (index < 0 || index > this._size) return false; if (index === 0) { this.unshift(value); return true; } - if (index === this.size) { + if (index === this._size) { this.push(value); return true; } @@ -372,7 +372,7 @@ export class SinglyLinkedList extends IterableElementBase + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import type { SkipLinkedListOptions } from '../../types'; diff --git a/src/data-structures/matrix/matrix.ts b/src/data-structures/matrix/matrix.ts index 2f93c7b..73a3ca4 100644 --- a/src/data-structures/matrix/matrix.ts +++ b/src/data-structures/matrix/matrix.ts @@ -1,8 +1,8 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import type { MatrixOptions } from '../../types'; diff --git a/src/data-structures/matrix/navigator.ts b/src/data-structures/matrix/navigator.ts index 2d68ba9..3d1646f 100644 --- a/src/data-structures/matrix/navigator.ts +++ b/src/data-structures/matrix/navigator.ts @@ -1,8 +1,8 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import type { Direction, NavigatorParams, Turning } from '../../types'; diff --git a/src/data-structures/queue/deque.ts b/src/data-structures/queue/deque.ts index 939ed15..f922959 100644 --- a/src/data-structures/queue/deque.ts +++ b/src/data-structures/queue/deque.ts @@ -1,8 +1,8 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import type { DequeOptions, ElementCallback, IterableWithSizeOrLength } from '../../types'; @@ -163,7 +163,7 @@ export class Deque extends IterableElementBase extends IterableElementBase extends IterableElementBase extends IterableElementBase 0) { this._lastInBucket -= 1; } else if (this._bucketLast > 0) { @@ -241,7 +241,7 @@ export class Deque extends IterableElementBase 0) { this._firstInBucket -= 1; } else if (this._bucketFirst > 0) { @@ -269,9 +269,9 @@ export class Deque extends IterableElementBase extends IterableElementBase extends IterableElementBase { let index = 0; - while (index < this.size) { + while (index < this._size) { yield this.at(index); index++; } @@ -327,7 +327,7 @@ export class Deque extends IterableElementBase { - let index = this.size - 1; + let index = this._size - 1; while (index >= 0) { yield this.at(index); index--; @@ -345,7 +345,7 @@ export class Deque extends IterableElementBase extends IterableElementBase extends IterableElementBase extends IterableElementBase([], { bucketSize: this._bucketSize }); if (pos < 0) pos = 0; - for (let i = pos; i < this.size; i++) { + for (let i = pos; i < this._size; i++) { newDeque.push(this.at(i)); } @@ -482,11 +482,11 @@ export class Deque extends IterableElementBase extends IterableElementBase extends IterableElementBase extends IterableElementBase number): this { const arr: E[] = []; - for (let i = 0; i < this.size; ++i) { + for (let i = 0; i < this._size; ++i) { arr.push(this.at(i)); } arr.sort(comparator); - for (let i = 0; i < this.size; ++i) { + for (let i = 0; i < this._size; ++i) { this.setAt(i, arr[i]); } return this; @@ -601,10 +601,10 @@ export class Deque extends IterableElementBase extends IterableElementBase extends IterableElementBase { - for (let i = 0; i < this.size; ++i) { + for (let i = 0; i < this._size; ++i) { yield this.at(i); } } diff --git a/src/data-structures/queue/queue.ts b/src/data-structures/queue/queue.ts index ab4adbd..ecdf06e 100644 --- a/src/data-structures/queue/queue.ts +++ b/src/data-structures/queue/queue.ts @@ -1,6 +1,6 @@ /** * @license MIT - * @copyright Tyler Zeng + * @copyright Pablo Zeng * @class */ import type { ElementCallback, QueueOptions } from '../../types'; diff --git a/src/data-structures/stack/stack.ts b/src/data-structures/stack/stack.ts index 2ecbfb0..344bd4a 100644 --- a/src/data-structures/stack/stack.ts +++ b/src/data-structures/stack/stack.ts @@ -1,8 +1,8 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import type { ElementCallback, StackOptions } from '../../types'; diff --git a/src/data-structures/trie/trie.ts b/src/data-structures/trie/trie.ts index bbb8e9a..ca4b4f2 100644 --- a/src/data-structures/trie/trie.ts +++ b/src/data-structures/trie/trie.ts @@ -1,8 +1,8 @@ /** * data-structure-typed * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng + * @author Pablo Zeng + * @copyright Copyright (c) 2022 Pablo Zeng * @license MIT License */ import type { ElementCallback, TrieOptions } from '../../types'; @@ -202,7 +202,7 @@ export class Trie extends IterableElementBase> { * @return True if the size of the queue is 0 */ isEmpty(): boolean { - return this.size === 0; + return this._size === 0; } /** diff --git a/src/index.ts b/src/index.ts index 187d579..a98e67c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,3 +2,4 @@ export * from './data-structures'; export * from './utils'; export * from './interfaces'; export * from './types'; +export * from './constants'; diff --git a/src/interfaces/binary-tree.ts b/src/interfaces/binary-tree.ts index c78a48d..8371922 100644 --- a/src/interfaces/binary-tree.ts +++ b/src/interfaces/binary-tree.ts @@ -5,7 +5,8 @@ import type { BinaryTreeNodeNested, BinaryTreeOptions, BTNCallback, - BTNKeyOrNodeOrEntry + BTNKeyOrNodeOrEntry, + BTNPredicate } from '../types'; export interface IBinaryTree< @@ -23,5 +24,5 @@ export interface IBinaryTree< addMany(nodes: Iterable>, values?: Iterable): boolean[]; - delete>(identifier: ReturnType | null, callback: C): BinaryTreeDeleteResult[]; + delete(predicate: R | BTNKeyOrNodeOrEntry | BTNPredicate): BinaryTreeDeleteResult[]; } diff --git a/src/types/data-structures/binary-tree/binary-tree.ts b/src/types/data-structures/binary-tree/binary-tree.ts index b61b2ae..4e2ae7f 100644 --- a/src/types/data-structures/binary-tree/binary-tree.ts +++ b/src/types/data-structures/binary-tree/binary-tree.ts @@ -1,5 +1,6 @@ import { BinaryTree, BinaryTreeNode } from '../../../data-structures'; import { IterationType, OptValue } from '../../common'; +import {DFSOperation} from "bst-typed"; export type BinaryTreeNodeNested = BinaryTreeNode>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -30,9 +31,6 @@ export type BinaryTreeDeleteResult = { deleted: OptBTNOrNull; needBa export type BTNCallback = (node: NODE) => D; -export enum DFSOperation { - VISIT = 0, - PROCESS = 1, -} +export type BTNPredicate = (node: NODE) => boolean; -export type DFSStackItem = { opt: DFSOperation; node: OptBTNOrNull } \ No newline at end of file +export type DFSStackItem = { opt: DFSOperation; node: OptBTNOrNull } diff --git a/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts b/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts index 07e7027..a51f3ff 100644 --- a/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +++ b/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts @@ -75,13 +75,13 @@ describe('AVLTreeMultiMap operations test1', () => { const nodeId10 = treeMultimap.getNode(10); expect(nodeId10?.key).toBe(10); - const nodeVal9 = treeMultimap.getNode(9, node => node.value); + const nodeVal9 = treeMultimap.getNode(node => node.value === 9); expect(nodeVal9?.key).toBe(9); - const nodesByCount1 = treeMultimap.getNodes(1, node => node.count); + const nodesByCount1 = treeMultimap.getNodes(node => node.count === 1); expect(nodesByCount1.length).toBe(14); - const nodesByCount2 = treeMultimap.getNodes(2, node => node.count); + const nodesByCount2 = treeMultimap.getNodes(node => node.count === 2); expect(nodesByCount2.length).toBe(2); const leftMost = treeMultimap.getLeftMost(); expect(leftMost).toBe(1); @@ -123,7 +123,7 @@ describe('AVLTreeMultiMap operations test1', () => { expect(bfsNodesAfterBalanced[0].key).toBe(8); expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16); - const removed11 = treeMultimap.delete(11, undefined, true); + const removed11 = treeMultimap.delete(11, true); expect(removed11 instanceof Array); expect(removed11[0]); expect(removed11[0].deleted); @@ -134,7 +134,7 @@ describe('AVLTreeMultiMap operations test1', () => { expect(treeMultimap.getHeight(15)).toBe(1); - const removed1 = treeMultimap.delete(1, undefined, true); + const removed1 = treeMultimap.delete(1, true); expect(removed1 instanceof Array); expect(removed1[0]); expect(removed1[0].deleted); @@ -144,7 +144,7 @@ describe('AVLTreeMultiMap operations test1', () => { expect(treeMultimap.getHeight()).toBe(4); - const removed4 = treeMultimap.delete(4, undefined, true); + const removed4 = treeMultimap.delete(4, true); expect(removed4 instanceof Array); expect(removed4[0]); expect(removed4[0].deleted); @@ -153,7 +153,7 @@ describe('AVLTreeMultiMap operations test1', () => { expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(4); - const removed10 = treeMultimap.delete(10, undefined, true); + const removed10 = treeMultimap.delete(10, true); expect(removed10 instanceof Array); expect(removed10[0]); expect(removed10[0].deleted); @@ -162,7 +162,7 @@ describe('AVLTreeMultiMap operations test1', () => { expect(treeMultimap.getHeight()).toBe(3); - const removed15 = treeMultimap.delete(15, undefined, true); + const removed15 = treeMultimap.delete(15, true); expect(removed15 instanceof Array); expect(removed15[0]); expect(removed15[0].deleted); @@ -171,7 +171,7 @@ describe('AVLTreeMultiMap operations test1', () => { expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(3); - const removed5 = treeMultimap.delete(5, undefined, true); + const removed5 = treeMultimap.delete(5, true); expect(removed5 instanceof Array); expect(removed5[0]); expect(removed5[0].deleted); @@ -180,7 +180,7 @@ describe('AVLTreeMultiMap operations test1', () => { expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(3); - const removed13 = treeMultimap.delete(13, undefined, true); + const removed13 = treeMultimap.delete(13, true); expect(removed13 instanceof Array); expect(removed13[0]); expect(removed13[0].deleted); @@ -188,7 +188,7 @@ describe('AVLTreeMultiMap operations test1', () => { expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(3); - const removed3 = treeMultimap.delete(3, undefined, true); + const removed3 = treeMultimap.delete(3, true); expect(removed3 instanceof Array); expect(removed3[0]); expect(removed3[0].deleted); @@ -196,7 +196,7 @@ describe('AVLTreeMultiMap operations test1', () => { expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(3); - const removed8 = treeMultimap.delete(8, undefined, true); + const removed8 = treeMultimap.delete(8, true); expect(removed8 instanceof Array); expect(removed8[0]); expect(removed8[0].deleted); @@ -204,17 +204,17 @@ describe('AVLTreeMultiMap operations test1', () => { expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(3); - const removed6 = treeMultimap.delete(6, undefined, true); + const removed6 = treeMultimap.delete(6, true); expect(removed6 instanceof Array); expect(removed6[0]); expect(removed6[0].deleted); if (removed6[0].deleted) expect(removed6[0].deleted.key).toBe(6); - expect(treeMultimap.delete(6, undefined, true).length).toBe(0); + expect(treeMultimap.delete(6, true).length).toBe(0); expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(2); - const removed7 = treeMultimap.delete(7, undefined, true); + const removed7 = treeMultimap.delete(7, true); expect(removed7 instanceof Array); expect(removed7[0]); expect(removed7[0].deleted); @@ -222,7 +222,7 @@ describe('AVLTreeMultiMap operations test1', () => { expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(2); - const removed9 = treeMultimap.delete(9, undefined, true); + const removed9 = treeMultimap.delete(9, true); expect(removed9 instanceof Array); expect(removed9[0]); expect(removed9[0].deleted); @@ -230,7 +230,7 @@ describe('AVLTreeMultiMap operations test1', () => { expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(2); - const removed14 = treeMultimap.delete(14, undefined, true); + const removed14 = treeMultimap.delete(14, true); expect(removed14 instanceof Array); expect(removed14[0]); expect(removed14[0].deleted); @@ -331,13 +331,13 @@ describe('AVLTreeMultiMap operations test recursively1', () => { const nodeId10 = treeMultimap.getNode(10); expect(nodeId10?.key).toBe(10); - const nodeVal9 = treeMultimap.getNode(9, node => node.value); + const nodeVal9 = treeMultimap.getNode(node => node.value === 9); expect(nodeVal9?.key).toBe(9); - const nodesByCount1 = treeMultimap.getNodes(1, node => node.count); + const nodesByCount1 = treeMultimap.getNodes(node => node.count === 1); expect(nodesByCount1.length).toBe(14); - const nodesByCount2 = treeMultimap.getNodes(2, node => node.count); + const nodesByCount2 = treeMultimap.getNodes(node => node.count === 2); expect(nodesByCount2.length).toBe(2); const leftMost = treeMultimap.getLeftMost(); expect(leftMost).toBe(1); @@ -379,7 +379,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => { expect(bfsNodesAfterBalanced[0].key).toBe(8); expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16); - const removed11 = treeMultimap.delete(11, undefined, true); + const removed11 = treeMultimap.delete(11, true); expect(removed11 instanceof Array); expect(removed11[0]); expect(removed11[0].deleted); @@ -390,7 +390,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => { expect(treeMultimap.getHeight(15)).toBe(1); - const removed1 = treeMultimap.delete(1, undefined, true); + const removed1 = treeMultimap.delete(1, true); expect(removed1 instanceof Array); expect(removed1[0]); expect(removed1[0].deleted); @@ -400,7 +400,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => { expect(treeMultimap.getHeight()).toBe(4); - const removed4 = treeMultimap.delete(4, undefined, true); + const removed4 = treeMultimap.delete(4, true); expect(removed4 instanceof Array); expect(removed4[0]); expect(removed4[0].deleted); @@ -409,7 +409,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => { expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(4); - const removed10 = treeMultimap.delete(10, undefined, true); + const removed10 = treeMultimap.delete(10, true); expect(removed10 instanceof Array); expect(removed10[0]); expect(removed10[0].deleted); @@ -418,7 +418,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => { expect(treeMultimap.getHeight()).toBe(3); - const removed15 = treeMultimap.delete(15, undefined, true); + const removed15 = treeMultimap.delete(15, true); expect(removed15 instanceof Array); expect(removed15[0]); expect(removed15[0].deleted); @@ -427,7 +427,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => { expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(3); - const removed5 = treeMultimap.delete(5, undefined, true); + const removed5 = treeMultimap.delete(5, true); expect(removed5 instanceof Array); expect(removed5[0]); expect(removed5[0].deleted); @@ -436,7 +436,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => { expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(3); - const removed13 = treeMultimap.delete(13, undefined, true); + const removed13 = treeMultimap.delete(13, true); expect(removed13 instanceof Array); expect(removed13[0]); expect(removed13[0].deleted); @@ -444,7 +444,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => { expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(3); - const removed3 = treeMultimap.delete(3, undefined, true); + const removed3 = treeMultimap.delete(3, true); expect(removed3 instanceof Array); expect(removed3[0]); expect(removed3[0].deleted); @@ -452,7 +452,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => { expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(3); - const removed8 = treeMultimap.delete(8, undefined, true); + const removed8 = treeMultimap.delete(8, true); expect(removed8 instanceof Array); expect(removed8[0]); expect(removed8[0].deleted); @@ -460,17 +460,17 @@ describe('AVLTreeMultiMap operations test recursively1', () => { expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(3); - const removed6 = treeMultimap.delete(6, undefined, true); + const removed6 = treeMultimap.delete(6, true); expect(removed6 instanceof Array); expect(removed6[0]); expect(removed6[0].deleted); if (removed6[0].deleted) expect(removed6[0].deleted.key).toBe(6); - expect(treeMultimap.delete(6, undefined, true).length).toBe(0); + expect(treeMultimap.delete(6, true).length).toBe(0); expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(2); - const removed7 = treeMultimap.delete(7, undefined, true); + const removed7 = treeMultimap.delete(7, true); expect(removed7 instanceof Array); expect(removed7[0]); expect(removed7[0].deleted); @@ -478,7 +478,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => { expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(2); - const removed9 = treeMultimap.delete(9, undefined, true); + const removed9 = treeMultimap.delete(9, true); expect(removed9 instanceof Array); expect(removed9[0]); expect(removed9[0].deleted); @@ -486,7 +486,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => { expect(treeMultimap.isAVLBalanced()).toBe(true); expect(treeMultimap.getHeight()).toBe(2); - const removed14 = treeMultimap.delete(14, undefined, true); + const removed14 = treeMultimap.delete(14, true); expect(removed14 instanceof Array); expect(removed14[0]); expect(removed14[0].deleted); diff --git a/test/unit/data-structures/binary-tree/binary-tree.test.ts b/test/unit/data-structures/binary-tree/binary-tree.test.ts index 674d106..4a76625 100644 --- a/test/unit/data-structures/binary-tree/binary-tree.test.ts +++ b/test/unit/data-structures/binary-tree/binary-tree.test.ts @@ -169,8 +169,8 @@ describe('BinaryTree', () => { expect(tree.has(4)).toBe(false); const node4 = tree.getNode(4); expect(tree.has(node4)).toBe(false); - expect(tree.has(node4, node => node)).toBe(false); - expect(tree.has('3', node => node.value?.toString())).toBe(true); + expect(tree.has(node => node === node4)).toBe(false); + expect(tree.has(node => node.value?.toString() === '3')).toBe(true); }); it('should the clone method work fine', () => { @@ -323,9 +323,9 @@ describe('BinaryTree', () => { expect(tree.isBST(tree.getNode(4), 'RECURSIVE')).toBe(true); expect(tree.isBST(tree.getNode(4), 'ITERATIVE')).toBe(true); - expect(tree.getNodes(2, undefined, false, null)).toEqual([]); + expect(tree.getNodes(2, false, null)).toEqual([]); expect(tree.getNodes(undefined)).toEqual([]); - expect(tree.getNodes(tree.getNodeByKey(2), undefined, false, tree.root)).toEqual([tree.getNodeByKey(2)]); + expect(tree.getNodes(tree.getNodeByKey(2), false, tree.root)).toEqual([tree.getNodeByKey(2)]); }); describe('should isKey', () => { @@ -1130,17 +1130,17 @@ describe('BinaryTree', () => { tree.add([2, 'B']); tree.add([null, 'null']); - const nodes = tree.getNodes('B', node => node.value); + const nodes = tree.getNodes(node => node.value === 'B'); expect(nodes.length).toBe(1); expect(nodes[0].key).toBe(2); - const nodesRec = tree.getNodes('B', node => node.value, false, tree.root, 'RECURSIVE'); + const nodesRec = tree.getNodes(node => node.value === 'B', false, tree.root, 'RECURSIVE'); expect(nodesRec.length).toBe(1); expect(nodesRec[0].key).toBe(2); - const nodesItr = tree.getNodes('B', node => node.value, false, tree.root, 'ITERATIVE'); + const nodesItr = tree.getNodes(node => node.value === 'B', false, tree.root, 'ITERATIVE'); expect(nodesItr.length).toBe(1); expect(nodesItr[0].key).toBe(2); diff --git a/test/unit/data-structures/binary-tree/bst.test.ts b/test/unit/data-structures/binary-tree/bst.test.ts index 142f7aa..4c42d09 100644 --- a/test/unit/data-structures/binary-tree/bst.test.ts +++ b/test/unit/data-structures/binary-tree/bst.test.ts @@ -69,7 +69,7 @@ describe('BST operations test', () => { const nodeId10 = bst.getNode(10); expect(nodeId10?.key).toBe(10); - const nodeVal9 = bst.getNode(9, node => node.value); + const nodeVal9 = bst.getNode(node => node.value === 9); expect(nodeVal9?.key).toBe(9); const leftMost = bst.getLeftMost(); @@ -81,7 +81,7 @@ describe('BST operations test', () => { const minNodeBySpecificNode = node15 && bst.getLeftMost(node => node, node15); expect(minNodeBySpecificNode?.key).toBe(12); - const nodes = bst.getNodes(15, node => node.value); + const nodes = bst.getNodes(node => node.value === 15); expect(nodes.map(node => node.key)).toEqual([15]); let subTreeSum = 0; @@ -490,7 +490,7 @@ describe('BST operations test recursively', () => { expect(bst.get(10)).toBe(undefined); expect(nodeId10?.key).toBe(10); - const nodeVal9 = bst.getNode(9, node => node.value); + const nodeVal9 = bst.getNode(node => node.value === 9); expect(nodeVal9?.key).toBe(undefined); const leftMost = bst.getLeftMost(); diff --git a/test/unit/data-structures/binary-tree/tree-multi-map.test.ts b/test/unit/data-structures/binary-tree/tree-multi-map.test.ts index 2cedfd1..a4a2f7a 100644 --- a/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +++ b/test/unit/data-structures/binary-tree/tree-multi-map.test.ts @@ -87,7 +87,7 @@ describe('TreeMultiMap operations test1', () => { tmm.delete(11); expect(tmm.count).toBe(17); expect(tmm.getComputedCount()).toBe(17); - tmm.delete(3, undefined, true); + tmm.delete(3, true); expect(tmm.count).toBe(15); expect(tmm.getComputedCount()).toBe(15); }); @@ -133,13 +133,13 @@ describe('TreeMultiMap operations test1', () => { const nodeId10 = tmm.getNode(10); expect(nodeId10?.key).toBe(10); - const nodeVal9 = tmm.getNode(9, node => node.value); + const nodeVal9 = tmm.getNode(node => node.value === 9); expect(nodeVal9?.key).toBe(9); - const nodesByCount1 = tmm.getNodes(1, node => node.count); + const nodesByCount1 = tmm.getNodes(node => node.count === 1); expect(nodesByCount1.length).toBe(14); - const nodesByCount2 = tmm.getNodes(2, node => node.count); + const nodesByCount2 = tmm.getNodes(node => node.count === 2); expect(nodesByCount2.length).toBe(2); const leftMost = tmm.getLeftMost(); expect(leftMost).toBe(1); @@ -180,7 +180,7 @@ describe('TreeMultiMap operations test1', () => { expect(bfsNodesAfterBalanced[0].key).toBe(6); expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16); - const removed11 = tmm.delete(11, undefined, true); + const removed11 = tmm.delete(11, true); expect(removed11 instanceof Array); expect(removed11[0]); expect(removed11[0].deleted); @@ -191,7 +191,7 @@ describe('TreeMultiMap operations test1', () => { expect(tmm.getHeight(15)).toBe(1); - const removed1 = tmm.delete(1, undefined, true); + const removed1 = tmm.delete(1, true); expect(removed1 instanceof Array); expect(removed1[0]); expect(removed1[0].deleted); @@ -201,7 +201,7 @@ describe('TreeMultiMap operations test1', () => { expect(tmm.getHeight()).toBe(5); - const removed4 = tmm.delete(4, undefined, true); + const removed4 = tmm.delete(4, true); expect(removed4 instanceof Array); expect(removed4[0]); expect(removed4[0].deleted); @@ -210,7 +210,7 @@ describe('TreeMultiMap operations test1', () => { expect(tmm.isAVLBalanced()).toBe(false); expect(tmm.getHeight()).toBe(5); - const removed10 = tmm.delete(10, undefined, true); + const removed10 = tmm.delete(10, true); expect(removed10 instanceof Array); expect(removed10[0]); expect(removed10[0].deleted); @@ -219,7 +219,7 @@ describe('TreeMultiMap operations test1', () => { expect(tmm.getHeight()).toBe(4); - const removed15 = tmm.delete(15, undefined, true); + const removed15 = tmm.delete(15, true); expect(removed15 instanceof Array); expect(removed15[0]); expect(removed15[0].deleted); @@ -228,7 +228,7 @@ describe('TreeMultiMap operations test1', () => { expect(tmm.isAVLBalanced()).toBe(false); expect(tmm.getHeight()).toBe(3); - const removed5 = tmm.delete(5, undefined, true); + const removed5 = tmm.delete(5, true); expect(removed5 instanceof Array); expect(removed5[0]); expect(removed5[0].deleted); @@ -237,7 +237,7 @@ describe('TreeMultiMap operations test1', () => { expect(tmm.isAVLBalanced()).toBe(true); expect(tmm.getHeight()).toBe(3); - const removed13 = tmm.delete(13, undefined, true); + const removed13 = tmm.delete(13, true); expect(removed13 instanceof Array); expect(removed13[0]); expect(removed13[0].deleted); @@ -245,7 +245,7 @@ describe('TreeMultiMap operations test1', () => { expect(tmm.isAVLBalanced()).toBe(true); expect(tmm.getHeight()).toBe(3); - const removed3 = tmm.delete(3, undefined, true); + const removed3 = tmm.delete(3, true); expect(removed3 instanceof Array); expect(removed3[0]); expect(removed3[0].deleted); @@ -253,7 +253,7 @@ describe('TreeMultiMap operations test1', () => { expect(tmm.isAVLBalanced()).toBe(false); expect(tmm.getHeight()).toBe(3); - const removed8 = tmm.delete(8, undefined, true); + const removed8 = tmm.delete(8, true); expect(removed8 instanceof Array); expect(removed8[0]); expect(removed8[0].deleted); @@ -261,17 +261,17 @@ describe('TreeMultiMap operations test1', () => { expect(tmm.isAVLBalanced()).toBe(false); expect(tmm.getHeight()).toBe(3); - const removed6 = tmm.delete(6, undefined, true); + const removed6 = tmm.delete(6, true); expect(removed6 instanceof Array); expect(removed6[0]); expect(removed6[0].deleted); if (removed6[0].deleted) expect(removed6[0].deleted.key).toBe(6); - expect(tmm.delete(6, undefined, true).length).toBe(0); + expect(tmm.delete(6, true).length).toBe(0); expect(tmm.isAVLBalanced()).toBe(false); expect(tmm.getHeight()).toBe(3); - const removed7 = tmm.delete(7, undefined, true); + const removed7 = tmm.delete(7, true); expect(removed7 instanceof Array); expect(removed7[0]); expect(removed7[0].deleted); @@ -279,7 +279,7 @@ describe('TreeMultiMap operations test1', () => { expect(tmm.isAVLBalanced()).toBe(false); expect(tmm.getHeight()).toBe(3); - const removed9 = tmm.delete(9, undefined, true); + const removed9 = tmm.delete(9, true); expect(removed9 instanceof Array); expect(removed9[0]); expect(removed9[0].deleted); @@ -287,7 +287,7 @@ describe('TreeMultiMap operations test1', () => { expect(tmm.isAVLBalanced()).toBe(true); expect(tmm.getHeight()).toBe(2); - const removed14 = tmm.delete(14, undefined, true); + const removed14 = tmm.delete(14, true); expect(removed14 instanceof Array); expect(removed14[0]); expect(removed14[0].deleted); @@ -391,13 +391,13 @@ describe('TreeMultiMap operations test recursively1', () => { const nodeId10 = tmm.getNode(10); expect(nodeId10?.key).toBe(10); - const nodeVal9 = tmm.getNode(9, node => node.value); + const nodeVal9 = tmm.getNode(node => node.value === 9); expect(nodeVal9?.key).toBe(9); - const nodesByCount1 = tmm.getNodes(1, node => node.count); + const nodesByCount1 = tmm.getNodes(node => node.count === 1); expect(nodesByCount1.length).toBe(14); - const nodesByCount2 = tmm.getNodes(2, node => node.count); + const nodesByCount2 = tmm.getNodes(node => node.count === 2); expect(nodesByCount2.length).toBe(2); const leftMost = tmm.getLeftMost(); expect(leftMost).toBe(1); @@ -447,7 +447,7 @@ describe('TreeMultiMap operations test recursively1', () => { expect(bfsNodesAfterBalanced[0].key).toBe(6); expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16); - const removed11 = tmm.delete(11, undefined, true); + const removed11 = tmm.delete(11, true); expect(removed11 instanceof Array); expect(removed11[0]); expect(removed11[0].deleted); @@ -458,7 +458,7 @@ describe('TreeMultiMap operations test recursively1', () => { expect(tmm.getHeight(15)).toBe(1); - const removed1 = tmm.delete(1, undefined, true); + const removed1 = tmm.delete(1, true); expect(removed1 instanceof Array); expect(removed1[0]); expect(removed1[0].deleted); @@ -468,7 +468,7 @@ describe('TreeMultiMap operations test recursively1', () => { expect(tmm.getHeight()).toBe(5); - const removed4 = tmm.delete(4, undefined, true); + const removed4 = tmm.delete(4, true); expect(removed4 instanceof Array); expect(removed4[0]); expect(removed4[0].deleted); @@ -477,7 +477,7 @@ describe('TreeMultiMap operations test recursively1', () => { expect(tmm.isAVLBalanced()).toBe(false); expect(tmm.getHeight()).toBe(5); - const removed10 = tmm.delete(10, undefined, true); + const removed10 = tmm.delete(10, true); expect(removed10 instanceof Array); expect(removed10[0]); expect(removed10[0].deleted); @@ -486,7 +486,7 @@ describe('TreeMultiMap operations test recursively1', () => { expect(tmm.getHeight()).toBe(4); - const removed15 = tmm.delete(15, undefined, true); + const removed15 = tmm.delete(15, true); expect(removed15 instanceof Array); expect(removed15[0]); expect(removed15[0].deleted); @@ -495,7 +495,7 @@ describe('TreeMultiMap operations test recursively1', () => { expect(tmm.isAVLBalanced()).toBe(false); expect(tmm.getHeight()).toBe(3); - const removed5 = tmm.delete(5, undefined, true); + const removed5 = tmm.delete(5, true); expect(removed5 instanceof Array); expect(removed5[0]); expect(removed5[0].deleted); @@ -504,7 +504,7 @@ describe('TreeMultiMap operations test recursively1', () => { expect(tmm.isAVLBalanced()).toBe(true); expect(tmm.getHeight()).toBe(3); - const removed13 = tmm.delete(13, undefined, true); + const removed13 = tmm.delete(13, true); expect(removed13 instanceof Array); expect(removed13[0]); expect(removed13[0].deleted); @@ -512,7 +512,7 @@ describe('TreeMultiMap operations test recursively1', () => { expect(tmm.isAVLBalanced()).toBe(true); expect(tmm.getHeight()).toBe(3); - const removed3 = tmm.delete(3, undefined, true); + const removed3 = tmm.delete(3, true); expect(removed3 instanceof Array); expect(removed3[0]); expect(removed3[0].deleted); @@ -520,7 +520,7 @@ describe('TreeMultiMap operations test recursively1', () => { expect(tmm.isAVLBalanced()).toBe(false); expect(tmm.getHeight()).toBe(3); - const removed8 = tmm.delete(8, undefined, true); + const removed8 = tmm.delete(8, true); expect(removed8 instanceof Array); expect(removed8[0]); expect(removed8[0].deleted); @@ -528,17 +528,17 @@ describe('TreeMultiMap operations test recursively1', () => { expect(tmm.isAVLBalanced()).toBe(false); expect(tmm.getHeight()).toBe(3); - const removed6 = tmm.delete(6, undefined, true); + const removed6 = tmm.delete(6, true); expect(removed6 instanceof Array); expect(removed6[0]); expect(removed6[0].deleted); if (removed6[0].deleted) expect(removed6[0].deleted.key).toBe(6); - expect(tmm.delete(6, undefined, true).length).toBe(0); + expect(tmm.delete(6, true).length).toBe(0); expect(tmm.isAVLBalanced()).toBe(false); expect(tmm.getHeight()).toBe(3); - const removed7 = tmm.delete(7, undefined, true); + const removed7 = tmm.delete(7, true); expect(removed7 instanceof Array); expect(removed7[0]); expect(removed7[0].deleted); @@ -546,7 +546,7 @@ describe('TreeMultiMap operations test recursively1', () => { expect(tmm.isAVLBalanced()).toBe(false); expect(tmm.getHeight()).toBe(3); - const removed9 = tmm.delete(9, undefined, true); + const removed9 = tmm.delete(9, true); expect(removed9 instanceof Array); expect(removed9[0]); expect(removed9[0].deleted); @@ -554,7 +554,7 @@ describe('TreeMultiMap operations test recursively1', () => { expect(tmm.isAVLBalanced()).toBe(true); expect(tmm.getHeight()).toBe(2); - const removed14 = tmm.delete(14, undefined, true); + const removed14 = tmm.delete(14, true); expect(removed14 instanceof Array); expect(removed14[0]); expect(removed14[0].deleted); @@ -664,7 +664,7 @@ describe('TreeMultiMap delete test', function () { } for (let i = 0; i < inputSize; i++) { - tmm.delete(i, undefined, true); + tmm.delete(i, true); } let nilCount = 0; diff --git a/test/unit/data-structures/graph/undirected-graph.test.ts b/test/unit/data-structures/graph/undirected-graph.test.ts index 57a5062..4ce28cc 100644 --- a/test/unit/data-structures/graph/undirected-graph.test.ts +++ b/test/unit/data-structures/graph/undirected-graph.test.ts @@ -44,6 +44,8 @@ describe('UndirectedGraph Operation Test', () => { expect(graph.hasEdge('A', 'B')).toBe(true); expect(graph.hasEdge('B', 'A')).toBe(true); + expect(graph.has('A')).toBe(true); + expect(graph.get('A')).toBe(undefined); }); it('should delete edges', () => {