data-structure-typed 1.19.6 → 1.19.8

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 (43) hide show
  1. package/dist/data-structures/binary-tree/abstract-binary-tree.d.ts +41 -58
  2. package/dist/data-structures/binary-tree/abstract-binary-tree.js +107 -145
  3. package/dist/data-structures/binary-tree/avl-tree.d.ts +1 -0
  4. package/dist/data-structures/binary-tree/avl-tree.js +4 -0
  5. package/dist/data-structures/binary-tree/binary-tree.d.ts +2 -1
  6. package/dist/data-structures/binary-tree/binary-tree.js +3 -0
  7. package/dist/data-structures/binary-tree/bst.d.ts +1 -0
  8. package/dist/data-structures/binary-tree/bst.js +4 -0
  9. package/dist/data-structures/binary-tree/rb-tree.d.ts +1 -1
  10. package/dist/data-structures/binary-tree/rb-tree.js +2 -3
  11. package/dist/data-structures/binary-tree/tree-multiset.d.ts +22 -16
  12. package/dist/data-structures/binary-tree/tree-multiset.js +138 -122
  13. package/dist/data-structures/interfaces/abstract-binary-tree.d.ts +6 -9
  14. package/dist/data-structures/types/abstract-binary-tree.d.ts +1 -2
  15. package/dist/data-structures/types/tree-multiset.d.ts +2 -2
  16. package/package.json +22 -5
  17. package/src/data-structures/binary-tree/abstract-binary-tree.ts +112 -161
  18. package/src/data-structures/binary-tree/avl-tree.ts +4 -0
  19. package/src/data-structures/binary-tree/binary-tree.ts +4 -2
  20. package/src/data-structures/binary-tree/bst.ts +4 -1
  21. package/src/data-structures/binary-tree/rb-tree.ts +3 -3
  22. package/src/data-structures/binary-tree/tree-multiset.ts +136 -118
  23. package/src/data-structures/interfaces/abstract-binary-tree.ts +6 -43
  24. package/src/data-structures/types/abstract-binary-tree.ts +1 -2
  25. package/src/data-structures/types/tree-multiset.ts +2 -2
  26. package/tsconfig.json +1 -2
  27. package/src/data-structures/binary-tree/diagrams/avl-tree-inserting.gif +0 -0
  28. package/src/data-structures/binary-tree/diagrams/bst-rotation.gif +0 -0
  29. package/src/data-structures/binary-tree/diagrams/segment-tree.png +0 -0
  30. package/src/data-structures/graph/diagrams/adjacency-list-pros-cons.jpg +0 -0
  31. package/src/data-structures/graph/diagrams/adjacency-list.jpg +0 -0
  32. package/src/data-structures/graph/diagrams/adjacency-matrix-pros-cons.jpg +0 -0
  33. package/src/data-structures/graph/diagrams/adjacency-matrix.jpg +0 -0
  34. package/src/data-structures/graph/diagrams/dfs-can-do.jpg +0 -0
  35. package/src/data-structures/graph/diagrams/edge-list-pros-cons.jpg +0 -0
  36. package/src/data-structures/graph/diagrams/edge-list.jpg +0 -0
  37. package/src/data-structures/graph/diagrams/max-flow.jpg +0 -0
  38. package/src/data-structures/graph/diagrams/mst.jpg +0 -0
  39. package/src/data-structures/graph/diagrams/tarjan-articulation-point-bridge.png +0 -0
  40. package/src/data-structures/graph/diagrams/tarjan-complicate-simple.png +0 -0
  41. package/src/data-structures/graph/diagrams/tarjan-strongly-connected-component.png +0 -0
  42. package/src/data-structures/graph/diagrams/tarjan.mp4 +0 -0
  43. package/src/data-structures/graph/diagrams/tarjan.webp +0 -0
@@ -10,6 +10,9 @@ exports.AVLTree = exports.AVLTreeNode = void 0;
10
10
  */
11
11
  const bst_1 = require("./bst");
12
12
  class AVLTreeNode extends bst_1.BSTNode {
13
+ constructor(id, val) {
14
+ super(id, val);
15
+ }
13
16
  }
14
17
  exports.AVLTreeNode = AVLTreeNode;
