min-heap-typed 1.50.0 → 1.50.2

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 (67) hide show
  1. package/dist/data-structures/base/iterable-base.d.ts +114 -9
  2. package/dist/data-structures/base/iterable-base.js +143 -7
  3. package/dist/data-structures/binary-tree/avl-tree.d.ts +43 -46
  4. package/dist/data-structures/binary-tree/avl-tree.js +68 -71
  5. package/dist/data-structures/binary-tree/binary-tree.d.ts +244 -199
  6. package/dist/data-structures/binary-tree/binary-tree.js +484 -376
  7. package/dist/data-structures/binary-tree/bst.d.ts +54 -74
  8. package/dist/data-structures/binary-tree/bst.js +30 -71
  9. package/dist/data-structures/binary-tree/rb-tree.d.ts +78 -60
  10. package/dist/data-structures/binary-tree/rb-tree.js +84 -89
  11. package/dist/data-structures/binary-tree/tree-multimap.d.ts +37 -56
  12. package/dist/data-structures/binary-tree/tree-multimap.js +64 -85
  13. package/dist/data-structures/graph/abstract-graph.d.ts +1 -0
  14. package/dist/data-structures/graph/abstract-graph.js +3 -0
  15. package/dist/data-structures/graph/directed-graph.d.ts +14 -0
  16. package/dist/data-structures/graph/directed-graph.js +26 -0
  17. package/dist/data-structures/graph/map-graph.d.ts +8 -0
  18. package/dist/data-structures/graph/map-graph.js +14 -0
  19. package/dist/data-structures/graph/undirected-graph.d.ts +16 -0
  20. package/dist/data-structures/graph/undirected-graph.js +25 -0
  21. package/dist/data-structures/hash/hash-map.d.ts +121 -15
  22. package/dist/data-structures/hash/hash-map.js +160 -25
  23. package/dist/data-structures/heap/heap.d.ts +66 -6
  24. package/dist/data-structures/heap/heap.js +66 -6
  25. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +67 -50
  26. package/dist/data-structures/linked-list/doubly-linked-list.js +70 -64
  27. package/dist/data-structures/linked-list/singly-linked-list.d.ts +128 -103
  28. package/dist/data-structures/linked-list/singly-linked-list.js +130 -112
  29. package/dist/data-structures/linked-list/skip-linked-list.d.ts +63 -36
  30. package/dist/data-structures/linked-list/skip-linked-list.js +63 -36
  31. package/dist/data-structures/matrix/matrix.d.ts +35 -4
  32. package/dist/data-structures/matrix/matrix.js +50 -11
  33. package/dist/data-structures/queue/deque.d.ts +49 -19
  34. package/dist/data-structures/queue/deque.js +101 -47
  35. package/dist/data-structures/queue/queue.d.ts +39 -5
  36. package/dist/data-structures/queue/queue.js +47 -5
  37. package/dist/data-structures/stack/stack.d.ts +16 -0
  38. package/dist/data-structures/stack/stack.js +22 -0
  39. package/dist/data-structures/trie/trie.d.ts +38 -1
  40. package/dist/data-structures/trie/trie.js +41 -0
  41. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
  42. package/dist/types/data-structures/hash/hash-map.d.ts +4 -3
  43. package/dist/types/utils/utils.d.ts +1 -0
  44. package/package.json +2 -2
  45. package/src/data-structures/base/iterable-base.ts +172 -19
  46. package/src/data-structures/binary-tree/avl-tree.ts +97 -97
  47. package/src/data-structures/binary-tree/binary-tree.ts +674 -671
  48. package/src/data-structures/binary-tree/bst.ts +89 -131
  49. package/src/data-structures/binary-tree/rb-tree.ts +127 -155
  50. package/src/data-structures/binary-tree/tree-multimap.ts +96 -112
  51. package/src/data-structures/graph/abstract-graph.ts +4 -0
  52. package/src/data-structures/graph/directed-graph.ts +30 -0
  53. package/src/data-structures/graph/map-graph.ts +15 -0
  54. package/src/data-structures/graph/undirected-graph.ts +28 -0
  55. package/src/data-structures/hash/hash-map.ts +175 -34
  56. package/src/data-structures/heap/heap.ts +66 -6
  57. package/src/data-structures/linked-list/doubly-linked-list.ts +72 -66
  58. package/src/data-structures/linked-list/singly-linked-list.ts +132 -114
  59. package/src/data-structures/linked-list/skip-linked-list.ts +63 -37
  60. package/src/data-structures/matrix/matrix.ts +52 -12
  61. package/src/data-structures/queue/deque.ts +108 -49
  62. package/src/data-structures/queue/queue.ts +51 -5
  63. package/src/data-structures/stack/stack.ts +24 -0
  64. package/src/data-structures/trie/trie.ts +45 -1
  65. package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
  66. package/src/types/data-structures/hash/hash-map.ts +4 -3
  67. package/src/types/utils/utils.ts +2 -0
