data-structure-typed 1.36.7 → 1.36.9

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 (84) hide show
  1. package/.eslintrc.js +1 -1
  2. package/CHANGELOG.md +3 -1
  3. package/README.md +8 -0
  4. package/dist/data-structures/binary-tree/avl-tree.d.ts +5 -5
  5. package/dist/data-structures/binary-tree/avl-tree.js +6 -6
  6. package/dist/data-structures/binary-tree/avl-tree.js.map +1 -1
  7. package/dist/data-structures/binary-tree/binary-tree.d.ts +18 -85
  8. package/dist/data-structures/binary-tree/binary-tree.js +76 -128
  9. package/dist/data-structures/binary-tree/binary-tree.js.map +1 -1
  10. package/dist/data-structures/binary-tree/tree-multiset.d.ts +9 -16
  11. package/dist/data-structures/binary-tree/tree-multiset.js +10 -20
  12. package/dist/data-structures/binary-tree/tree-multiset.js.map +1 -1
  13. package/dist/data-structures/hash/hash-map.d.ts +1 -1
  14. package/dist/data-structures/hash/hash-map.js +1 -1
  15. package/dist/data-structures/hash/hash-table.d.ts +3 -3
  16. package/dist/data-structures/hash/hash-table.js +3 -3
  17. package/dist/data-structures/heap/heap.d.ts +136 -11
  18. package/dist/data-structures/heap/heap.js +293 -13
  19. package/dist/data-structures/heap/heap.js.map +1 -1
  20. package/dist/data-structures/linked-list/skip-linked-list.d.ts +3 -3
  21. package/dist/data-structures/linked-list/skip-linked-list.js +3 -3
  22. package/dist/data-structures/queue/deque.d.ts +2 -2
  23. package/dist/data-structures/queue/deque.js +2 -2
  24. package/dist/data-structures/queue/queue.js +1 -1
  25. package/dist/data-structures/trie/trie.d.ts +2 -2
  26. package/dist/data-structures/trie/trie.js +2 -2
  27. package/dist/interfaces/binary-tree.d.ts +1 -1
  28. package/lib/data-structures/binary-tree/avl-tree.d.ts +5 -5
  29. package/lib/data-structures/binary-tree/avl-tree.js +6 -6
  30. package/lib/data-structures/binary-tree/binary-tree.d.ts +18 -85
  31. package/lib/data-structures/binary-tree/binary-tree.js +76 -128
  32. package/lib/data-structures/binary-tree/tree-multiset.d.ts +9 -16
  33. package/lib/data-structures/binary-tree/tree-multiset.js +10 -20
  34. package/lib/data-structures/hash/hash-map.d.ts +1 -1
  35. package/lib/data-structures/hash/hash-map.js +1 -1
  36. package/lib/data-structures/hash/hash-table.d.ts +3 -3
  37. package/lib/data-structures/hash/hash-table.js +3 -3
  38. package/lib/data-structures/heap/heap.d.ts +136 -11
  39. package/lib/data-structures/heap/heap.js +290 -12
  40. package/lib/data-structures/linked-list/skip-linked-list.d.ts +3 -3
  41. package/lib/data-structures/linked-list/skip-linked-list.js +3 -3
  42. package/lib/data-structures/queue/deque.d.ts +2 -2
  43. package/lib/data-structures/queue/deque.js +2 -2
  44. package/lib/data-structures/queue/queue.js +1 -1
  45. package/lib/data-structures/trie/trie.d.ts +2 -2
  46. package/lib/data-structures/trie/trie.js +2 -2
  47. package/lib/interfaces/binary-tree.d.ts +1 -1
  48. package/package.json +7 -6
  49. package/src/data-structures/binary-tree/avl-tree.ts +6 -6
  50. package/src/data-structures/binary-tree/binary-tree.ts +79 -214
  51. package/src/data-structures/binary-tree/rb-tree.ts +3 -3
  52. package/src/data-structures/binary-tree/tree-multiset.ts +10 -21
  53. package/src/data-structures/hash/hash-map.ts +1 -1
  54. package/src/data-structures/hash/hash-table.ts +3 -3
  55. package/src/data-structures/heap/heap.ts +340 -16
  56. package/src/data-structures/linked-list/skip-linked-list.ts +3 -3
  57. package/src/data-structures/queue/deque.ts +2 -2
  58. package/src/data-structures/queue/queue.ts +1 -1
  59. package/src/data-structures/trie/trie.ts +2 -2
  60. package/src/interfaces/binary-tree.ts +1 -1
  61. package/test/types/index.ts +1 -0
  62. package/test/types/utils/big-o.ts +1 -0
  63. package/test/types/utils/index.ts +1 -0
  64. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +14 -14
  65. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +2 -2
  66. package/test/unit/data-structures/binary-tree/bst.test.ts +28 -28
  67. package/test/unit/data-structures/binary-tree/overall.test.ts +3 -3
  68. package/test/unit/data-structures/binary-tree/rb-tree.test.ts +1 -1
  69. package/test/unit/data-structures/binary-tree/tree-multiset.test.ts +28 -28
  70. package/test/unit/data-structures/graph/directed-graph.test.ts +1 -1
  71. package/test/unit/data-structures/graph/undirected-graph.test.ts +1 -1
  72. package/test/unit/data-structures/hash/hash-map.test.ts +2 -2
  73. package/test/unit/data-structures/hash/hash-table.test.ts +5 -5
  74. package/test/unit/data-structures/heap/heap.test.ts +192 -1
  75. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +7 -7
  76. package/test/unit/data-structures/linked-list/skip-list.test.ts +2 -2
  77. package/test/unit/data-structures/priority-queue/max-priority-queue.test.ts +1 -1
  78. package/test/unit/data-structures/queue/deque.test.ts +3 -3
  79. package/test/unit/data-structures/trie/trie.test.ts +5 -5
  80. package/test/utils/big-o.ts +199 -0
  81. package/test/utils/index.ts +1 -1
  82. package/umd/bundle.min.js +1 -1
  83. package/umd/bundle.min.js.map +1 -1
  84. package/test/utils/magnitude.ts +0 -21
