data-structure-typed 1.51.0 → 1.51.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +13 -13
  3. package/benchmark/report.html +37 -1
  4. package/benchmark/report.json +378 -12
  5. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js +1 -1
  6. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
  7. package/dist/cjs/data-structures/binary-tree/avl-tree.d.ts +1 -1
  8. package/dist/cjs/data-structures/binary-tree/avl-tree.js +2 -2
  9. package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
  10. package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +1 -1
  11. package/dist/cjs/data-structures/binary-tree/binary-tree.js +73 -73
  12. package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
  13. package/dist/cjs/data-structures/binary-tree/bst.js +39 -39
  14. package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
  15. package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +1 -1
  16. package/dist/cjs/data-structures/binary-tree/rb-tree.js +3 -3
  17. package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
  18. package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
  19. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +2 -2
  20. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
  21. package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.js +1 -1
  22. package/dist/mjs/data-structures/binary-tree/avl-tree.d.ts +1 -1
  23. package/dist/mjs/data-structures/binary-tree/avl-tree.js +2 -2
  24. package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +1 -1
  25. package/dist/mjs/data-structures/binary-tree/binary-tree.js +73 -73
  26. package/dist/mjs/data-structures/binary-tree/bst.js +39 -39
  27. package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +1 -1
  28. package/dist/mjs/data-structures/binary-tree/rb-tree.js +3 -3
  29. package/dist/mjs/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
  30. package/dist/mjs/data-structures/binary-tree/tree-multi-map.js +2 -2
  31. package/dist/umd/data-structure-typed.js +119 -119
  32. package/dist/umd/data-structure-typed.min.js +2 -2
  33. package/dist/umd/data-structure-typed.min.js.map +1 -1
  34. package/package.json +6 -6
  35. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +1 -1
  36. package/src/data-structures/binary-tree/avl-tree.ts +2 -2
  37. package/src/data-structures/binary-tree/binary-tree.ts +71 -71
  38. package/src/data-structures/binary-tree/bst.ts +33 -33
  39. package/src/data-structures/binary-tree/rb-tree.ts +3 -3
  40. package/src/data-structures/binary-tree/tree-multi-map.ts +2 -2
  41. package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +1 -0
  42. package/test/utils/big-o.ts +12 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "data-structure-typed",
3
- "version": "1.51.0",
3
+ "version": "1.51.1",
4
4
  "description": "Javascript Data Structure. Heap, Binary Tree, Red Black Tree, Linked List, Deque, Trie, HashMap, Directed Graph, Undirected Graph, Binary Search Tree(BST), AVL Tree, Priority Queue, Graph, Queue, Tree Multiset, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue, Stack. Benchmark compared with C++ STL. API aligned with ES6 and Java.util. Usability is comparable to Python",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/mjs/index.js",
@@ -66,11 +66,11 @@
66
66
  "@typescript-eslint/eslint-plugin": "^6.7.4",
67
67
  "@typescript-eslint/parser": "^6.7.4",
68
68
  "auto-changelog": "^2.4.0",
69
- "avl-tree-typed": "^1.50.9",
69
+ "avl-tree-typed": "^1.51.0",
70
70
  "benchmark": "^2.1.4",
71
- "binary-tree-typed": "^1.50.9",
72
- "bst-typed": "^1.50.9",
73
- "data-structure-typed": "^1.50.9",
71
+ "binary-tree-typed": "^1.51.0",
72
+ "bst-typed": "^1.51.0",
73
+ "data-structure-typed": "^1.51.0",
74
74
  "dependency-cruiser": "^14.1.0",
75
75
  "doctoc": "^2.2.1",
76
76
  "eslint": "^8.50.0",
@@ -79,7 +79,7 @@
79
79
  "eslint-import-resolver-typescript": "^3.6.1",
80
80
  "eslint-plugin-import": "^2.28.1",
81
81
  "fast-glob": "^3.3.1",
82
- "heap-typed": "^1.50.9",
82
+ "heap-typed": "^1.51.0",
83
83
  "istanbul-badges-readme": "^1.8.5",
84
84
  "jest": "^29.7.0",
85
85
  "js-sdsl": "^4.4.2",
@@ -240,7 +240,7 @@ export class AVLTreeMultiMap<
240
240
  */