@@ -21,8 +21,8 @@ import { AVLTree, AVLTreeNode } from './avl-tree';
21
21
  export class TreeMultimapNode<
22
22
  K = any,
23
23
  V = any,
24
- N extends TreeMultimapNode<K, V, N> = TreeMultimapNodeNested<K, V>
25
- > extends AVLTreeNode<K, V, N> {
24
+ NODE extends TreeMultimapNode<K, V, NODE> = TreeMultimapNodeNested<K, V>
25
+ > extends AVLTreeNode<K, V, NODE> {
26
26
  count: number;
27
27
 
28
28
  /**
@@ -47,12 +47,12 @@ export class TreeMultimapNode<
47
47
  export class TreeMultimap<
48
48
  K = any,
49
49
  V = any,
50
- N extends TreeMultimapNode<K, V, N> = TreeMultimapNode<K, V, TreeMultimapNodeNested<K, V>>,
51
- TREE extends TreeMultimap<K, V, N, TREE> = TreeMultimap<K, V, N, TreeMultimapNested<K, V, N>>
50
+ NODE extends TreeMultimapNode<K, V, NODE> = TreeMultimapNode<K, V, TreeMultimapNodeNested<K, V>>,
51
+ TREE extends TreeMultimap<K, V, NODE, TREE> = TreeMultimap<K, V, NODE, TreeMultimapNested<K, V, NODE>>
52
52
  >
53
- extends AVLTree<K, V, N, TREE>
54
- implements IBinaryTree<K, V, N, TREE> {
55
- constructor(keysOrNodesOrEntries: Iterable<KeyOrNodeOrEntry<K, V, N>> = [], options?: TreeMultimapOptions<K>) {
53
+ extends AVLTree<K, V, NODE, TREE>
54
+ implements IBinaryTree<K, V, NODE, TREE> {
55
+ constructor(keysOrNodesOrEntries: Iterable<KeyOrNodeOrEntry<K, V, NODE>> = [], options?: TreeMultimapOptions<K>) {
56
56
  super([], options);
57
57
  if (keysOrNodesOrEntries) this.addMany(keysOrNodesOrEntries);
58
58
  }
@@ -70,17 +70,17 @@ export class TreeMultimap<
70
70
  * The function creates a new BSTNode with the given key, value, and count.
71
71
  * @param {K} key - The key parameter is the unique identifier for the binary tree node. It is used to
72
72
  * distinguish one node from another in the tree.
73
- * @param {N} value - The `value` parameter represents the value that will be stored in the binary search tree node.
73
+ * @param {NODE} value - The `value` parameter represents the value that will be stored in the binary search tree node.
74
74
  * @param {number} [count] - The "count" parameter is an optional parameter of type number. It represents the number of
75
75
  * occurrences of the value in the binary search tree node. If not provided, the count will default to 1.
76
76
  * @returns A new instance of the BSTNode class with the specified key, value, and count (if provided).
77
77
  */
78
- override createNode(key: K, value?: V, count?: number): N {
79
- return new TreeMultimapNode(key, value, count) as N;
78
+ override createNode(key: K, value?: V, count?: number): NODE {
79
+ return new TreeMultimapNode(key, value, count) as NODE;
80
80
  }
81
81
 
82
82
  override createTree(options?: TreeMultimapOptions<K>): TREE {
83
- return new TreeMultimap<K, V, N, TREE>([], {
83
+ return new TreeMultimap<K, V, NODE, TREE>([], {
84
84
  iterationType: this.iterationType,
85
85
  variant: this.variant,
86
86
  ...options
@@ -88,18 +88,22 @@ export class TreeMultimap<
88
88
  }
89
89
 
90
90
  /**
91
- * The function `exemplarToNode` converts an keyOrNodeOrEntry object into a node object.
92
- * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter is of type `KeyOrNodeOrEntry<K, V, N>`, which means it
91
+ * The function `keyValueOrEntryToNode` converts an keyOrNodeOrEntry object into a node object.
92
+ * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter is of type `KeyOrNodeOrEntry<K, V, NODE>`, which means it
93
93
  * can be one of the following:
94
94
  * @param {V} [value] - The `value` parameter is an optional argument that represents the value
95
95
  * associated with the node. It is of type `V`, which can be any data type. If no value is provided,
96
96
  * it defaults to `undefined`.
97
97
  * @param [count=1] - The `count` parameter is an optional parameter that specifies the number of
98
98
  * times the value should be added to the node. If not provided, it defaults to 1.
99
- * @returns a node of type `N` or `undefined`.
99
+ * @returns a node of type `NODE` or `undefined`.
100
100
  */
101
- override exemplarToNode(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, N>, value?: V, count = 1): N | undefined {
102
- let node: N | undefined;
101
+ override keyValueOrEntryToNode(
102
+ keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>,
103
+ value?: V,
104
+ count = 1
105
+ ): NODE | undefined {
106
+ let node: NODE | undefined;
103
107
  if (keyOrNodeOrEntry === undefined || keyOrNodeOrEntry === null) {
104
108
  return;
105
109
  } else if (this.isNode(keyOrNodeOrEntry)) {
@@ -121,18 +125,17 @@ export class TreeMultimap<
121
125
 
122
126
  /**
123
127
  * The function checks if an keyOrNodeOrEntry is an instance of the TreeMultimapNode class.
124
- * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter is of type `KeyOrNodeOrEntry<K, V, N>`.
128
+ * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter is of type `KeyOrNodeOrEntry<K, V, NODE>`.
125
129
  * @returns a boolean value indicating whether the keyOrNodeOrEntry is an instance of the TreeMultimapNode
126
130
  * class.
127
131
  */
128
- override isNode(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, N>): keyOrNodeOrEntry is N {
132
+ override isNode(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>): keyOrNodeOrEntry is NODE {
129
133
  return keyOrNodeOrEntry instanceof TreeMultimapNode;
130
134
  }
131
135
 
132
136
  /**
133
137
  * Time Complexity: O(log n)
134
138
  * Space Complexity: O(1)
135
- * logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity. constant space, as it doesn't use additional data structures that scale with input size.
136
139
  */
137
140
 
138
141
  /**
@@ -151,8 +154,8 @@ export class TreeMultimap<
151
154
  * @returns The method is returning either the newly inserted node or `undefined` if the insertion
152
155
  * was not successful.
153
156
  */
154
- override add(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, N>, value?: V, count = 1): boolean {
155
- const newNode = this.exemplarToNode(keyOrNodeOrEntry, value, count);
157
+ override add(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>, value?: V, count = 1): boolean {
158
+ const newNode = this.keyValueOrEntryToNode(keyOrNodeOrEntry, value, count);
156
159
  if (newNode === undefined) return false;
157
160
 
158
161
  const orgNodeCount = newNode?.count || 0;
@@ -164,88 +167,12 @@ export class TreeMultimap<
164
167
  }
165
168
 
166
169
  /**
167
- * Time Complexity: O(k log n)
168
- * Space Complexity: O(1)
169
- * logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity. constant space, as it doesn't use additional data structures that scale with input size.
170
- */
171
-
172
- /**
173
- * Time Complexity: O(k log n)
174
- * Space Complexity: O(1)
175
- *
176
- * The function overrides the addMany method to add multiple keys, nodes, or entries to a data
177
- * structure.
178
- * @param keysOrNodesOrEntries - The parameter `keysOrNodesOrEntries` is an iterable that can contain
179
- * either keys, nodes, or entries.
180
- * @returns The method is returning an array of type `N | undefined`.
181
- */
182
- override addMany(keysOrNodesOrEntries: Iterable<KeyOrNodeOrEntry<K, V, N>>): boolean[] {
183
- return super.addMany(keysOrNodesOrEntries);
184
- }
185
-
186
- /**
187
- * Time Complexity: O(n log n)
188
- * Space Complexity: O(n)
189
- * logarithmic time for each insertion, where "n" is the number of nodes in the tree. This is because the method calls the add method for each node. linear space, as it creates an array to store the sorted nodes.
190
- */
191
-
192
- /**
193
- * Time Complexity: O(n log n)
194
- * Space Complexity: O(n)
195
- *
196
- * The `perfectlyBalance` function takes a sorted array of nodes and builds a balanced binary search
197
- * tree using either a recursive or iterative approach.
198
- * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
199
- * type of iteration to use when building the balanced binary search tree. It can have two possible
200
- * values:
201
- * @returns a boolean value.
202
- */
203
- override perfectlyBalance(iterationType = this.iterationType): boolean {
204
- const sorted = this.dfs(node => node, 'in'),
205
- n = sorted.length;
206
- if (sorted.length < 1) return false;
207
-
208
- this.clear();
209
-
210
- if (iterationType === IterationType.RECURSIVE) {
211
- const buildBalanceBST = (l: number, r: number) => {
212
- if (l > r) return;
213
- const m = l + Math.floor((r - l) / 2);
214
- const midNode = sorted[m];
215
- this.add(midNode.key, midNode.value, midNode.count);
216
- buildBalanceBST(l, m - 1);
217
- buildBalanceBST(m + 1, r);
218
- };
219
-
220
- buildBalanceBST(0, n - 1);
221
- return true;
222
- } else {
223
- const stack: [[number, number]] = [[0, n - 1]];
224
- while (stack.length > 0) {
225
- const popped = stack.pop();
226
- if (popped) {
227
- const [l, r] = popped;
228
- if (l <= r) {
229
- const m = l + Math.floor((r - l) / 2);
230
- const midNode = sorted[m];
231
- this.add(midNode.key, midNode.value, midNode.count);
232
- stack.push([m + 1, r]);
233
- stack.push([l, m - 1]);
234
- }
235
- }
236
- }
237
- return true;
238
- }
239
- }
240
-
241
- /**
242
- * Time Complexity: O(k log n)
170
+ * Time Complexity: O(log n)
243
171
  * Space Complexity: O(1)
244
- * logarithmic time for each insertion, where "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted. This is because the method iterates through the keys and calls the add method for each. constant space, as it doesn't use additional data structures that scale with input size.
245
172
  */
246
173
 
247
174
  /**
248
- * Time Complexity: O(k log n)
175
+ * Time Complexity: O(log n)
249
176
  * Space Complexity: O(1)
250
177
  *
251
178
  * The `delete` function in TypeScript is used to remove a node from a binary tree, taking into
@@ -261,22 +188,22 @@ export class TreeMultimap<
261
188
  * being deleted. If set to true, the count of the node will not be considered and the node will be
262
189
  * deleted regardless of its count. If set to false (default), the count of the node will be
263
190
  * decremented by 1 and
264
- * @returns an array of `BinaryTreeDeleteResult<N>`.
191
+ * @returns an array of `BinaryTreeDeleteResult<NODE>`.
265
192
  */
266
- override delete<C extends BTNCallback<N>>(
193
+ override delete<C extends BTNCallback<NODE>>(
267
194
  identifier: ReturnType<C>,
268
195
  callback: C = this._defaultOneParamCallback as C,
269
196
  ignoreCount = false
270
- ): BinaryTreeDeleteResult<N>[] {
271
- const deletedResult: BinaryTreeDeleteResult<N>[] = [];
197
+ ): BinaryTreeDeleteResult<NODE>[] {
198
+ const deletedResult: BinaryTreeDeleteResult<NODE>[] = [];
272
199
  if (!this.root) return deletedResult;
273
200
 
274
- const curr: N | undefined = this.getNode(identifier, callback) ?? undefined;
201
+ const curr: NODE | undefined = this.getNode(identifier, callback) ?? undefined;
275
202
  if (!curr) return deletedResult;
276
203
 
277
- const parent: N | undefined = curr?.parent ? curr.parent : undefined;
278
- let needBalanced: N | undefined = undefined,
279
- orgCurrent: N | undefined = curr;
204
+ const parent: NODE | undefined = curr?.parent ? curr.parent : undefined;
205
+ let needBalanced: NODE | undefined = undefined,
206
+ orgCurrent: NODE | undefined = curr;
280
207
 
281
208
  if (curr.count > 1 && !ignoreCount) {
282
209
  curr.count--;
@@ -339,6 +266,60 @@ export class TreeMultimap<
339
266
  this._count = 0;
340
267
  }
341
268
 
269
+ /**
270
+ * Time Complexity: O(n log n)
271
+ * Space Complexity: O(log n)
272
+ */
273
+
274
+ /**
275
+ * Time Complexity: O(n log n)
276
+ * Space Complexity: O(log n)
277
+ *
278
+ * The `perfectlyBalance` function takes a sorted array of nodes and builds a balanced binary search
279
+ * tree using either a recursive or iterative approach.
280
+ * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
281
+ * type of iteration to use when building the balanced binary search tree. It can have two possible
282
+ * values:
283
+ * @returns a boolean value.
284
+ */
285
+ override perfectlyBalance(iterationType = this.iterationType): boolean {
286
+ const sorted = this.dfs(node => node, 'in'),
287
+ n = sorted.length;
288
+ if (sorted.length < 1) return false;
289
+
290
+ this.clear();
291
+
292
+ if (iterationType === IterationType.RECURSIVE) {
293
+ const buildBalanceBST = (l: number, r: number) => {
294
+ if (l > r) return;
295
+ const m = l + Math.floor((r - l) / 2);
296
+ const midNode = sorted[m];
297
+ this.add(midNode.key, midNode.value, midNode.count);
298
+ buildBalanceBST(l, m - 1);
299
+ buildBalanceBST(m + 1, r);
300
+ };
301
+
302
+ buildBalanceBST(0, n - 1);
303
+ return true;
304
+ } else {
305
+ const stack: [[number, number]] = [[0, n - 1]];
306
+ while (stack.length > 0) {
307
+ const popped = stack.pop();
308
+ if (popped) {
309
+ const [l, r] = popped;
310
+ if (l <= r) {
311
+ const m = l + Math.floor((r - l) / 2);
312
+ const midNode = sorted[m];
313
+ this.add(midNode.key, midNode.value, midNode.count);
314
+ stack.push([m + 1, r]);
315
+ stack.push([l, m - 1]);
316
+ }
317
+ }
318
+ }
319
+ return true;
320
+ }
321
+ }
322
+
342
323
  /**
343
324
  * Time complexity: O(n)
344
325
  * Space complexity: O(n)
@@ -359,14 +340,17 @@ export class TreeMultimap<
359
340
 
360
341
  /**
361
342
  * The `_swapProperties` function swaps the key, value, count, and height properties between two nodes.
362
- * @param {K | N | undefined} srcNode - The `srcNode` parameter represents the source node from
363
- * which the values will be swapped. It can be of type `K`, `N`, or `undefined`.
364
- * @param {K | N | undefined} destNode - The `destNode` parameter represents the destination
343
+ * @param {K | NODE | undefined} srcNode - The `srcNode` parameter represents the source node from
344
+ * which the values will be swapped. It can be of type `K`, `NODE`, or `undefined`.
345
+ * @param {K | NODE | undefined} destNode - The `destNode` parameter represents the destination
365
346
  * node where the values from the source node will be swapped to.
366
347
  * @returns either the `destNode` object if both `srcNode` and `destNode` are defined, or `undefined`
367
348
  * if either `srcNode` or `destNode` is undefined.
368
349
  */
369
- protected override _swapProperties(srcNode: BSTNKeyOrNode<K, N>, destNode: BSTNKeyOrNode<K, N>): N | undefined {
350
+ protected override _swapProperties(
351
+ srcNode: BSTNKeyOrNode<K, NODE>,
352
+ destNode: BSTNKeyOrNode<K, NODE>
353
+ ): NODE | undefined {
370
354
  srcNode = this.ensureNode(srcNode);
371
355
  destNode = this.ensureNode(destNode);
372
356
  if (srcNode && destNode) {
@@ -391,7 +375,7 @@ export class TreeMultimap<
391
375
  return undefined;
392
376
  }
393
377
 
394
- protected _replaceNode(oldNode: N, newNode: N): N {
378
+ protected _replaceNode(oldNode: NODE, newNode: NODE): NODE {
395
379
  newNode.count = oldNode.count + newNode.count;
396
380
  return super._replaceNode(oldNode, newNode);
397
381
  }
@@ -78,6 +78,10 @@ export abstract class AbstractGraph<
78
78
  return this._vertexMap;
79
79
  }
80
80
 
81
+ set vertexMap(v: Map<VertexKey, VO>) {
82
+ this._vertexMap = v;
83
+ }
84
+
81
85
  /**
82
86
  * In TypeScript, a subclass inherits the interface implementation of its parent class, without needing to implement the same interface again in the subclass. This behavior differs from Java's approach. In Java, if a parent class implements an interface, the subclass needs to explicitly implement the same interface, even if the parent class has already implemented it.
83
87
  * This means that using abstract methods in the parent class cannot constrain the grandchild classes. Defining methods within an interface also cannot constrain the descendant classes. When inheriting from this class, developers need to be aware that this method needs to be overridden.
@@ -66,12 +66,20 @@ export class DirectedGraph<
66
66
  return this._outEdgeMap;
67
67
  }
68
68
 
69
+ set outEdgeMap(v: Map<VO, EO[]>) {
70
+ this._outEdgeMap = v;
71
+ }
72
+
69
73
  protected _inEdgeMap: Map<VO, EO[]> = new Map<VO, EO[]>();
70
74
 
71
75
  get inEdgeMap(): Map<VO, EO[]> {
72
76
  return this._inEdgeMap;
73
77
  }
74
78
 
79
+ set inEdgeMap(v: Map<VO, EO[]>) {
80
+ this._inEdgeMap = v;
81
+ }
82
+
75
83
  /**
76
84
  * In TypeScript, a subclass inherits the interface implementation of its parent class, without needing to implement the same interface again in the subclass. This behavior differs from Java's approach. In Java, if a parent class implements an interface, the subclass needs to explicitly implement the same interface, even if the parent class has already implemented it.
77
85
  * This means that using abstract methods in the parent class cannot constrain the grandchild classes. Defining methods within an interface also cannot constrain the descendant classes. When inheriting from this class, developers need to be aware that this method needs to be overridden.
@@ -599,6 +607,28 @@ export class DirectedGraph<
599
607
  }
600
608
  }
601
609
 
610
+ /**
611
+ * The isEmpty function checks if the graph is empty.
612
+ *
613
+ * @return A boolean value
614
+ */
615
+ isEmpty(): boolean {
616
+ return this.vertexMap.size === 0 && this.inEdgeMap.size === 0 && this.outEdgeMap.size === 0;
617
+ }
618
+
619
+ /**
620
+ * The clone function creates a new DirectedGraph object with the same vertices and edges as the original.
621
+ *
622
+ * @return A new instance of the directedgraph class
623
+ */
624
+ clone(): DirectedGraph<V, E, VO, EO> {
625
+ const cloned = new DirectedGraph<V, E, VO, EO>();
626
+ cloned.vertexMap = new Map<VertexKey, VO>(this.vertexMap);
627
+ cloned.inEdgeMap = new Map<VO, EO[]>(this.inEdgeMap);
628
+ cloned.outEdgeMap = new Map<VO, EO[]>(this.outEdgeMap);
629
+ return cloned;
630
+ }
631
+
602
632
  /**
603
633
  * Time Complexity: O(1)
604
634
  * Space Complexity: O(1)
@@ -108,4 +108,19 @@ export class MapGraph<
108
108
  override createEdge(src: VertexKey, dest: VertexKey, weight?: number, value?: E): EO {
109
109
  return new MapEdge(src, dest, weight, value) as EO;
110
110
  }
111
+
112
+ /**
113
+ * The override function is used to override the default behavior of a function.
114
+ * In this case, we are overriding the clone() function from Graph&lt;V, E&gt;.
115
+ * The clone() function returns a new graph that is an exact copy of the original graph.
116
+ *
117
+ * @return A mapgraph&lt;v, e, vo, eo&gt;
118
+ */
119
+ override clone(): MapGraph<V, E, VO, EO> {
120
+ const cloned = new MapGraph<V, E, VO, EO>(this.originCoord, this.bottomRight);
121
+ cloned.vertexMap = new Map<VertexKey, VO>(this.vertexMap);
122
+ cloned.inEdgeMap = new Map<VO, EO[]>(this.inEdgeMap);
123
+ cloned.outEdgeMap = new Map<VO, EO[]>(this.outEdgeMap);
124
+ return cloned;
125
+ }
111
126
  }
@@ -64,6 +64,10 @@ export class UndirectedGraph<
64
64
  return this._edgeMap;
65
65
  }
66
66
 
67
+ set edgeMap(v: Map<VO, EO[]>) {
68
+ this._edgeMap = v;
69
+ }
70
+
67
71
  /**
68
72
  * The function creates a new vertex with an optional value and returns it.
69
73
  * @param {VertexKey} key - The `key` parameter is the unique identifier for the vertex. It is used to distinguish one
@@ -365,6 +369,30 @@ export class UndirectedGraph<
365
369
  }
366
370
  }
367
371
 
372
+ /**
373
+ * The isEmpty function checks if the graph is empty.
374
+ * @return True if the graph is empty and false otherwise
375
+ */
376
+ isEmpty(): boolean {
377
+ return this.vertexMap.size === 0 && this.edgeMap.size === 0;
378
+ }
379
+
380
+ /**
381
+ * The clone function creates a new UndirectedGraph object and copies the
382
+ * vertexMap and edgeMap from this graph to the new one. This is done by
383
+ * assigning each of these properties to their respective counterparts in the
384
+ * cloned graph. The clone function returns a reference to this newly created,
385
+ * cloned UndirectedGraph object.
386
+ *
387
+ * @return A new instance of the undirectedgraph class
388
+ */
389
+ clone(): UndirectedGraph<V, E, VO, EO> {
390
+ const cloned = new UndirectedGraph<V, E, VO, EO>();
391
+ cloned.vertexMap = new Map<VertexKey, VO>(this.vertexMap);
392
+ cloned.edgeMap = new Map<VO, EO[]>(this.edgeMap);
393
+ return cloned;
394
+ }
395
+
368
396
  /**
369
397
  * Time Complexity: O(1)
370
398
  * Space Complexity: O(1)