@@ -96,10 +96,10 @@ export class Trie {
96
96
  }
97
97
  /**
98
98
  * Remove a word from the Trie structure.
99
- * @param{string} word - The word to remove.
99
+ * @param{string} word - The word to delete.
100
100
  * @returns {boolean} True if the word was successfully removed.
101
101
  */
102
- remove(word) {
102
+ delete(word) {
103
103
  word = this._caseProcess(word);
104
104
  let isDeleted = false;
105
105
  const dfs = (cur, i) => {
@@ -3,5 +3,5 @@ import { BinaryTreeDeletedResult, BinaryTreeNodeKey } from '../types';
3
3
  export interface IBinaryTree<N extends BinaryTreeNode<N['val'], N>> {
4
4
  createNode(key: BinaryTreeNodeKey, val?: N['val']): N;
5
5
  add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val']): N | null | undefined;
6
- remove(nodeOrKey: N | BinaryTreeNodeKey): BinaryTreeDeletedResult<N>[];
6
+ delete(nodeOrKey: N | BinaryTreeNodeKey): BinaryTreeDeletedResult<N>[];
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "data-structure-typed",
3
- "version": "1.36.7",
3
+ "version": "1.36.9",
4
4
  "description": "Data Structures of Javascript & TypeScript. Binary Tree, BST, Graph, Heap, Priority Queue, Linked List, Queue, Deque, Stack, AVL Tree, Tree Multiset, Trie, Directed Graph, Undirected Graph, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue.",
5
5
  "main": "dist/index.js",
6
6
  "module": "lib/index.js",
@@ -33,7 +33,8 @@
33
33
  "check:deps": "dependency-cruiser src",
34
34
  "changelog": "auto-changelog",
35
35
  "coverage:badge": "istanbul-badges-readme",
36
- "ci": "env && npm run lint && npm run build && npm run update:individuals && npm run test && git fetch --tags && npm run changelog"
36
+ "ci": "env && npm run lint && npm run build && npm run update:individuals && npm run test && git fetch --tags && npm run changelog",
37
+ "publish:all": "npm run ci && npm publish && sh scripts/publish_all_subs.sh && sh scripts/publish_docs.sh"
37
38
  },
38
39
  "repository": {
39
40
  "type": "git",
@@ -55,17 +56,17 @@
55
56
  "@typescript-eslint/eslint-plugin": "^6.7.4",
56
57
  "@typescript-eslint/parser": "^6.7.4",
57
58
  "auto-changelog": "^2.4.0",
58
- "avl-tree-typed": "^1.36.6",
59
+ "avl-tree-typed": "^1.36.8",
59
60
  "benchmark": "^2.1.4",
60
- "binary-tree-typed": "^1.36.6",
61
- "bst-typed": "^1.36.6",
61
+ "binary-tree-typed": "^1.36.8",
62
+ "bst-typed": "^1.36.8",
62
63
  "dependency-cruiser": "^14.1.0",
63
64
  "eslint": "^8.50.0",
64
65
  "eslint-config-prettier": "^9.0.0",
65
66
  "eslint-import-resolver-alias": "^1.1.2",
66
67
  "eslint-import-resolver-typescript": "^3.6.1",
67
68
  "eslint-plugin-import": "^2.28.1",
68
- "heap-typed": "^1.36.6",
69
+ "heap-typed": "^1.36.8",
69
70
  "istanbul-badges-readme": "^1.8.5",
70
71
  "jest": "^29.7.0",
71
72
  "prettier": "^3.0.3",
@@ -33,13 +33,13 @@ export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode> extends B
33
33
  }
34
34
 
35
35
  /**
36
- * The `swapLocation` function swaps the location of two nodes in a binary tree.
37
- * @param {N} srcNode - The source node that you want to swap with the destination node.
36
+ * The `_swap` function swaps the location of two nodes in a binary tree.
37
+ * @param {N} srcNode - The source node that you want to _swap with the destination node.
38
38
  * @param {N} destNode - The `destNode` parameter represents the destination node where the values from `srcNode` will
39
39
  * be swapped to.
40
40
  * @returns The `destNode` is being returned.
41
41
  */
42
- override swapLocation(srcNode: N, destNode: N): N {
42
+ protected override _swap(srcNode: N, destNode: N): N {
43
43
  const {key, val, height} = destNode;
44
44
  const tempNode = this.createNode(key, val);
45
45
 
@@ -85,14 +85,14 @@ export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode> extends B
85
85
  }
86
86
 
87
87
  /**
88
- * The function overrides the remove method of a binary tree and performs additional operations to balance the tree after
88
+ * The function overrides the delete method of a binary tree and performs additional operations to balance the tree after
89
89
  * deletion.
90
90
  * @param {BinaryTreeNodeKey} key - The `key` parameter represents the identifier of the binary tree node that needs to be
91
91
  * removed.
92
92
  * @returns The method is returning an array of `BinaryTreeDeletedResult<N>` objects.
93
93
  */
94
- override remove(key: BinaryTreeNodeKey): BinaryTreeDeletedResult<N>[] {
95
- const deletedResults = super.remove(key);
94
+ override delete(key: BinaryTreeNodeKey): BinaryTreeDeletedResult<N>[] {
95
+ const deletedResults = super.delete(key);
96
96
  for (const {needBalanced} of deletedResults) {
97
97
  if (needBalanced) {
98
98
  this._balancePath(needBalanced);
@@ -145,6 +145,10 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
145
145
  return this._loopType;
146
146
  }
147
147
 
148
+ set loopType(v: LoopType) {
149
+ this._loopType = v;
150
+ }
151
+
148
152
  visitedKey: BinaryTreeNodeKey[] = [];
149
153
 
150
154
  visitedVal: N['val'][] = [];
@@ -152,13 +156,13 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
152
156
  visitedNode: N[] = [];
153
157
 
154
158
  /**
155
- * The `swapLocation` function swaps the location of two nodes in a binary tree.
156
- * @param {N} srcNode - The source node that you want to swap with the destination node.
159
+ * The `_swap` function swaps the location of two nodes in a binary tree.
160
+ * @param {N} srcNode - The source node that you want to _swap with the destination node.
157
161
  * @param {N} destNode - The `destNode` parameter represents the destination node where the values from `srcNode` will
158
162
  * be swapped to.
159
163
  * @returns The `destNode` is being returned.
160
164
  */
161
- swapLocation(srcNode: N, destNode: N): N {
165
+ protected _swap(srcNode: N, destNode: N): N {
162
166
  const {key, val} = destNode;
163
167
  const tempNode = this.createNode(key, val);
164
168
 
@@ -300,13 +304,13 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
300
304
  }
301
305
 
302
306
  /**
303
- * The `remove` function in TypeScript is used to delete a node from a binary search tree and returns an array of objects
307
+ * The `delete` function in TypeScript is used to delete a node from a binary search tree and returns an array of objects
304
308
  * containing the deleted node and the node that needs to be balanced.
305
309
  * @param {N | BinaryTreeNodeKey} nodeOrKey - The `nodeOrKey` parameter can be either a node object (`N`) or a binary tree
306
310
  * node ID (`BinaryTreeNodeKey`).
307
- * @returns The function `remove` returns an array of `BinaryTreeDeletedResult<N>` objects.
311
+ * @returns The function `delete` returns an array of `BinaryTreeDeletedResult<N>` objects.
308
312
  */
309
- remove(nodeOrKey: N | BinaryTreeNodeKey): BinaryTreeDeletedResult<N>[] {
313
+ delete(nodeOrKey: N | BinaryTreeNodeKey): BinaryTreeDeletedResult<N>[] {
310
314
  const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
311
315
  if (!this.root) return bstDeletedResult;
312
316
 
@@ -333,7 +337,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
333
337
  const leftSubTreeRightMost = curr.left ? this.getRightMost(curr.left) : null;
334
338
  if (leftSubTreeRightMost) {
335
339
  const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
336
- orgCurrent = this.swapLocation(curr, leftSubTreeRightMost);
340
+ orgCurrent = this._swap(curr, leftSubTreeRightMost);
337
341
  if (parentOfLeftSubTreeMax) {
338
342
  if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
339
343
  parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
@@ -683,12 +687,12 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
683
687
 
684
688
  /**
685
689
  * The function checks if a binary search tree is valid by traversing it either recursively or iteratively.
686
- * @param {N | null} node - The `node` parameter represents the root node of a binary search tree (BST).
690
+ * @param {N | null} subTreeRoot - The `node` parameter represents the root node of a binary search tree (BST).
687
691
  * @returns a boolean value.
688
692
  */
689
- isSubtreeBST(node: N | null): boolean {
693
+ isSubtreeBST(subTreeRoot: N | null): boolean {
690
694
  // TODO there is a bug
691
- if (!node) return true;
695
+ if (!subTreeRoot) return true;
692
696
 
693
697
  if (this._loopType === LoopType.RECURSIVE) {
694
698
  const dfs = (cur: N | null | undefined, min: BinaryTreeNodeKey, max: BinaryTreeNodeKey): boolean => {
@@ -697,11 +701,11 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
697
701
  return dfs(cur.left, min, cur.key) && dfs(cur.right, cur.key, max);
698
702
  };
699
703
 
700
- return dfs(node, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
704
+ return dfs(subTreeRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
701
705
  } else {
702
706
  const stack = [];
703
707
  let prev = Number.MIN_SAFE_INTEGER,
704
- curr: N | null | undefined = node;
708
+ curr: N | null | undefined = subTreeRoot;
705
709
  while (curr || stack.length > 0) {
706
710
  while (curr) {
707
711
  stack.push(curr);
@@ -813,38 +817,21 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
813
817
  }
814
818
 
815
819
  /**
816
- * The function `subTreeAdd` adds a delta value to a specified property of each node in a subtree.
820
+ * The function `subTreeForeach` adds a delta value to a specified property of each node in a subtree.
817
821
  * @param {N | BinaryTreeNodeKey | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a binary
818
822
  * tree or the ID of a node in the binary tree. It can also be `null` if there is no subtree to add to.
819
- * @param {number} delta - The `delta` parameter is a number that represents the amount by which the property value of
820
- * each node in the subtree should be incremented.
821
- * @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
823
+ * @param callBack - The `callBack` parameter is a function that takes a node as a parameter and returns a number.
822
824
  * specifies the property of the binary tree node that should be modified. If not provided, it defaults to 'key'.
823
825
  * @returns a boolean value.
824
826
  */
825
- subTreeAdd(
826
- subTreeRoot: N | BinaryTreeNodeKey | null,
827
- delta: number,
828
- propertyName: BinaryTreeNodePropertyName = 'key'
829
- ): boolean {
827
+ subTreeForeach(subTreeRoot: N | BinaryTreeNodeKey | null, callback: (node: N) => any): boolean {
830
828
  if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot, 'key');
831
829
 
832
830
  if (!subTreeRoot) return false;
833
831
 
834
- const _addByProperty = (cur: N) => {
835
- switch (propertyName) {
836
- case 'key':
837
- cur.key += delta;
838
- break;
839
- default:
840
- cur.key += delta;
841
- break;
842
- }
843
- };
844
-
845
832
  if (this._loopType === LoopType.RECURSIVE) {
846
833
  const _traverse = (cur: N) => {
847
- _addByProperty(cur);
834
+ callback(cur);
848
835
  cur.left && _traverse(cur.left);
849
836
  cur.right && _traverse(cur.right);
850
837
  };
@@ -856,7 +843,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
856
843
  while (stack.length > 0) {
857
844
  const cur = stack.pop()!;
858
845
 
859
- _addByProperty(cur);
846
+ callback(cur);
860
847
  cur.right && stack.push(cur.right);
861
848
  cur.left && stack.push(cur.left);
862
849
  }
@@ -903,6 +890,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
903
890
  const queue: Array<N | null | undefined> = [this.root];
904
891
 
905
892
  while (queue.length !== 0) {
893
+ // TODO Array.shift is not efficient, consider using Deque
906
894
  const cur = queue.shift();
907
895
  if (cur) {
908
896
  this._accumulatedByPropertyName(cur, nodeOrPropertyName);
@@ -931,215 +919,98 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
931
919
  * Performs a depth-first search (dfs) traversal on a binary tree and accumulates properties of each node based on the specified property name.
932
920
  * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
933
921
  * @param {string} nodeOrPropertyName - The name of the property to accumulate.
922
+ * @param loopType - The type of loop to use for the depth-first search traversal. The default value is `LoopType.ITERATIVE`.
934
923
  * @returns An array of values corresponding to the specified property.
935
924
  */
936
- dfs(pattern: DFSOrderPattern, nodeOrPropertyName: 'key'): BinaryTreeNodeKey[];
925
+ dfs(pattern: DFSOrderPattern, nodeOrPropertyName: 'key', loopType?: LoopType): BinaryTreeNodeKey[];
937
926
 
938
927
  /**
939
928
  * Performs a depth-first search (dfs) traversal on a binary tree and accumulates the 'val' property of each node.
940
929
  * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
941
930
  * @param {'val'} nodeOrPropertyName - The name of the property to accumulate.
931
+ * @param loopType - The type of loop to use for the depth-first search traversal. The default value is `LoopType.ITERATIVE`.
942
932
  * @returns An array of 'val' properties from each node.
943
933
  */
944
- dfs(pattern: DFSOrderPattern, nodeOrPropertyName: 'val'): N[];
934
+ dfs(pattern: DFSOrderPattern, nodeOrPropertyName: 'val', loopType?: LoopType): N[];
945
935
 
946
936
  /**
947
937
  * Performs a depth-first search (dfs) traversal on a binary tree and accumulates nodes themselves.
948
938
  * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
949
939
  * @param {'node'} nodeOrPropertyName - The name of the property to accumulate.
940
+ * @param loopType - The type of loop to use for the depth-first search traversal. The default value is `LoopType.ITERATIVE`.
950
941
  * @returns An array of binary tree nodes.
951
942
  */
952
- dfs(pattern: DFSOrderPattern, nodeOrPropertyName: 'node'): N[];
943
+ dfs(pattern: DFSOrderPattern, nodeOrPropertyName: 'node', loopType?: LoopType): N[];
953
944
 
954
945
  /**
955
946
  * The dfs function performs a depth-first search traversal on a binary tree and returns the accumulated properties of
956
947
  * each node based on the specified pattern and property name.
957
948
  * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
958
949
  * @param {NodeOrPropertyName} [nodeOrPropertyName] - The name of a property of the nodes in the binary tree. This property will be used to accumulate values during the depth-first search traversal. If no `nodeOrPropertyName` is provided, the default value is `'key'`.
950
+ * @param loopType - The type of loop to use for the depth-first search traversal. The default value is `LoopType.ITERATIVE`.
959
951
  * @returns an instance of the BinaryTreeNodeProperties class, which contains the accumulated properties of the binary tree nodes based on the specified pattern and node or property name.
960
952
  */
961
- dfs(pattern: DFSOrderPattern = 'in', nodeOrPropertyName: NodeOrPropertyName = 'key'): BinaryTreeNodeProperties<N> {
962
- this._clearResults();
963
- const _traverse = (node: N) => {
964
- switch (pattern) {
965
- case 'in':
966
- if (node.left) _traverse(node.left);
967
- this._accumulatedByPropertyName(node, nodeOrPropertyName);
968
- if (node.right) _traverse(node.right);
969
- break;
970
- case 'pre':
971
- this._accumulatedByPropertyName(node, nodeOrPropertyName);
972
- if (node.left) _traverse(node.left);
973
- if (node.right) _traverse(node.right);
974
- break;
975
- case 'post':
976
- if (node.left) _traverse(node.left);
977
- if (node.right) _traverse(node.right);
978
- this._accumulatedByPropertyName(node, nodeOrPropertyName);
979
- break;
980
- }
981
- };
982
-
983
- this.root && _traverse(this.root);
984
- return this._getResultByPropertyName(nodeOrPropertyName);
985
- }
986
-
987
- // --- start additional methods ---
988
-
989
- /**
990
- * Performs an iterative depth-first search (dfs) traversal on a binary tree and accumulates properties of each node based on their 'key' property.
991
- * @returns An array of binary tree node IDs.
992
- */
993
- dfsIterative(): BinaryTreeNodeKey[];
994
-
995
- /**
996
- * Performs an iterative depth-first search (dfs) traversal on a binary tree and accumulates properties of each node based on their 'key' property.
997
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
998
- * @returns An array of values corresponding to the specified property.
999
- */
1000
- dfsIterative(pattern: DFSOrderPattern): BinaryTreeNodeKey[];
1001
-
1002
- /**
1003
- * Performs an iterative depth-first search (dfs) traversal on a binary tree and accumulates properties of each node based on the specified property name.
1004
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
1005
- * @param {string} nodeOrPropertyName - The name of the property to accumulate.
1006
- * @returns An array of values corresponding to the specified property.
1007
- */
1008
- dfsIterative(pattern: DFSOrderPattern, nodeOrPropertyName: 'key'): BinaryTreeNodeKey[];
1009
-
1010
- /**
1011
- * Performs an iterative depth-first search (dfs) traversal on a binary tree and accumulates the 'val' property of each node.
1012
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
1013
- * @param {'val'} nodeOrPropertyName - The name of the property to accumulate.
1014
- * @returns An array of 'val' properties from each node.
1015
- */
1016
- dfsIterative(pattern: DFSOrderPattern, nodeOrPropertyName: 'val'): N['val'][];
1017
-
1018
- /**
1019
- * Performs an iterative depth-first search (dfs) traversal on a binary tree and accumulates nodes themselves.
1020
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
1021
- * @param {'node'} nodeOrPropertyName - The name of the property to accumulate.
1022
- * @returns An array of binary tree nodes.
1023
- */
1024
- dfsIterative(pattern: DFSOrderPattern, nodeOrPropertyName: 'node'): N[];
1025
-
1026
- /**
1027
- * The dfsIterative function performs an iterative depth-first search traversal on a binary tree, with the option to
1028
- * specify the traversal pattern and the property name to accumulate results by.
1029
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
1030
- * @param {NodeOrPropertyName} [nodeOrPropertyName] - The name of a property of the nodes in the binary tree. This property will be used to accumulate values during the depth-first search traversal. By default, it is set to `'key'`.
1031
- * @returns An object of type BinaryTreeNodeProperties<N>.
1032
- */
1033
- dfsIterative(
953
+ dfs(
1034
954
  pattern: DFSOrderPattern = 'in',
1035
- nodeOrPropertyName: NodeOrPropertyName = 'key'
955
+ nodeOrPropertyName: NodeOrPropertyName = 'key',
956
+ loopType: LoopType = LoopType.ITERATIVE
1036
957
  ): BinaryTreeNodeProperties<N> {
1037
958
  this._clearResults();
1038
- if (!this.root) return this._getResultByPropertyName(nodeOrPropertyName);
1039
- // 0: visit, 1: print
1040
- const stack: {opt: 0 | 1; node: N | null | undefined}[] = [{opt: 0, node: this.root}];
1041
-
1042
- while (stack.length > 0) {
1043
- const cur = stack.pop();
1044
- if (!cur || !cur.node) continue;
1045
- if (cur.opt === 1) {
1046
- this._accumulatedByPropertyName(cur.node, nodeOrPropertyName);
1047
- } else {
959
+ if (loopType === LoopType.RECURSIVE) {
960
+ const _traverse = (node: N) => {
1048
961
  switch (pattern) {
1049
962
  case 'in':
1050
- stack.push({opt: 0, node: cur.node.right});
1051
- stack.push({opt: 1, node: cur.node});
1052
- stack.push({opt: 0, node: cur.node.left});
963
+ if (node.left) _traverse(node.left);
964
+ this._accumulatedByPropertyName(node, nodeOrPropertyName);
965
+ if (node.right) _traverse(node.right);
1053
966
  break;
1054
967
  case 'pre':
1055
- stack.push({opt: 0, node: cur.node.right});
1056
- stack.push({opt: 0, node: cur.node.left});
1057
- stack.push({opt: 1, node: cur.node});
968
+ this._accumulatedByPropertyName(node, nodeOrPropertyName);
969
+ if (node.left) _traverse(node.left);
970
+ if (node.right) _traverse(node.right);
1058
971
  break;
1059
972
  case 'post':
1060
- stack.push({opt: 1, node: cur.node});
1061
- stack.push({opt: 0, node: cur.node.right});
1062
- stack.push({opt: 0, node: cur.node.left});
1063
- break;
1064
- default:
1065
- stack.push({opt: 0, node: cur.node.right});
1066
- stack.push({opt: 1, node: cur.node});
1067
- stack.push({opt: 0, node: cur.node.left});
973
+ if (node.left) _traverse(node.left);
974
+ if (node.right) _traverse(node.right);
975
+ this._accumulatedByPropertyName(node, nodeOrPropertyName);
1068
976
  break;
1069
977
  }
1070
- }
1071
- }
1072
-
1073
- return this._getResultByPropertyName(nodeOrPropertyName);
1074
- }
1075
-
1076
- /**
1077
- * Performs a level-order traversal on a binary tree starting from the specified node and accumulates properties of each node based on their 'key' property.
1078
- * @returns An array of binary tree node IDs.
1079
- */
1080
- levelIterative(): BinaryTreeNodeKey[];
1081
-
1082
- /**
1083
- * Performs a level-order traversal on a binary tree starting from the specified node and accumulates properties of each node based on their 'key' property.
1084
- * @param {N | null} node - The starting node for the level order traversal. If null, the root node of the tree is used as the starting node.
1085
- * @returns An array of binary tree node IDs.
1086
- */
1087
- levelIterative(node: N | null): BinaryTreeNodeKey[];
1088
-
1089
- /**
1090
- * Performs a level-order traversal on a binary tree starting from the specified node and accumulates properties of each node based on the specified property name.
1091
- * @param {N | null} node - The starting node for the level order traversal. If null, the root node of the tree is used as the starting node.
1092
- * @param {string} nodeOrPropertyName - The name of the property to accumulate.
1093
- * @returns An array of values corresponding to the specified property.
1094
- */
1095
- levelIterative(node: N | null, nodeOrPropertyName: 'key'): BinaryTreeNodeKey[];
1096
-
1097
- /**
1098
- * Performs a level-order traversal on a binary tree starting from the specified node and accumulates the 'val' property of each node.
1099
- * @param {N | null} node - The starting node for the level order traversal. If null, the root node of the tree is used as the starting node.
1100
- * @param {'val'} nodeOrPropertyName - The name of the property to accumulate.
1101
- * @returns An array of 'val' properties from each node.
1102
- */
1103
- levelIterative(node: N | null, nodeOrPropertyName: 'val'): N['val'][];
1104
-
1105
- /**
1106
- * Performs a level-order traversal on a binary tree starting from the specified node and accumulates nodes themselves.
1107
- * @param {N | null} node - The starting node for the level order traversal. If null, the root node of the tree is used as the starting node.
1108
- * @param {'node'} nodeOrPropertyName - The name of the property to accumulate.
1109
- * @returns An array of binary tree nodes.
1110
- */
1111
- levelIterative(node: N | null, nodeOrPropertyName: 'node'): N[];
1112
-
1113
- /**
1114
- * The `levelIterative` function performs a level-order traversal on a binary tree and returns the values of the nodes
1115
- * in an array, based on a specified property name.
1116
- * @param {N | null} node - The `node` parameter is a BinaryTreeNode object representing the starting
1117
- * node for the level order traversal. It can be null if no specific node is provided, in which case the root node of
1118
- * the tree is used as the starting node.
1119
- * @param {NodeOrPropertyName} [nodeOrPropertyName] - The `nodeOrPropertyName` parameter is an optional parameter that
1120
- * can be either a `BinaryTreeNode` property name or the string `'key'`. If a property name is provided, the function
1121
- * will accumulate results based on that property. If no property name is provided, the function will default to
1122
- * accumulating results based on the 'key' property.
1123
- * @returns An object of type `BinaryTreeNodeProperties<N>`.
1124
- */
1125
- levelIterative(
1126
- node: N | null = this.root,
1127
- nodeOrPropertyName: NodeOrPropertyName = 'key'
1128
- ): BinaryTreeNodeProperties<N> {
1129
- if (!node) return [];
978
+ };
1130
979
 
1131
- this._clearResults();
1132
- const queue: N[] = [node];
980
+ this.root && _traverse(this.root);
981
+ } else {
982
+ if (!this.root) return this._getResultByPropertyName(nodeOrPropertyName);
983
+ // 0: visit, 1: print
984
+ const stack: {opt: 0 | 1; node: N | null | undefined}[] = [{opt: 0, node: this.root}];
1133
985
 
1134
- while (queue.length > 0) {
1135
- const cur = queue.shift();
1136
- if (cur) {
1137
- this._accumulatedByPropertyName(cur, nodeOrPropertyName);
1138
- if (cur.left) {
1139
- queue.push(cur.left);
1140
- }
1141
- if (cur.right) {
1142
- queue.push(cur.right);
986
+ while (stack.length > 0) {
987
+ const cur = stack.pop();
988
+ if (!cur || !cur.node) continue;
989
+ if (cur.opt === 1) {
990
+ this._accumulatedByPropertyName(cur.node, nodeOrPropertyName);
991
+ } else {
992
+ switch (pattern) {
993
+ case 'in':
994
+ stack.push({opt: 0, node: cur.node.right});
995
+ stack.push({opt: 1, node: cur.node});
996
+ stack.push({opt: 0, node: cur.node.left});
997
+ break;
998
+ case 'pre':
999
+ stack.push({opt: 0, node: cur.node.right});
1000
+ stack.push({opt: 0, node: cur.node.left});
1001
+ stack.push({opt: 1, node: cur.node});
1002
+ break;
1003
+ case 'post':
1004
+ stack.push({opt: 1, node: cur.node});
1005
+ stack.push({opt: 0, node: cur.node.right});
1006
+ stack.push({opt: 0, node: cur.node.left});
1007
+ break;
1008
+ default:
1009
+ stack.push({opt: 0, node: cur.node.right});
1010
+ stack.push({opt: 1, node: cur.node});
1011
+ stack.push({opt: 0, node: cur.node.left});
1012
+ break;
1013
+ }
1143
1014
  }
1144
1015
  }
1145
1016
  }
@@ -1147,6 +1018,8 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
1147
1018
  return this._getResultByPropertyName(nodeOrPropertyName);
1148
1019
  }
1149
1020
 
1021
+ // --- start additional methods ---
1022
+
1150
1023
  /**
1151
1024
  * Collects nodes from a binary tree by a specified property and organizes them into levels.
1152
1025
  * @returns A 2D array of AbstractBinaryTreeNodeProperty<N> objects.
@@ -1425,14 +1298,6 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
1425
1298
  }
1426
1299
  }
1427
1300
 
1428
- /**
1429
- * The function sets the loop type for a protected variable.
1430
- * @param {LoopType} value - The value parameter is of type LoopType.
1431
- */
1432
- protected _setLoopType(value: LoopType) {
1433
- this._loopType = value;
1434
- }
1435
-
1436
1301
  /**
1437
1302
  * The function sets the root property of an object to a given value, and if the value is not null, it also sets the
1438
1303
  * parent property of the value to undefined.
@@ -164,10 +164,10 @@ export class RBTree<N extends RBTreeNode<N['val'], N> = RBTreeNode> extends BST<
164
164
  // // Remove a node
165
165
  // private _removeNode(node: N, replacement: N | null | undefined): void {
166
166
  // if (node === this.root && !replacement) {
167
- // // If there's only the root node and no replacement, simply remove the root node
167
+ // // If there's only the root node and no replacement, simply delete the root node
168
168
  // this._setRoot(null);
169
169
  // } else if (node === this.root || this._isNodeRed(node)) {
170
- // // If the node is the root or a red node, remove it directly
170
+ // // If the node is the root or a red node, delete it directly
171
171
  // if (node.parent!.left === node) {
172
172
  // node.parent!.left = replacement;
173
173
  // } else {
@@ -205,7 +205,7 @@ export class RBTree<N extends RBTreeNode<N['val'], N> = RBTreeNode> extends BST<
205
205
  // node.right = null;
206
206
  // }
207
207
  //
208
- // override remove(nodeOrKey: BinaryTreeNodeKey | N): BinaryTreeDeletedResult<N>[] {
208
+ // override delete(nodeOrKey: BinaryTreeNodeKey | N): BinaryTreeDeletedResult<N>[] {
209
209
  // const node = this.get(nodeOrKey);
210
210
  // const result: BinaryTreeDeletedResult<N>[] = [{deleted: undefined, needBalanced: null}];
211
211
  // if (!node) return result; // Node does not exist
@@ -70,12 +70,12 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
70
70
 
71
71
  /**
72
72
  * The function swaps the location of two nodes in a tree data structure.
73
- * @param {N} srcNode - The source node that we want to swap with the destination node.
73
+ * @param {N} srcNode - The source node that we want to _swap with the destination node.
74
74
  * @param {N} destNode - The `destNode` parameter represents the destination node where the values from `srcNode` will
75
75
  * be swapped with.
76
76
  * @returns the `destNode` after swapping its values with the `srcNode`.
77
77
  */
78
- override swapLocation(srcNode: N, destNode: N): N {
78
+ protected override _swap(srcNode: N, destNode: N): N {
79
79
  const {key, val, count, height} = destNode;
80
80
  const tempNode = this.createNode(key, val, count);
81
81
  if (tempNode) {
@@ -285,15 +285,15 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
285
285
  }
286
286
 
287
287
  /**
288
- * The `remove` function removes a node from a binary search tree and returns the deleted node along with the parent
288
+ * The `delete` function removes a node from a binary search tree and returns the deleted node along with the parent
289
289
  * node that needs to be balanced.
290
290
  * @param {N | BinaryTreeNodeKey | null} nodeOrKey - The `nodeOrKey` parameter can be one of the following:
291
291
  * @param {boolean} [ignoreCount] - The `ignoreCount` parameter is an optional boolean parameter that determines
292
292
  * whether to ignore the count of the node being removed. If `ignoreCount` is set to `true`, the count of the node will
293
293
  * not be taken into account when removing it. If `ignoreCount` is set to `false
294
- * @returns The function `remove` returns an array of `BinaryTreeDeletedResult<N>` objects.
294
+ * @returns The function `delete` returns an array of `BinaryTreeDeletedResult<N>` objects.
295
295
  */
296
- override remove(nodeOrKey: N | BinaryTreeNodeKey, ignoreCount = false): BinaryTreeDeletedResult<N>[] {
296
+ override delete(nodeOrKey: N | BinaryTreeNodeKey, ignoreCount = false): BinaryTreeDeletedResult<N>[] {
297
297
  const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
298
298
  if (!this.root) return bstDeletedResult;
299
299
 
@@ -324,7 +324,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
324
324
  const leftSubTreeRightMost = curr.left ? this.getRightMost(curr.left) : null;
325
325
  if (leftSubTreeRightMost) {
326
326
  const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
327
- orgCurrent = this.swapLocation(curr, leftSubTreeRightMost);
327
+ orgCurrent = this._swap(curr, leftSubTreeRightMost);
328
328
  if (parentOfLeftSubTreeMax) {
329
329
  if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost) {
330
330
  parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
@@ -515,7 +515,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
515
515
  * @returns The BFSCount() function returns an array of numbers, specifically the count property of each node in the
516
516
  * bfs traversal.
517
517
  */
518
- BFSCount(): number[] {
518
+ bfsCount(): number[] {
519
519
  const nodes = super.bfs('node');
520
520
  return nodes.map(node => node.count);
521
521
  }
@@ -550,23 +550,12 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
550
550
  * the specified traversal pattern.
551
551
  * @param {'in' | 'pre' | 'post'} [pattern] - The pattern parameter is a string that specifies the traversal order for
552
552
  * the Depth-First Search (dfs) algorithm. It can have three possible values: 'in', 'pre', or 'post'.
553
+ * @param loopType - The loopType parameter is a string that specifies the type of loop to use when traversing the
553
554
  * @returns The dfsCountIterative function returns an array of numbers, which represents the count property of each node
554
555
  * in the dfs traversal.
555
556
  */
556
- dfsCountIterative(pattern: DFSOrderPattern = 'in'): number[] {
557
- const nodes = super.dfsIterative(pattern, 'node');
558
- return nodes.map(node => node.count);
559
- }
560
-
561
- /**
562
- * The dfsCount function returns an array of counts for each node in a depth-first search traversal.
563
- * @param {DFSOrderPattern} [pattern] - The pattern parameter is an optional parameter that specifies the order in which
564
- * the Depth-First Search (dfs) algorithm should traverse the nodes. It can have one of the following values:
565
- * @returns The dfsCount function returns an array of numbers, specifically the count property of each node in the dfs
566
- * traversal.
567
- */
568
- dfsCount(pattern: DFSOrderPattern = 'in'): number[] {
569
- const nodes = super.dfs(pattern, 'node');
557
+ dfsCount(pattern: DFSOrderPattern = 'in', loopType: LoopType = LoopType.ITERATIVE): number[] {
558
+ const nodes = super.dfs(pattern, 'node', loopType);
570
559
  return nodes.map(node => node.count);
571
560
  }
572
561
 
@@ -157,7 +157,7 @@ export class HashMap<K, V> {
157
157
  return undefined;
158
158
  }
159
159
 
160
- remove(key: K): void {
160
+ delete(key: K): void {
161
161
  const index = this._hash(key);
162
162
  if (!this.table[index]) {
163
163
  return;