15
18
  class AVLTree extends bst_1.BST {
@@ -41,6 +44,7 @@ class AVLTree extends bst_1.BST {
41
44
  * @returns The method is returning the inserted node, or null or undefined if the insertion was not successful.
42
45
  */
43
46
  add(id, val) {
47
+ // TODO support node as a param
44
48
  const inserted = super.add(id, val);
45
49
  if (inserted)
46
50
  this.balancePath(inserted);
@@ -7,8 +7,9 @@
7
7
  */
8
8
  import type { BinaryTreeNodeId, BinaryTreeNodeNested, BinaryTreeOptions } from '../types';
9
9
  import { AbstractBinaryTree, AbstractBinaryTreeNode } from './abstract-binary-tree';
10
- import { IBinaryTree, IBinaryTreeNode } from '../interfaces/binary-tree';
10
+ import { IBinaryTree, IBinaryTreeNode } from '../interfaces';
11
11
  export declare class BinaryTreeNode<T = any, NEIGHBOR extends BinaryTreeNode<T, NEIGHBOR> = BinaryTreeNodeNested<T>> extends AbstractBinaryTreeNode<T, NEIGHBOR> implements IBinaryTreeNode<T, NEIGHBOR> {
12
+ constructor(id: BinaryTreeNodeId, val?: T);
12
13
  }
13
14
  export declare class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode> extends AbstractBinaryTree<N> implements IBinaryTree<N> {
14
15
  /**
@@ -10,6 +10,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.BinaryTree = exports.BinaryTreeNode = void 0;
11
11
  const abstract_binary_tree_1 = require("./abstract-binary-tree");
12
12
  class BinaryTreeNode extends abstract_binary_tree_1.AbstractBinaryTreeNode {
13
+ constructor(id, val) {
14
+ super(id, val);
15
+ }
13
16
  }
14
17
  exports.BinaryTreeNode = BinaryTreeNode;
15
18
  class BinaryTree extends abstract_binary_tree_1.AbstractBinaryTree {
@@ -10,6 +10,7 @@ import { CP } from '../types';
10
10
  import { BinaryTree, BinaryTreeNode } from './binary-tree';
11
11
  import { IBST, IBSTNode } from '../interfaces';
12
12
  export declare class BSTNode<T = any, NEIGHBOR extends BSTNode<T, NEIGHBOR> = BSTNodeNested<T>> extends BinaryTreeNode<T, NEIGHBOR> implements IBSTNode<T, NEIGHBOR> {
13
+ constructor(id: BinaryTreeNodeId, val?: T);
13
14
  }
14
15
  export declare class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N> implements IBST<N> {
15
16
  /**
@@ -4,6 +4,9 @@ exports.BST = exports.BSTNode = void 0;
4
4
  const types_1 = require("../types");
5
5
  const binary_tree_1 = require("./binary-tree");
6
6
  class BSTNode extends binary_tree_1.BinaryTreeNode {
7
+ constructor(id, val) {
8
+ super(id, val);
9
+ }
7
10
  }
8
11
  exports.BSTNode = BSTNode;
9
12
  class BST extends binary_tree_1.BinaryTree {
@@ -42,6 +45,7 @@ class BST extends binary_tree_1.BinaryTree {
42
45
  * If the node was not added (e.g., due to a duplicate ID), it returns `null` or `undefined`.
43
46
  */
44
47
  add(id, val) {
48
+ // TODO support node as a param
45
49
  let inserted = null;
46
50
  const newNode = this.createNode(id, val);
47
51
  if (this.root === null) {
@@ -2,7 +2,7 @@ import { BinaryTreeNodeId, RBColor, RBTreeNodeNested, RBTreeOptions } from '../t
2
2
  import { IRBTree, IRBTreeNode } from '../interfaces/rb-tree';
3
3
  import { BST, BSTNode } from './bst';
4
4
  export declare class RBTreeNode<T = any, NEIGHBOR extends RBTreeNode<T, NEIGHBOR> = RBTreeNodeNested<T>> extends BSTNode<T, NEIGHBOR> implements IRBTreeNode<T, NEIGHBOR> {
5
- constructor(id: BinaryTreeNodeId, color: RBColor, val?: T);
5
+ constructor(id: BinaryTreeNodeId, val?: T, color?: RBColor);
6
6
  private _color;
7
7
  get color(): RBColor;
8
8
  set color(value: RBColor);
@@ -4,9 +4,8 @@ exports.RBTree = exports.RBTreeNode = void 0;
4
4
  const types_1 = require("../types");
5
5
  const bst_1 = require("./bst");
6
6
  class RBTreeNode extends bst_1.BSTNode {
7
- constructor(id, color, val) {
7
+ constructor(id, val, color = types_1.RBColor.RED) {
8
8
  super(id, val);
9
- this._color = types_1.RBColor.RED;
10
9
  this._color = color;
11
10
  }
12
11
  get color() {
@@ -22,7 +21,7 @@ class RBTree extends bst_1.BST {
22
21
  super(options);
23
22
  }
24
23
  createNode(id, val) {
25
- return new RBTreeNode(id, types_1.RBColor.RED, val);
24
+ return new RBTreeNode(id, val, types_1.RBColor.RED);
26
25
  }
27
26
  // private override _root: BinaryTreeNode<N> | null = null;
28
27
  //
@@ -57,17 +57,16 @@ export declare class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = Tree
57
57
  */
58
58
  swapLocation(srcNode: N, destNode: N): N;
59
59
  /**
60
- * The `add` function adds a new node to a binary tree, updating the size and count properties accordingly, and
61
- * balancing the tree if necessary.
62
- * @param {BinaryTreeNodeId} id - The id parameter represents the identifier of the binary tree node that we want to
63
- * add. It is of type BinaryTreeNodeId.
64
- * @param [val] - The `val` parameter is an optional value that can be assigned to the node being added. If no value is
65
- * provided, it will default to `undefined`.
66
- * @param {number} [count] - The `count` parameter is an optional parameter that specifies the number of times the node
67
- * with the given `id` should be added to the binary tree. If the `count` parameter is not provided, it defaults to 1.
68
- * @returns The `add` method returns the inserted node (`N`), `null`, or `undefined`.
69
- */
70
- add(id: BinaryTreeNodeId, val?: N['val'], count?: number): N | null | undefined;
60
+ * The `add` function adds a new node to a binary search tree, maintaining the tree's properties and balancing if
61
+ * necessary.
62
+ * @param {BinaryTreeNodeId | N} idOrNode - The `idOrNode` parameter can be either a `BinaryTreeNodeId` or a `N` (which
63
+ * represents a `BinaryTreeNode`).
64
+ * @param [val] - The `val` parameter represents the value to be added to the binary tree node.
65
+ * @param {number} [count] - The `count` parameter is an optional parameter that specifies the number of times the
66
+ * value should be added to the binary tree. If the `count` parameter is not provided, it defaults to 1.
67
+ * @returns The method `add` returns either the inserted node (`N`), `null`, or `undefined`.
68
+ */
69
+ add(idOrNode: BinaryTreeNodeId | N | null, val?: N['val'], count?: number): N | null | undefined;
71
70
  /**
72
71
  * The function adds a new node to a binary tree as the left or right child of a given parent node.
73
72
  * @param {N | null} newNode - The `newNode` parameter represents the node that you want to add to the tree. It can be
@@ -79,13 +78,20 @@ export declare class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = Tree
79
78
  */
80
79
  addTo(newNode: N | null, parent: N): N | null | undefined;
81
80
  /**
82
- * The `addMany` function inserts multiple items into a binary tree and returns an array of the inserted nodes or
83
- * null/undefined values.
84
- * @param {N[] | N[]} data - The `data` parameter can be either an array of elements of type `N` or an
85
- * array of `N` objects.
81
+ * The `addMany` function adds multiple nodes to a binary tree and returns an array of the inserted nodes.
82
+ * @param {BinaryTreeNodeId[] | N[]} idsOrNodes - An array of BinaryTreeNodeId objects or N objects. These objects
83
+ * represent the IDs or nodes of the binary tree where the values will be added.
84
+ * @param {N['val'][]} [data] - Optional array of values to be associated with each node being added. If provided, the
85
+ * length of the `data` array should be equal to the length of the `idsOrNodes` array.
86
86
  * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
87
87
  */
88
- addMany(data: N[] | Array<N['val']>): (N | null | undefined)[];
88
+ addMany(idsOrNodes: (BinaryTreeNodeId | N)[], data?: N['val'][]): (N | null | undefined)[];
89
+ /**
90
+ * The `perfectlyBalance` function takes a binary tree, performs a depth-first search to sort the nodes, and then
91
+ * constructs a balanced binary search tree using either a recursive or iterative approach.
92
+ * @returns The function `perfectlyBalance()` returns a boolean value.
93
+ */
94
+ perfectlyBalance(): boolean;
89
95
  /**
90
96
  * The `remove` function removes a node from a binary search tree and returns the deleted node along with the parent
91
97
  * node that needs to be balanced.
@@ -16,7 +16,6 @@ class TreeMultisetNode extends avl_tree_1.AVLTreeNode {
16
16
  */
17
17
  constructor(id, val, count = 1) {
18
18
  super(id, val);
19
- this._count = 1;
20
19
  this._count = count;
21
20
  }
22
21
  get count() {
@@ -38,7 +37,7 @@ class TreeMultiset extends avl_tree_1.AVLTree {
38
37
  * TreeMultiset.
39
38
  */
40
39
  constructor(options) {
41
- super(Object.assign(Object.assign({}, options), { isMergeDuplicatedVal: true }));
40
+ super(Object.assign(Object.assign({}, options), { isMergeDuplicatedNodeById: true }));
42
41
  this._count = 0;
43
42
  }
44
43
  get count() {
@@ -64,97 +63,98 @@ class TreeMultiset extends avl_tree_1.AVLTree {
64
63
  * @returns the `destNode` after swapping its values with the `srcNode`.
65
64
  */
66
65
  swapLocation(srcNode, destNode) {
67
- const { val, count, height, id } = destNode;
66
+ const { id, val, count, height } = destNode;
68
67
  const tempNode = this.createNode(id, val, count);
69
68
  if (tempNode) {
70
69
  tempNode.height = height;
71
- if (tempNode instanceof TreeMultisetNode) {
72
- destNode.id = srcNode.id;
73
- destNode.val = srcNode.val;
74
- destNode.count = srcNode.count;
75
- destNode.height = srcNode.height;
76
- srcNode.id = tempNode.id;
77
- srcNode.val = tempNode.val;
78
- srcNode.count = tempNode.count;
79
- srcNode.height = tempNode.height;
80
- }
70
+ destNode.id = srcNode.id;
71
+ destNode.val = srcNode.val;
72
+ destNode.count = srcNode.count;
73
+ destNode.height = srcNode.height;
74
+ srcNode.id = tempNode.id;
75
+ srcNode.val = tempNode.val;
76
+ srcNode.count = tempNode.count;
77
+ srcNode.height = tempNode.height;
81
78
  }
82
79
  return destNode;
83
80
  }
84
81
  /**
85
- * The `add` function adds a new node to a binary tree, updating the size and count properties accordingly, and
86
- * balancing the tree if necessary.
87
- * @param {BinaryTreeNodeId} id - The id parameter represents the identifier of the binary tree node that we want to
88
- * add. It is of type BinaryTreeNodeId.
89
- * @param [val] - The `val` parameter is an optional value that can be assigned to the node being added. If no value is
90
- * provided, it will default to `undefined`.
91
- * @param {number} [count] - The `count` parameter is an optional parameter that specifies the number of times the node
92
- * with the given `id` should be added to the binary tree. If the `count` parameter is not provided, it defaults to 1.
93
- * @returns The `add` method returns the inserted node (`N`), `null`, or `undefined`.
82
+ * The `add` function adds a new node to a binary search tree, maintaining the tree's properties and balancing if
83
+ * necessary.
84
+ * @param {BinaryTreeNodeId | N} idOrNode - The `idOrNode` parameter can be either a `BinaryTreeNodeId` or a `N` (which
85
+ * represents a `BinaryTreeNode`).
86
+ * @param [val] - The `val` parameter represents the value to be added to the binary tree node.
87
+ * @param {number} [count] - The `count` parameter is an optional parameter that specifies the number of times the
88
+ * value should be added to the binary tree. If the `count` parameter is not provided, it defaults to 1.
89
+ * @returns The method `add` returns either the inserted node (`N`), `null`, or `undefined`.
94
90
  */
95
- add(id, val, count) {
91
+ add(idOrNode, val, count) {
96
92
  count = count !== null && count !== void 0 ? count : 1;
97
- let inserted = null;
98
- const newNode = this.createNode(id, val, count);
99
- if (this.root === null) {
93
+ let inserted = undefined, newNode;
94
+ if (idOrNode instanceof TreeMultisetNode) {
95
+ newNode = this.createNode(idOrNode.id, idOrNode.val, idOrNode.count);
96
+ }
97
+ else if (idOrNode === null) {
98
+ newNode = null;
99
+ }
100
+ else {
101
+ newNode = this.createNode(idOrNode, val, count);
102
+ }
103
+ if (!this.root) {
100
104
  this._setRoot(newNode);
101
105
  this._setSize(this.size + 1);
102
- this._setCount(this.count + count);
103
- inserted = (this.root);
106
+ newNode && this._setCount(this.count + newNode.count);
107
+ inserted = this.root;
104
108
  }
105
109
  else {
106
110
  let cur = this.root;
107
111
  let traversing = true;
108
112
  while (traversing) {
109
- if (cur !== null && newNode !== null) {
110
- if (this._compare(cur.id, id) === types_1.CP.eq) {
111
- if (newNode) {
113
+ if (cur) {
114
+ if (newNode) {
115
+ if (this._compare(cur.id, newNode.id) === types_1.CP.eq) {
112
116
  cur.val = newNode.val;
113
- cur.count += count;
114
- this._setCount(this.count + newNode.count);
115
- }
116
- //Duplicates are not accepted.
117
- traversing = false;
118
- inserted = cur;
119
- }
120
- else if (this._compare(cur.id, id) === types_1.CP.gt) {
121
- // Traverse left of the node
122
- if (cur.left === undefined) {
123
- if (newNode) {
124
- newNode.parent = cur;
125
- }
126
- //Add to the left of the current node
127
- cur.left = newNode;
128
- this._setSize(this.size + 1);
117
+ cur.count += newNode.count;
129
118
  this._setCount(this.count + newNode.count);
130
119
  traversing = false;
131
- inserted = cur.left;
120
+ inserted = cur;
132
121
  }
133
- else {
134
- //Traverse the left of the current node
135
- if (cur.left)
136
- cur = cur.left;
137
- }
138
- }
139
- else if (this._compare(cur.id, id) === types_1.CP.lt) {
140
- // Traverse right of the node
141
- if (cur.right === undefined) {
142
- if (newNode) {
143
- newNode.parent = cur;
122
+ else if (this._compare(cur.id, newNode.id) === types_1.CP.gt) {
123
+ // Traverse left of the node
124
+ if (cur.left === undefined) {
125
+ //Add to the left of the current node
126
+ cur.left = newNode;
127
+ this._setSize(this.size + 1);
128
+ this._setCount(this.count + newNode.count);
129
+ traversing = false;
130
+ inserted = cur.left;
131
+ }
132
+ else {
133
+ //Traverse the left of the current node
134
+ if (cur.left)
135
+ cur = cur.left;
144
136
  }
145
- //Add to the right of the current node
146
- cur.right = newNode;
147
- this._setSize(this.size + 1);
148
- this._setCount(this.count + newNode.count);
149
- traversing = false;
150
- inserted = (cur.right);
151
137
  }
152
- else {
153
- //Traverse the left of the current node
154
- if (cur.right)
155
- cur = cur.right;
138
+ else if (this._compare(cur.id, newNode.id) === types_1.CP.lt) {
139
+ // Traverse right of the node
140
+ if (cur.right === undefined) {
141
+ //Add to the right of the current node
142
+ cur.right = newNode;
143
+ this._setSize(this.size + 1);
144
+ this._setCount(this.count + newNode.count);
145
+ traversing = false;
146
+ inserted = (cur.right);
147
+ }
148
+ else {
149
+ //Traverse the left of the current node
150
+ if (cur.right)
151
+ cur = cur.right;
152
+ }
156
153
  }
157
154
  }
155
+ else {
156
+ // TODO may need to support null inserted
157
+ }
158
158
  }
159
159
  else {
160
160
  traversing = false;
@@ -175,27 +175,20 @@ class TreeMultiset extends avl_tree_1.AVLTree {
175
175
  * `undefined` in certain cases.
176
176
  */
177
177
  addTo(newNode, parent) {
178
- var _a, _b;
179
178
  if (parent) {
180
179
  if (parent.left === undefined) {
181
- if (newNode) {
182
- newNode.parent = parent;
183
- }
184
180
  parent.left = newNode;
185
181
  if (newNode !== null) {
186
182
  this._setSize(this.size + 1);
187
- this._setCount((_a = this.count + newNode.count) !== null && _a !== void 0 ? _a : 0);
183
+ this._setCount(this.count + newNode.count);
188
184
  }
189
185
  return parent.left;
190
186
  }
191
187
  else if (parent.right === undefined) {
192
- if (newNode) {
193
- newNode.parent = parent;
194
- }
195
188
  parent.right = newNode;
196
189
  if (newNode !== null) {
197
190
  this._setSize(this.size + 1);
198
- this._setCount((_b = this.count + newNode.count) !== null && _b !== void 0 ? _b : 0);
191
+ this._setCount(this.count + newNode.count);
199
192
  }
200
193
  return parent.right;
201
194
  }
@@ -208,66 +201,86 @@ class TreeMultiset extends avl_tree_1.AVLTree {
208
201
  }
209
202
  }
210
203
  /**
211
- * The `addMany` function inserts multiple items into a binary tree and returns an array of the inserted nodes or
212
- * null/undefined values.
213
- * @param {N[] | N[]} data - The `data` parameter can be either an array of elements of type `N` or an
214
- * array of `N` objects.
204
+ * The `addMany` function adds multiple nodes to a binary tree and returns an array of the inserted nodes.
205
+ * @param {BinaryTreeNodeId[] | N[]} idsOrNodes - An array of BinaryTreeNodeId objects or N objects. These objects
206
+ * represent the IDs or nodes of the binary tree where the values will be added.
207
+ * @param {N['val'][]} [data] - Optional array of values to be associated with each node being added. If provided, the
208
+ * length of the `data` array should be equal to the length of the `idsOrNodes` array.
215
209
  * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
216
210
  */
217
- addMany(data) {
211
+ addMany(idsOrNodes, data) {
218
212
  var _a;
219
213
  // TODO not sure addMany not be run multi times
220
214
  const inserted = [];
221
215
  const map = new Map();
222
- if (this.isMergeDuplicatedVal) {
223
- for (const nodeOrId of data)
224
- map.set(nodeOrId, ((_a = map.get(nodeOrId)) !== null && _a !== void 0 ? _a : 0) + 1);
216
+ if (this.isMergeDuplicatedNodeById) {
217
+ for (const idOrNode of idsOrNodes)
218
+ map.set(idOrNode, ((_a = map.get(idOrNode)) !== null && _a !== void 0 ? _a : 0) + 1);
225
219
  }
226
- for (const nodeOrId of data) {
227
- if (nodeOrId instanceof TreeMultisetNode) {
228
- inserted.push(this.add(nodeOrId.id, nodeOrId.val, nodeOrId.count));
220
+ for (let i = 0; i < idsOrNodes.length; i++) {
221
+ const idOrNode = idsOrNodes[i];
222
+ if (idOrNode instanceof TreeMultisetNode) {
223
+ inserted.push(this.add(idOrNode.id, idOrNode.val, idOrNode.count));
229
224
  continue;
230
225
  }
231
- if (nodeOrId === null) {
226
+ if (idOrNode === null) {
232
227
  inserted.push(this.add(NaN, null, 0));
233
228
  continue;
234
229
  }
235
- // TODO will this cause an issue?
236
- const count = this.isMergeDuplicatedVal ? map.get(nodeOrId) : 1;
237
- let newId;
238
- if (typeof nodeOrId === 'number') {
239
- newId = this.autoIncrementId ? this.maxId + 1 : nodeOrId;
240
- }
241
- else if (nodeOrId instanceof Object) {
242
- if (this.autoIncrementId) {
243
- newId = this.maxId + 1;
244
- }
245
- else {
246
- if (Object.keys(nodeOrId).includes('id')) {
247
- newId = nodeOrId.id;
248
- }
249
- else {
250
- console.warn(nodeOrId, 'Object value must has an id property when the autoIncrementId is false');
251
- continue;
252
- }
230
+ const count = this.isMergeDuplicatedNodeById ? map.get(idOrNode) : 1;
231
+ const val = data === null || data === void 0 ? void 0 : data[i];
232
+ if (this.isMergeDuplicatedNodeById) {
233
+ if (map.has(idOrNode)) {
234
+ inserted.push(this.add(idOrNode, val, count));
235
+ map.delete(idOrNode);
253
236
  }
254
237
  }
255
238
  else {
256
- console.warn(nodeOrId, ` is not added`);
257
- continue;
239
+ inserted.push(this.add(idOrNode, val, 1));
258
240
  }
259
- if (this.isMergeDuplicatedVal) {
260
- if (map.has(nodeOrId)) {
261
- inserted.push(this.add(newId, nodeOrId, count));
262
- map.delete(nodeOrId);
241
+ }
242
+ return inserted;
243
+ }
244
+ /**
245
+ * The `perfectlyBalance` function takes a binary tree, performs a depth-first search to sort the nodes, and then
246
+ * constructs a balanced binary search tree using either a recursive or iterative approach.
247
+ * @returns The function `perfectlyBalance()` returns a boolean value.
248
+ */
249
+ perfectlyBalance() {
250
+ const sorted = this.DFS('in', 'node'), n = sorted.length;
251
+ if (sorted.length < 1)
252
+ return false;
253
+ this.clear();
254
+ if (this.loopType === types_1.LoopType.RECURSIVE) {
255
+ const buildBalanceBST = (l, r) => {
256
+ if (l > r)
257
+ return;
258
+ const m = l + Math.floor((r - l) / 2);
259
+ const midNode = sorted[m];
260
+ this.add(midNode.id, midNode.val, midNode.count);
261
+ buildBalanceBST(l, m - 1);
262
+ buildBalanceBST(m + 1, r);
263
+ };
264
+ buildBalanceBST(0, n - 1);
265
+ return true;
266
+ }
267
+ else {
268
+ const stack = [[0, n - 1]];
269
+ while (stack.length > 0) {
270
+ const popped = stack.pop();
271
+ if (popped) {
272
+ const [l, r] = popped;
273
+ if (l <= r) {
274
+ const m = l + Math.floor((r - l) / 2);
275
+ const midNode = sorted[m];
276
+ this.add(midNode.id, midNode.val, midNode.count);
277
+ stack.push([m + 1, r]);
278
+ stack.push([l, m - 1]);
279
+ }
263
280
  }
264
281
  }
265
- else {
266
- inserted.push(this.add(newId, nodeOrId, 1));
267
- }
268
- this._setMaxId(newId);
282
+ return true;
269
283
  }
270
- return inserted;
271
284
  }
272
285
  /**
273
286
  * The `remove` function removes a node from a binary search tree and returns the deleted node along with the parent
@@ -282,7 +295,7 @@ class TreeMultiset extends avl_tree_1.AVLTree {
282
295
  const bstDeletedResult = [];
283
296
  if (!this.root)
284
297
  return bstDeletedResult;
285
- const curr = (typeof nodeOrId === 'number') ? this.get(nodeOrId) : nodeOrId;
298
+ const curr = this.get(nodeOrId);
286
299
  if (!curr)
287
300
  return bstDeletedResult;
288
301
  const parent = (curr === null || curr === void 0 ? void 0 : curr.parent) ? curr.parent : null;
@@ -314,15 +327,18 @@ class TreeMultiset extends avl_tree_1.AVLTree {
314
327
  const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
315
328
  orgCurrent = this.swapLocation(curr, leftSubTreeRightMost);
316
329
  if (parentOfLeftSubTreeMax) {
317
- if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
330
+ if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost) {
318
331
  parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
319
- else
332
+ }
333
+ else {
320
334
  parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left;
335
+ }
321
336
  needBalanced = parentOfLeftSubTreeMax;
322
337
  }
323
338
  }
324
339
  }
325
340
  this._setSize(this.size - 1);
341
+ // TODO How to handle when the count of target node is lesser than current node's count
326
342
  this._setCount(this.count - orgCurrent.count);
327
343
  }
328
344
  bstDeletedResult.push({ deleted: orgCurrent, needBalanced });
@@ -21,20 +21,17 @@ export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'],
21
21
  get visitedId(): BinaryTreeNodeId[];
22
22
  get visitedVal(): Array<N['val']>;
23
23
  get visitedNode(): N[];
24
- get visitedCount(): number[];
25
24
  get visitedLeftSum(): number[];
26
- get autoIncrementId(): boolean;
27
- get maxId(): number;
28
- get isMergeDuplicatedVal(): boolean;
25
+ get isMergeDuplicatedNodeById(): boolean;
29
26
  get root(): N | null;
30
27
  get size(): number;
31
28
  swapLocation(srcNode: N, destNode: N): N;
32
29
  clear(): void;
33
30
  isEmpty(): boolean;
34
- add(id: BinaryTreeNodeId, val?: N['val'], count?: number): N | null | undefined;
31
+ add(id: BinaryTreeNodeId | N, val?: N['val']): N | null | undefined;
35
32
  addTo(newNode: N | null, parent: N): N | null | undefined;
36
- addMany(data: N[] | Array<N['val']>): (N | null | undefined)[];
37
- fill(data: N[] | Array<N['val']>): boolean;
33
+ addMany(idsOrNodes: (BinaryTreeNodeId | N | null)[], data?: N['val'][]): (N | null | undefined)[];
34
+ fill(idsOrNodes: (BinaryTreeNodeId | N | null)[], data?: N[] | Array<N['val']>): boolean;
38
35
  remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeletedResult<N>[];
39
36
  getDepth(node: N): number;
40
37
  getHeight(beginRoot?: N | null): number;
@@ -50,8 +47,8 @@ export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'],
50
47
  getRightMost(): N | null;
51
48
  getRightMost(node: N): N;
52
49
  getRightMost(node?: N | null): N | null;
53
- isBSTByRooted(node: N | null): boolean;
54
- isBST(node?: N | null): boolean;
50
+ isSubtreeBST(node: N | null): boolean;
51
+ isBST(): boolean;
55
52
  getSubTreeSize(subTreeRoot: N | null | undefined): number;
56
53
  subTreeSum(subTreeRoot: N, propertyName?: BinaryTreeNodePropertyName): number;
57
54
  subTreeAdd(subTreeRoot: N, delta: number, propertyName?: BinaryTreeNodePropertyName): boolean;
@@ -31,6 +31,5 @@ export type AbstractBinaryTreeNodeProperties<N extends AbstractBinaryTreeNode<N[
31
31
  export type AbstractBinaryTreeNodeNested<T> = AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
32
32
  export type AbstractBinaryTreeOptions = {
33
33
  loopType?: LoopType;
34
- autoIncrementId?: boolean;
35
- isMergeDuplicatedVal?: boolean;
34
+ isMergeDuplicatedNodeById?: boolean;
36
35
  };
@@ -1,6 +1,6 @@
1
1
  import { TreeMultisetNode } from '../binary-tree';
2
2
  import { AVLTreeOptions } from './avl-tree';
3
3
  export type TreeMultisetNodeNested<T> = TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
4
- export type TreeMultisetOptions = Omit<AVLTreeOptions, 'isMergeDuplicatedVal'> & {
5
- isMergeDuplicatedVal: true;
4
+ export type TreeMultisetOptions = Omit<AVLTreeOptions, 'isMergeDuplicatedNodeById'> & {
5
+ isMergeDuplicatedNodeById: true;
6
6
  };
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "data-structure-typed",
3
- "version": "1.19.6",
3
+ "version": "1.19.8",
4
4
  "description": "Javascript & TypeScript Data Structure Library, meticulously crafted to empower developers with a versatile set of essential data structures. Our library includes a wide range of data structures, such as Binary Tree, AVL Tree, Binary Search Tree (BST), Tree Multiset, Segment Tree, Binary Indexed Tree, Graph, Directed Graph, Undirected Graph, Singly Linked List, Hash, CoordinateSet, CoordinateMap, Heap, Doubly Linked List, Priority Queue, Max Priority Queue, Min Priority Queue, Queue, ObjectDeque, ArrayDeque, Stack, and Trie. Each data structure is thoughtfully designed and implemented using TypeScript to provide efficient, reliable, and easy-to-use solutions for your programming needs. Whether you're optimizing algorithms, managing data, or enhancing performance, our TypeScript Data Structure Library is your go-to resource. Elevate your coding experience with these fundamental building blocks for software development.",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
7
7
  "build": "rm -rf dist && npx tsc",
8
8
  "test": "jest",
9
+ "update:test-deps": "npm i avl-tree-typed binary-tree-typed bst-typed deque-typed directed-graph-typed doubly-linked-list-typed graph-typed heap-typed linked-list-typed max-heap-typed max-priority-queue-typed min-heap-typed min-priority-queue-typed priority-queue-typed singly-linked-list-typed stack-typed tree-multiset-typed trie-typed undirected-graph-typed --save-dev",
9
10
  "build:docs": "typedoc --out docs ./src",
10
11
  "deps:check": "dependency-cruiser src",
11
12
  "build:publish": "npm run test && npm run build && npm run build:docs && npm publish"
@@ -58,16 +59,32 @@
58
59
  "devDependencies": {
59
60
  "@types/jest": "^29.5.3",
60
61
  "@types/node": "^20.4.9",
62
+ "avl-tree-typed": "^1.19.7",
63
+ "binary-tree-typed": "^1.19.7",
64
+ "bst-typed": "^1.19.7",
61
65
  "dependency-cruiser": "^13.1.2",
66
+ "deque-typed": "^1.19.7",
67
+ "directed-graph-typed": "^1.19.7",
68
+ "doubly-linked-list-typed": "^1.19.7",
69
+ "graph-typed": "^1.19.7",
70
+ "heap-typed": "^1.19.7",
62
71
  "jest": "^29.6.2",
72
+ "linked-list-typed": "^1.19.7",
73
+ "max-heap-typed": "^1.19.7",
74
+ "max-priority-queue-typed": "^1.19.7",
75
+ "min-heap-typed": "^1.19.7",
76
+ "min-priority-queue-typed": "^1.19.7",
77
+ "priority-queue-typed": "^1.19.7",
78
+ "singly-linked-list-typed": "^1.19.7",
79
+ "stack-typed": "^1.19.7",
80
+ "tree-multiset-typed": "^1.19.7",
81
+ "trie-typed": "^1.19.7",
63
82
  "ts-jest": "^29.1.1",
64
83
  "typedoc": "^0.24.8",
65
- "typescript": "^4.9.5"
84
+ "typescript": "^4.9.5",
85
+ "undirected-graph-typed": "^1.19.7"
66
86
  },
67
87
  "dependencies": {
68
- "avl-tree-typed": "^1.19.6",
69
- "bst-typed": "^1.19.6",
70
- "heap-typed": "^1.19.6",
71
88
  "zod": "^3.22.2"
72
89
  }
73
90
  }