241
241
  override delete<C extends BTNCallback<NODE>>(
242
242
  identifier: ReturnType<C>,
243
- callback: C = this._defaultOneParamCallback as C,
243
+ callback: C = this._DEFAULT_CALLBACK as C,
244
244
  ignoreCount = false
245
245
  ): BinaryTreeDeleteResult<NODE>[] {
246
246
  const deletedResult: BinaryTreeDeleteResult<NODE>[] = [];
@@ -164,13 +164,13 @@ export class AVLTree<
164
164
  * `callback` function.
165
165
  * @param {C} callback - The `callback` parameter is a function that will be called for each node
166
166
  * that is deleted from the binary tree. It is an optional parameter and if not provided, it will
167
- * default to the `_defaultOneParamCallback` function. The `callback` function should have a single
167
+ * default to the `_DEFAULT_CALLBACK` function. The `callback` function should have a single
168
168
  * parameter of type `NODE
169
169
  * @returns The method is returning an array of `BinaryTreeDeleteResult<NODE>`.
170
170
  */
171
171
  override delete<C extends BTNCallback<NODE>>(
172
172
  identifier: ReturnType<C>,
173
- callback: C = this._defaultOneParamCallback as C
173
+ callback: C = this._DEFAULT_CALLBACK as C
174
174
  ): BinaryTreeDeleteResult<NODE>[] {
175
175
  if ((identifier as any) instanceof AVLTreeNode) callback = (node => node) as C;
176
176
  const deletedResults = super.delete(identifier, callback);
@@ -268,17 +268,17 @@ export class BinaryTree<
268
268
  keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>,
269
269
  iterationType: IterationType = 'ITERATIVE'
270
270
  ): NODE | null | undefined {
271
- let res: NODE | null | undefined;
272
271
  if (this.isRealNode(keyOrNodeOrEntry)) {
273
- res = keyOrNodeOrEntry;
272
+ return keyOrNodeOrEntry;
274
273
  } else if (this.isEntry(keyOrNodeOrEntry)) {
275
- if (keyOrNodeOrEntry[0] === null) res = null;
276
- else if (keyOrNodeOrEntry[0] !== undefined) res = this.getNodeByKey(keyOrNodeOrEntry[0], iterationType);
274
+ if (keyOrNodeOrEntry[0] === null) return null;
275
+ if (keyOrNodeOrEntry[0] === undefined) return;
276
+ return this.getNodeByKey(keyOrNodeOrEntry[0], iterationType);
277
277
  } else {
278
- if (keyOrNodeOrEntry === null) res = null;
279
- else if (keyOrNodeOrEntry !== undefined) res = this.getNodeByKey(keyOrNodeOrEntry, iterationType);
278
+ if (keyOrNodeOrEntry === null) return null;
279
+ if (keyOrNodeOrEntry === undefined) return;
280
+ return this.getNodeByKey(keyOrNodeOrEntry, iterationType);
280
281
  }
281
- return res;
282
282
  }
283
283
 
284
284
  /**
@@ -486,16 +486,16 @@ export class BinaryTree<
486
486
  * specific node based on its value or object.
487
487
  * @param {C} callback - The `callback` parameter is a function that is used to determine the
488
488
  * identifier of the node to be deleted. It is optional and has a default value of
489
- * `this._defaultOneParamCallback`. The `callback` function should return the identifier of the node.
489
+ * `this._DEFAULT_CALLBACK`. The `callback` function should return the identifier of the node.
490
490
  * @returns an array of `BinaryTreeDeleteResult<NODE>`.
491
491
  */
492
492
  delete<C extends BTNCallback<NODE>>(
493
493
  identifier: ReturnType<C> | null | undefined,
494
- callback: C = this._defaultOneParamCallback as C
494
+ callback: C = this._DEFAULT_CALLBACK as C
495
495
  ): BinaryTreeDeleteResult<NODE>[] {
496
496
  const deletedResult: BinaryTreeDeleteResult<NODE>[] = [];
497
497
  if (!this.root) return deletedResult;
498
- if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
498
+ if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
499
499
  callback = (node => node) as C;
500
500
 
501
501
  const curr = this.getNode(identifier, callback);
@@ -579,7 +579,7 @@ export class BinaryTree<
579
579
  * specific value.
580
580
  * @param {C} callback - The `callback` parameter is a function that takes a node of type `NODE` as
581
581
  * input and returns a value of type `C`. It is used to determine if a node matches the given
582
- * identifier. If no callback is provided, the `_defaultOneParamCallback` function is used as the
582
+ * identifier. If no callback is provided, the `_DEFAULT_CALLBACK` function is used as the
583
583
  * default
584
584
  * @param [onlyOne=false] - A boolean value indicating whether to only return the first node that
585
585
  * matches the identifier. If set to true, the function will stop iterating once it finds a matching
@@ -594,12 +594,12 @@ export class BinaryTree<
594
594
  */
595
595
  getNodes<C extends BTNCallback<NODE>>(
596
596
  identifier: ReturnType<C> | null | undefined,
597
- callback: C = this._defaultOneParamCallback as C,
597
+ callback: C = this._DEFAULT_CALLBACK as C,
598
598
  onlyOne = false,
599
599
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
600
600
  iterationType: IterationType = this.iterationType
601
601
  ): NODE[] {
602
- if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
602
+ if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
603
603
  callback = (node => node) as C;
604
604
  beginRoot = this.ensureNode(beginRoot);
605
605
  if (!beginRoot) return [];
@@ -607,28 +607,28 @@ export class BinaryTree<
607
607
  const ans: NODE[] = [];
608
608
 
609
609
  if (iterationType === 'RECURSIVE') {
610
- const _traverse = (cur: NODE) => {
610
+ const dfs = (cur: NODE) => {
611
611
  if (callback(cur) === identifier) {
612
612
  ans.push(cur);
613
613
  if (onlyOne) return;
614
614
  }
615
615
  if (!cur.left && !cur.right) return;
616
- cur.left && _traverse(cur.left);
617
- cur.right && _traverse(cur.right);
616
+ cur.left && dfs(cur.left);
617
+ cur.right && dfs(cur.right);
618
618
  };
619
619
 
620
- _traverse(beginRoot);
620
+ dfs(beginRoot);
621
621
  } else {
622
- const queue = new Queue<NODE>([beginRoot]);
623
- while (queue.size > 0) {
624
- const cur = queue.shift();
622
+ const stack = [beginRoot];
623
+ while (stack.length > 0) {
624
+ const cur = stack.pop();
625
625
  if (cur) {
626
626
  if (callback(cur) === identifier) {
627
627
  ans.push(cur);
628
628
  if (onlyOne) return ans;
629
629
  }
630
- cur.left && queue.push(cur.left);
631
- cur.right && queue.push(cur.right);
630
+ cur.left && stack.push(cur.left);
631
+ cur.right && stack.push(cur.right);
632
632
  }
633
633
  }
634
634
  }
@@ -685,11 +685,11 @@ export class BinaryTree<
685
685
  */
686
686
  getNode<C extends BTNCallback<NODE>>(
687
687
  identifier: ReturnType<C> | null | undefined,
688
- callback: C = this._defaultOneParamCallback as C,
688
+ callback: C = this._DEFAULT_CALLBACK as C,
689
689
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
690
690
  iterationType: IterationType = this.iterationType
691
691
  ): NODE | null | undefined {
692
- if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
692
+ if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
693
693
  callback = (node => node) as C;
694
694
 
695
695
  return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;
@@ -717,23 +717,23 @@ export class BinaryTree<
717
717
  getNodeByKey(key: K, iterationType: IterationType = 'ITERATIVE'): NODE | undefined {
718
718
  if (!this.root) return undefined;
719
719
  if (iterationType === 'RECURSIVE') {
720
- const _dfs = (cur: NODE): NODE | undefined => {
720
+ const dfs = (cur: NODE): NODE | undefined => {
721
721
  if (cur.key === key) return cur;
722
722
 
723
723
  if (!cur.left && !cur.right) return;
724
- if (cur.left) return _dfs(cur.left);
725
- if (cur.right) return _dfs(cur.right);
724
+ if (cur.left) return dfs(cur.left);
725
+ if (cur.right) return dfs(cur.right);
726
726
  };
727
727
 
728
- return _dfs(this.root);
728
+ return dfs(this.root);
729
729
  } else {
730
- const queue = new Queue<NODE>([this.root]);
731
- while (queue.size > 0) {
732
- const cur = queue.shift();
730
+ const stack = [this.root];
731
+ while (stack.length > 0) {
732
+ const cur = stack.pop();
733
733
  if (cur) {
734
734
  if (cur.key === key) return cur;
735
- cur.left && queue.push(cur.left);
736
- cur.right && queue.push(cur.right);
735
+ cur.left && stack.push(cur.left);
736
+ cur.right && stack.push(cur.right);
737
737
  }
738
738
  }
739
739
  }
@@ -789,11 +789,11 @@ export class BinaryTree<
789
789
  */
790
790
  override get<C extends BTNCallback<NODE>>(
791
791
  identifier: ReturnType<C> | null | undefined,
792
- callback: C = this._defaultOneParamCallback as C,
792
+ callback: C = this._DEFAULT_CALLBACK as C,
793
793
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
794
794
  iterationType: IterationType = this.iterationType
795
795
  ): V | undefined {
796
- if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
796
+ if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
797
797
  callback = (node => node) as C;
798
798
 
799
799
  return this.getNode(identifier, callback, beginRoot, iterationType)?.value ?? undefined;
@@ -848,11 +848,11 @@ export class BinaryTree<
848
848
  */
849
849
  override has<C extends BTNCallback<NODE>>(
850
850
  identifier: ReturnType<C> | null | undefined,
851
- callback: C = this._defaultOneParamCallback as C,
851
+ callback: C = this._DEFAULT_CALLBACK as C,
852
852
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
853
853
  iterationType: IterationType = this.iterationType
854
854
  ): boolean {
855
- if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
855
+ if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
856
856
  callback = (node => node) as C;
857
857
 
858
858
  return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
@@ -1184,20 +1184,20 @@ export class BinaryTree<
1184
1184
  if (!this.isRealNode(beginRoot)) return beginRoot;
1185
1185
 
1186
1186
  if (iterationType === 'RECURSIVE') {
1187
- const _traverse = (cur: NODE): NODE => {
1187
+ const dfs = (cur: NODE): NODE => {
1188
1188
  if (!this.isRealNode(cur.left)) return cur;
1189
- return _traverse(cur.left);
1189
+ return dfs(cur.left);
1190
1190
  };
1191
1191
 
1192
- return _traverse(beginRoot);
1192
+ return dfs(beginRoot);
1193
1193
  } else {
1194
1194
  // Indirect implementation of iteration using tail recursion optimization
1195
- const _traverse = trampoline((cur: NODE) => {
1195
+ const dfs = trampoline((cur: NODE) => {
1196
1196
  if (!this.isRealNode(cur.left)) return cur;
1197
- return _traverse.cont(cur.left);
1197
+ return dfs.cont(cur.left);
1198
1198
  });
1199
1199
 
1200
- return _traverse(beginRoot);
1200
+ return dfs(beginRoot);
1201
1201
  }
1202
1202
  }
1203
1203
 
@@ -1231,20 +1231,20 @@ export class BinaryTree<
1231
1231
  if (!beginRoot) return beginRoot;
1232
1232
 
1233
1233
  if (iterationType === 'RECURSIVE') {
1234
- const _traverse = (cur: NODE): NODE => {
1234
+ const dfs = (cur: NODE): NODE => {
1235
1235
  if (!this.isRealNode(cur.right)) return cur;
1236
- return _traverse(cur.right);
1236
+ return dfs(cur.right);
1237
1237
  };
1238
1238
 
1239
- return _traverse(beginRoot);
1239
+ return dfs(beginRoot);
1240
1240
  } else {
1241
1241
  // Indirect implementation of iteration using tail recursion optimization
1242
- const _traverse = trampoline((cur: NODE) => {
1242
+ const dfs = trampoline((cur: NODE) => {
1243
1243
  if (!this.isRealNode(cur.right)) return cur;
1244
- return _traverse.cont(cur.right);
1244
+ return dfs.cont(cur.right);
1245
1245
  });
1246
1246
 
1247
- return _traverse(beginRoot);
1247
+ return dfs(beginRoot);
1248
1248
  }
1249
1249
  }
1250
1250
 
@@ -1351,7 +1351,7 @@ export class BinaryTree<
1351
1351
  * @returns an array of values that are the return values of the callback function.
1352
1352
  */
1353
1353
  dfs<C extends BTNCallback<NODE | null | undefined>>(
1354
- callback: C = this._defaultOneParamCallback as C,
1354
+ callback: C = this._DEFAULT_CALLBACK as C,
1355
1355
  pattern: DFSOrderPattern = 'IN',
1356
1356
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
1357
1357
  iterationType: IterationType = 'ITERATIVE',
@@ -1361,38 +1361,38 @@ export class BinaryTree<
1361
1361
  if (!beginRoot) return [];
1362
1362
  const ans: ReturnType<C>[] = [];
1363
1363
  if (iterationType === 'RECURSIVE') {
1364
- const _traverse = (node: NODE | null | undefined) => {
1364
+ const dfs = (node: NODE | null | undefined) => {
1365
1365
  switch (pattern) {
1366
1366
  case 'IN':
1367
1367
  if (includeNull) {
1368
- if (this.isRealNode(node) && this.isNodeOrNull(node.left)) _traverse(node.left);
1368
+ if (this.isRealNode(node) && this.isNodeOrNull(node.left)) dfs(node.left);
1369
1369
  this.isNodeOrNull(node) && ans.push(callback(node));
1370
- if (this.isRealNode(node) && this.isNodeOrNull(node.right)) _traverse(node.right);
1370
+ if (this.isRealNode(node) && this.isNodeOrNull(node.right)) dfs(node.right);
1371
1371
  } else {
1372
- if (this.isRealNode(node) && this.isRealNode(node.left)) _traverse(node.left);
1372
+ if (this.isRealNode(node) && this.isRealNode(node.left)) dfs(node.left);
1373
1373
  this.isRealNode(node) && ans.push(callback(node));
1374
- if (this.isRealNode(node) && this.isRealNode(node.right)) _traverse(node.right);
1374
+ if (this.isRealNode(node) && this.isRealNode(node.right)) dfs(node.right);
1375
1375
  }
1376
1376
  break;
1377
1377
  case 'PRE':
1378
1378
  if (includeNull) {
1379
1379
  this.isNodeOrNull(node) && ans.push(callback(node));
1380
- if (this.isRealNode(node) && this.isNodeOrNull(node.left)) _traverse(node.left);
1381
- if (this.isRealNode(node) && this.isNodeOrNull(node.right)) _traverse(node.right);
1380
+ if (this.isRealNode(node) && this.isNodeOrNull(node.left)) dfs(node.left);
1381
+ if (this.isRealNode(node) && this.isNodeOrNull(node.right)) dfs(node.right);
1382
1382
  } else {
1383
1383
  this.isRealNode(node) && ans.push(callback(node));
1384
- if (this.isRealNode(node) && this.isRealNode(node.left)) _traverse(node.left);
1385
- if (this.isRealNode(node) && this.isRealNode(node.right)) _traverse(node.right);
1384
+ if (this.isRealNode(node) && this.isRealNode(node.left)) dfs(node.left);
1385
+ if (this.isRealNode(node) && this.isRealNode(node.right)) dfs(node.right);
1386
1386
  }
1387
1387
  break;
1388
1388
  case 'POST':
1389
1389
  if (includeNull) {
1390
- if (this.isRealNode(node) && this.isNodeOrNull(node.left)) _traverse(node.left);
1391
- if (this.isRealNode(node) && this.isNodeOrNull(node.right)) _traverse(node.right);
1390
+ if (this.isRealNode(node) && this.isNodeOrNull(node.left)) dfs(node.left);
1391
+ if (this.isRealNode(node) && this.isNodeOrNull(node.right)) dfs(node.right);
1392
1392
  this.isNodeOrNull(node) && ans.push(callback(node));
1393
1393
  } else {
1394
- if (this.isRealNode(node) && this.isRealNode(node.left)) _traverse(node.left);
1395
- if (this.isRealNode(node) && this.isRealNode(node.right)) _traverse(node.right);
1394
+ if (this.isRealNode(node) && this.isRealNode(node.left)) dfs(node.left);
1395
+ if (this.isRealNode(node) && this.isRealNode(node.right)) dfs(node.right);
1396
1396
  this.isRealNode(node) && ans.push(callback(node));
1397
1397
  }
1398
1398
 
@@ -1400,7 +1400,7 @@ export class BinaryTree<
1400
1400
  }
1401
1401
  };
1402
1402
 
1403
- _traverse(beginRoot);
1403
+ dfs(beginRoot);
1404
1404
  } else {
1405
1405
  // 0: visit, 1: print
1406
1406
  const stack: { opt: 0 | 1; node: NODE | null | undefined }[] = [{ opt: 0, node: beginRoot }];
@@ -1486,7 +1486,7 @@ export class BinaryTree<
1486
1486
  * the breadth-first traversal of a binary tree.
1487
1487
  */
1488
1488
  bfs<C extends BTNCallback<NODE | null>>(
1489
- callback: C = this._defaultOneParamCallback as C,
1489
+ callback: C = this._DEFAULT_CALLBACK as C,
1490
1490
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
1491
1491
  iterationType: IterationType = this.iterationType,
1492
1492
  includeNull = false
@@ -1499,7 +1499,7 @@ export class BinaryTree<
1499
1499
  if (iterationType === 'RECURSIVE') {
1500
1500
  const queue: Queue<NODE | null | undefined> = new Queue<NODE | null | undefined>([beginRoot]);
1501
1501
 
1502
- const traverse = (level: number) => {
1502
+ const dfs = (level: number) => {
1503
1503
  if (queue.size === 0) return;
1504
1504
 
1505
1505
  const current = queue.shift()!;
@@ -1513,10 +1513,10 @@ export class BinaryTree<
1513
1513
  if (this.isRealNode(current.right)) queue.push(current.right);
1514
1514
  }
1515
1515
 
1516
- traverse(level + 1);
1516
+ dfs(level + 1);
1517
1517
  };
1518
1518
 
1519
- traverse(0);
1519
+ dfs(0);
1520
1520
  } else {
1521
1521
  const queue = new Queue<NODE | null | undefined>([beginRoot]);
1522
1522
  while (queue.size > 0) {
@@ -1580,7 +1580,7 @@ export class BinaryTree<
1580
1580
  * @returns The function `listLevels` returns a two-dimensional array of type `ReturnType<C>[][]`.
1581
1581
  */
1582
1582
  listLevels<C extends BTNCallback<NODE | null>>(
1583
- callback: C = this._defaultOneParamCallback as C,
1583
+ callback: C = this._DEFAULT_CALLBACK as C,
1584
1584
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
1585
1585
  iterationType: IterationType = this.iterationType,
1586
1586
  includeNull = false
@@ -1651,7 +1651,7 @@ export class BinaryTree<
1651
1651
  * by the return type of the `callback` function.
1652
1652
  */
1653
1653
  morris<C extends BTNCallback<NODE>>(
1654
- callback: C = this._defaultOneParamCallback as C,
1654
+ callback: C = this._DEFAULT_CALLBACK as C,
1655
1655
  pattern: DFSOrderPattern = 'IN',
1656
1656
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root
1657
1657
  ): ReturnType<C>[] {
@@ -1995,7 +1995,7 @@ export class BinaryTree<
1995
1995
  }
1996
1996
  }
1997
1997
 
1998
- protected _defaultOneParamCallback = (node: NODE | null | undefined) => (node ? node.key : undefined);
1998
+ protected _DEFAULT_CALLBACK = (node: NODE | null | undefined) => (node ? node.key : undefined);
1999
1999
 
2000
2000
  /**
2001
2001
  * Swap the data of two nodes in the binary tree.
@@ -214,15 +214,15 @@ export class BST<
214
214
  keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>,
215
215
  iterationType: IterationType = 'ITERATIVE'
216
216
  ): NODE | undefined {
217
- let res: NODE | undefined;
218
217
  if (this.isRealNode(keyOrNodeOrEntry)) {
219
- res = keyOrNodeOrEntry;
218
+ return keyOrNodeOrEntry;
220
219
  } else if (this.isEntry(keyOrNodeOrEntry)) {
221
- if (keyOrNodeOrEntry[0]) res = this.getNodeByKey(keyOrNodeOrEntry[0], iterationType);
220
+ if (keyOrNodeOrEntry[0] === null || keyOrNodeOrEntry[0] === undefined) return;
221
+ return this.getNodeByKey(keyOrNodeOrEntry[0], iterationType);
222
222
  } else {
223
- if (keyOrNodeOrEntry) res = this.getNodeByKey(keyOrNodeOrEntry, iterationType);
223
+ if (keyOrNodeOrEntry === null || keyOrNodeOrEntry === undefined) return;
224
+ return this.getNodeByKey(keyOrNodeOrEntry, iterationType);
224
225
  }
225
- return res;
226
226
  }
227
227
 
228
228
  /**
@@ -426,26 +426,26 @@ export class BST<
426
426
  * found in the binary tree. If no node is found, it returns `undefined`.
427
427
  */
428
428
  override getNodeByKey(key: K, iterationType: IterationType = 'ITERATIVE'): NODE | undefined {
429
- // return this.getNodes(key, this._defaultOneParamCallback, true, this.root, iterationType)[0];
430
- if (!this.isRealNode(this.root)) return undefined;
429
+ // return this.getNodes(key, this._DEFAULT_CALLBACK, true, this.root, iterationType)[0];
430
+ if (!this.isRealNode(this.root)) return;
431
431
  if (iterationType === 'RECURSIVE') {
432
- const _dfs = (cur: NODE): NODE | undefined => {
432
+ const dfs = (cur: NODE): NODE | undefined => {
433
433
  if (cur.key === key) return cur;
434
434
  if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
435
435
 
436
- if (this._compare(cur.key, key) === 'GT' && this.isRealNode(cur.left)) return _dfs(cur.left);
437
- if (this._compare(cur.key, key) === 'LT' && this.isRealNode(cur.right)) return _dfs(cur.right);
436
+ if (this.isRealNode(cur.left) && this._compare(cur.key, key) === 'GT') return dfs(cur.left);
437
+ if (this.isRealNode(cur.right) && this._compare(cur.key, key) === 'LT') return dfs(cur.right);
438
438
  };
439
439
 
440
- return _dfs(this.root);
440
+ return dfs(this.root);
441
441
  } else {
442
- const queue = new Queue<NODE>([this.root]);
443
- while (queue.size > 0) {
444
- const cur = queue.shift();
442
+ const stack = [this.root];
443
+ while (stack.length > 0) {
444
+ const cur = stack.pop();
445
445
  if (this.isRealNode(cur)) {
446
446
  if (this._compare(cur.key, key) === 'EQ') return cur;
447
- if (this._compare(cur.key, key) === 'GT') this.isRealNode(cur.left) && queue.push(cur.left);
448
- if (this._compare(cur.key, key) === 'LT') this.isRealNode(cur.right) && queue.push(cur.right);
447
+ if (this.isRealNode(cur.left) && this._compare(cur.key, key) === 'GT') stack.push(cur.left);
448
+ if (this.isRealNode(cur.right) && this._compare(cur.key, key) === 'LT') stack.push(cur.right);
449
449
  }
450
450
  }
451
451
  }
@@ -481,7 +481,7 @@ export class BST<
481
481
  */
482
482
  override getNodes<C extends BTNCallback<NODE>>(
483
483
  identifier: ReturnType<C> | undefined,
484
- callback: C = this._defaultOneParamCallback as C,
484
+ callback: C = this._DEFAULT_CALLBACK as C,
485
485
  onlyOne = false,
486
486
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
487
487
  iterationType: IterationType = this.iterationType
@@ -491,7 +491,7 @@ export class BST<
491
491
  const ans: NODE[] = [];
492
492
 
493
493
  if (iterationType === 'RECURSIVE') {
494
- const _traverse = (cur: NODE) => {
494
+ const dfs = (cur: NODE) => {
495
495
  const callbackResult = callback(cur);
496
496
  if (callbackResult === identifier) {
497
497
  ans.push(cur);
@@ -500,16 +500,16 @@ export class BST<
500
500
 
501
501
  if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
502
502
  // TODO potential bug
503
- if (callback === this._defaultOneParamCallback) {
504
- if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') _traverse(cur.left);
505
- if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') _traverse(cur.right);
503
+ if (callback === this._DEFAULT_CALLBACK) {
504
+ if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') dfs(cur.left);
505
+ if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') dfs(cur.right);
506
506
  } else {
507
- this.isRealNode(cur.left) && _traverse(cur.left);
508
- this.isRealNode(cur.right) && _traverse(cur.right);
507
+ this.isRealNode(cur.left) && dfs(cur.left);
508
+ this.isRealNode(cur.right) && dfs(cur.right);
509
509
  }
510
510
  };
511
511
 
512
- _traverse(beginRoot);
512
+ dfs(beginRoot);
513
513
  } else {
514
514
  const stack = [beginRoot];
515
515
  while (stack.length > 0) {
@@ -521,7 +521,7 @@ export class BST<
521
521
  if (onlyOne) return ans;
522
522
  }
523
523
  // TODO potential bug
524
- if (callback === this._defaultOneParamCallback) {
524
+ if (callback === this._DEFAULT_CALLBACK) {
525
525
  if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') stack.push(cur.right);
526
526
  if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') stack.push(cur.left);
527
527
 
@@ -568,7 +568,7 @@ export class BST<
568
568
  * @returns The method is returning an array of the return type of the callback function.
569
569
  */
570
570
  override dfs<C extends BTNCallback<NODE>>(
571
- callback: C = this._defaultOneParamCallback as C,
571
+ callback: C = this._DEFAULT_CALLBACK as C,
572
572
  pattern: DFSOrderPattern = 'IN',
573
573
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
574
574
  iterationType: IterationType = 'ITERATIVE'
@@ -599,7 +599,7 @@ export class BST<
599
599
  * @returns The method is returning an array of the return type of the callback function.
600
600
  */
601
601
  override bfs<C extends BTNCallback<NODE>>(
602
- callback: C = this._defaultOneParamCallback as C,
602
+ callback: C = this._DEFAULT_CALLBACK as C,
603
603
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
604
604
  iterationType: IterationType = this.iterationType
605
605
  ): ReturnType<C>[] {
@@ -630,7 +630,7 @@ export class BST<
630
630
  * function.
631
631
  */
632
632
  override listLevels<C extends BTNCallback<NODE>>(
633
- callback: C = this._defaultOneParamCallback as C,
633
+ callback: C = this._DEFAULT_CALLBACK as C,
634
634
  beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
635
635
  iterationType: IterationType = this.iterationType
636
636
  ): ReturnType<C>[][] {
@@ -700,7 +700,7 @@ export class BST<
700
700
  * `ReturnType<C>`, which is the return type of the callback function passed as an argument.
701
701
  */
702
702
  lesserOrGreaterTraverse<C extends BTNCallback<NODE>>(
703
- callback: C = this._defaultOneParamCallback as C,
703
+ callback: C = this._DEFAULT_CALLBACK as C,
704
704
  lesserOrGreater: CP = 'LT',
705
705
  targetNode: KeyOrNodeOrEntry<K, V, NODE> = this.root,
706
706
  iterationType: IterationType = this.iterationType
@@ -713,15 +713,15 @@ export class BST<
713
713
  const targetKey = targetNode.key;
714
714
 
715
715
  if (iterationType === 'RECURSIVE') {
716
- const _traverse = (cur: NODE) => {
716
+ const dfs = (cur: NODE) => {
717
717
  const compared = this._compare(cur.key, targetKey);
718
718
  if (compared === lesserOrGreater) ans.push(callback(cur));
719
719
 
720
- if (this.isRealNode(cur.left)) _traverse(cur.left);
721
- if (this.isRealNode(cur.right)) _traverse(cur.right);
720
+ if (this.isRealNode(cur.left)) dfs(cur.left);
721
+ if (this.isRealNode(cur.right)) dfs(cur.right);
722
722
  };
723
723
 
724
- _traverse(this.root);
724
+ dfs(this.root);
725
725
  return ans;
726
726
  } else {
727
727
  const queue = new Queue<NODE>([this.root]);
@@ -231,7 +231,7 @@ export class RedBlackTree<
231
231
  */
232
232
  override getNode<C extends BTNCallback<NODE>>(
233
233
  identifier: ReturnType<C> | undefined,
234
- callback: C = this._defaultOneParamCallback as C,
234
+ callback: C = this._DEFAULT_CALLBACK as C,
235
235
  beginRoot: BSTNKeyOrNode<K, NODE> = this.root,
236
236
  iterationType: IterationType = this.iterationType
237
237
  ): NODE | null | undefined {
@@ -308,13 +308,13 @@ export class RedBlackTree<
308
308
  * deleted is not found.
309
309
  * @param {C} callback - The `callback` parameter is a function that is used to retrieve a node from
310
310
  * the binary tree based on its identifier. It is an optional parameter and if not provided, the
311
- * `_defaultOneParamCallback` function is used as the default callback. The callback function should
311
+ * `_DEFAULT_CALLBACK` function is used as the default callback. The callback function should
312
312
  * return the identifier of the node to
313
313
  * @returns an array of BinaryTreeDeleteResult<NODE> objects.
314
314
  */
315
315
  override delete<C extends BTNCallback<NODE>>(
316
316
  identifier: ReturnType<C> | null | undefined,
317
- callback: C = this._defaultOneParamCallback as C
317
+ callback: C = this._DEFAULT_CALLBACK as C
318
318
  ): BinaryTreeDeleteResult<NODE>[] {
319
319
  if (identifier === null) return [];
320
320
  const results: BinaryTreeDeleteResult<NODE>[] = [];
@@ -242,7 +242,7 @@ export class TreeMultiMap<
242
242
  * function. It can also be null or undefined if no node needs to be deleted.
243
243
  * @param {C} callback - The `callback` parameter is a function that takes a node of type `NODE` as
244
244
  * input and returns a value of type `ReturnType<C>`. It is used to determine if a node matches the
245
- * identifier for deletion. If no callback is provided, the `_defaultOneParamCallback` function is
245
+ * identifier for deletion. If no callback is provided, the `_DEFAULT_CALLBACK` function is
246
246
  * used
247
247
  * @param [ignoreCount=false] - A boolean value indicating whether to ignore the count of the target
248
248
  * node when performing deletion. If set to true, the count of the target node will not be considered
@@ -252,7 +252,7 @@ export class TreeMultiMap<
252
252
  */
253
253
  override delete<C extends BTNCallback<NODE>>(
254
254
  identifier: ReturnType<C> | null | undefined,
255
- callback: C = this._defaultOneParamCallback as C,
255
+ callback: C = this._DEFAULT_CALLBACK as C,
256
256
  ignoreCount = false
257
257
  ): BinaryTreeDeleteResult<NODE>[] {
258
258
  if (identifier === null) return [];
@@ -45,6 +45,7 @@ describe('TreeMultiMap operations test1', () => {
45
45
  expect(tmm.getMinHeight()).toBe(-1);
46
46
 
47
47
  tmm.addMany([1, 6, 7, 2, 3, 4, 9, 11, 8, 5, 10, 12, 16, 14, 13, 15]);
48
+ // tmm.print()
48
49
  expect(tmm.getHeight()).toBe(5);
49
50
  expect(tmm.getMinHeight()).toBe(2);
50
51
  });
@@ -205,3 +205,15 @@ export function logBigOMetrics(target: any, propertyKey: string, descriptor: Pro
205
205
 
206
206
  return descriptor;
207
207
  }
208
+
209
+ export const logPerf = function (fn: (...args: any[]) => any, args: any[], thisArg?: any) {
210
+ const start = performance.now();
211
+ if (thisArg) {
212
+ if (args && args.length > 0) fn.apply(thisArg, args);
213
+ else fn.apply(thisArg);
214
+ } else {
215
+ if (args && args.length > 0) fn(...args);
216
+ else fn();
217
+ }
218
+ console.log(`function running cost : ${(performance.now() - start).toFixed(2)} ms`);
219
+ };