directed-graph-typed 1.48.0 → 1.49.0
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.
- package/dist/data-structures/base/index.d.ts +1 -0
- package/dist/data-structures/base/index.js +17 -0
- package/dist/data-structures/base/iterable-base.d.ts +232 -0
- package/dist/data-structures/base/iterable-base.js +312 -0
- package/dist/data-structures/binary-tree/avl-tree.d.ts +28 -19
- package/dist/data-structures/binary-tree/avl-tree.js +22 -11
- package/dist/data-structures/binary-tree/binary-tree.d.ts +158 -152
- package/dist/data-structures/binary-tree/binary-tree.js +241 -215
- package/dist/data-structures/binary-tree/bst.d.ts +64 -48
- package/dist/data-structures/binary-tree/bst.js +94 -65
- package/dist/data-structures/binary-tree/rb-tree.d.ts +39 -39
- package/dist/data-structures/binary-tree/rb-tree.js +42 -49
- package/dist/data-structures/binary-tree/tree-multimap.d.ts +60 -34
- package/dist/data-structures/binary-tree/tree-multimap.js +59 -27
- package/dist/data-structures/graph/abstract-graph.d.ts +92 -53
- package/dist/data-structures/graph/abstract-graph.js +130 -103
- package/dist/data-structures/graph/directed-graph.d.ts +70 -52
- package/dist/data-structures/graph/directed-graph.js +111 -65
- package/dist/data-structures/graph/map-graph.d.ts +5 -5
- package/dist/data-structures/graph/map-graph.js +8 -8
- package/dist/data-structures/graph/undirected-graph.d.ts +51 -32
- package/dist/data-structures/graph/undirected-graph.js +117 -54
- package/dist/data-structures/hash/hash-map.d.ts +160 -44
- package/dist/data-structures/hash/hash-map.js +314 -82
- package/dist/data-structures/heap/heap.d.ts +50 -7
- package/dist/data-structures/heap/heap.js +60 -30
- package/dist/data-structures/index.d.ts +1 -0
- package/dist/data-structures/index.js +1 -0
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +42 -55
- package/dist/data-structures/linked-list/doubly-linked-list.js +50 -77
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +36 -55
- package/dist/data-structures/linked-list/singly-linked-list.js +44 -77
- package/dist/data-structures/queue/deque.d.ts +35 -167
- package/dist/data-structures/queue/deque.js +43 -249
- package/dist/data-structures/queue/queue.d.ts +49 -48
- package/dist/data-structures/queue/queue.js +69 -82
- package/dist/data-structures/stack/stack.d.ts +43 -10
- package/dist/data-structures/stack/stack.js +50 -31
- package/dist/data-structures/trie/trie.d.ts +41 -6
- package/dist/data-structures/trie/trie.js +53 -32
- package/dist/interfaces/binary-tree.d.ts +6 -6
- package/dist/types/common.d.ts +11 -8
- package/dist/types/common.js +6 -1
- package/dist/types/data-structures/base/base.d.ts +5 -0
- package/dist/types/data-structures/base/base.js +2 -0
- package/dist/types/data-structures/base/index.d.ts +1 -0
- package/dist/types/data-structures/base/index.js +17 -0
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +3 -3
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +4 -4
- package/dist/types/data-structures/binary-tree/bst.d.ts +6 -6
- package/dist/types/data-structures/binary-tree/rb-tree.d.ts +3 -3
- package/dist/types/data-structures/binary-tree/tree-multimap.d.ts +3 -3
- package/dist/types/data-structures/hash/hash-map.d.ts +4 -0
- package/dist/types/data-structures/index.d.ts +1 -0
- package/dist/types/data-structures/index.js +1 -0
- package/package.json +2 -2
- package/src/data-structures/base/index.ts +1 -0
- package/src/data-structures/base/iterable-base.ts +329 -0
- package/src/data-structures/binary-tree/avl-tree.ts +37 -25
- package/src/data-structures/binary-tree/binary-tree.ts +336 -296
- package/src/data-structures/binary-tree/bst.ts +135 -89
- package/src/data-structures/binary-tree/rb-tree.ts +60 -69
- package/src/data-structures/binary-tree/tree-multimap.ts +86 -49
- package/src/data-structures/graph/abstract-graph.ts +136 -104
- package/src/data-structures/graph/directed-graph.ts +114 -65
- package/src/data-structures/graph/map-graph.ts +8 -8
- package/src/data-structures/graph/undirected-graph.ts +124 -56
- package/src/data-structures/hash/hash-map.ts +335 -84
- package/src/data-structures/heap/heap.ts +63 -36
- package/src/data-structures/index.ts +1 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +54 -83
- package/src/data-structures/linked-list/singly-linked-list.ts +49 -84
- package/src/data-structures/queue/deque.ts +43 -275
- package/src/data-structures/queue/queue.ts +71 -86
- package/src/data-structures/stack/stack.ts +53 -34
- package/src/data-structures/trie/trie.ts +58 -35
- package/src/interfaces/binary-tree.ts +5 -6
- package/src/types/common.ts +11 -8
- package/src/types/data-structures/base/base.ts +6 -0
- package/src/types/data-structures/base/index.ts +1 -0
- package/src/types/data-structures/binary-tree/avl-tree.ts +3 -3
- package/src/types/data-structures/binary-tree/binary-tree.ts +6 -5
- package/src/types/data-structures/binary-tree/bst.ts +6 -6
- package/src/types/data-structures/binary-tree/rb-tree.ts +3 -3
- package/src/types/data-structures/binary-tree/tree-multimap.ts +3 -3
- package/src/types/data-structures/hash/hash-map.ts +2 -0
- package/src/types/data-structures/heap/heap.ts +1 -1
- package/src/types/data-structures/index.ts +1 -0
- package/src/types/data-structures/priority-queue/priority-queue.ts +1 -1
|
@@ -10,8 +10,8 @@ import {
|
|
|
10
10
|
BiTreeDeleteResult,
|
|
11
11
|
BSTNodeKeyOrNode,
|
|
12
12
|
BTNCallback,
|
|
13
|
-
BTNKey,
|
|
14
13
|
BTNodeExemplar,
|
|
14
|
+
BTNodeKeyOrNode,
|
|
15
15
|
IterationType,
|
|
16
16
|
RBTNColor,
|
|
17
17
|
RBTreeOptions,
|
|
@@ -22,13 +22,13 @@ import { BST, BSTNode } from './bst';
|
|
|
22
22
|
import { IBinaryTree } from '../../interfaces';
|
|
23
23
|
import { BinaryTreeNode } from './binary-tree';
|
|
24
24
|
|
|
25
|
-
export class RedBlackTreeNode<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTreeNodeNested<V>> extends BSTNode<
|
|
26
|
-
V,
|
|
25
|
+
export class RedBlackTreeNode<K = any, V = any, N extends RedBlackTreeNode<K, V, N> = RedBlackTreeNodeNested<K, V>> extends BSTNode<
|
|
26
|
+
K, V,
|
|
27
27
|
N
|
|
28
28
|
> {
|
|
29
29
|
color: RBTNColor;
|
|
30
30
|
|
|
31
|
-
constructor(key:
|
|
31
|
+
constructor(key: K, value?: V, color: RBTNColor = RBTNColor.BLACK) {
|
|
32
32
|
super(key, value);
|
|
33
33
|
this.color = color;
|
|
34
34
|
}
|
|
@@ -41,15 +41,15 @@ export class RedBlackTreeNode<V = any, N extends RedBlackTreeNode<V, N> = RedBla
|
|
|
41
41
|
* 4. Red nodes must have black children.
|
|
42
42
|
* 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.
|
|
43
43
|
*/
|
|
44
|
-
export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTreeNode<V, RedBlackTreeNodeNested<V>>, TREE extends RedBlackTree<V, N, TREE> = RedBlackTree<V, N, RedBlackTreeNested<V, N>>>
|
|
45
|
-
extends BST<V, N, TREE>
|
|
46
|
-
implements IBinaryTree<V, N, TREE> {
|
|
47
|
-
Sentinel: N = new RedBlackTreeNode<V>(NaN) as unknown as N;
|
|
44
|
+
export class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>, TREE extends RedBlackTree<K, V, N, TREE> = RedBlackTree<K, V, N, RedBlackTreeNested<K, V, N>>>
|
|
45
|
+
extends BST<K, V, N, TREE>
|
|
46
|
+
implements IBinaryTree<K, V, N, TREE> {
|
|
47
|
+
Sentinel: N = new RedBlackTreeNode<K, V>(NaN as K) as unknown as N;
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
50
|
* This is the constructor function for a Red-Black Tree data structure in TypeScript, which
|
|
51
51
|
* initializes the tree with optional elements and options.
|
|
52
|
-
* @param [elements] - The `elements` parameter is an optional iterable of `BTNodeExemplar<V, N>`
|
|
52
|
+
* @param [elements] - The `elements` parameter is an optional iterable of `BTNodeExemplar<K, V, N>`
|
|
53
53
|
* objects. It represents the initial elements that will be added to the RBTree during its
|
|
54
54
|
* construction. If this parameter is provided, the `addMany` method is called to add all the
|
|
55
55
|
* elements to the
|
|
@@ -57,7 +57,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
57
57
|
* behavior of the RBTree. It is of type `Partial<RBTreeOptions>`, which means that you can provide
|
|
58
58
|
* only a subset of the properties defined in the `RBTreeOptions` interface.
|
|
59
59
|
*/
|
|
60
|
-
constructor(elements?: Iterable<BTNodeExemplar<V, N>>, options?: Partial<RBTreeOptions
|
|
60
|
+
constructor(elements?: Iterable<BTNodeExemplar<K, V, N>>, options?: Partial<RBTreeOptions<K>>) {
|
|
61
61
|
super([], options);
|
|
62
62
|
|
|
63
63
|
this._root = this.Sentinel;
|
|
@@ -78,7 +78,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
80
|
* The function creates a new Red-Black Tree node with the specified key, value, and color.
|
|
81
|
-
* @param {
|
|
81
|
+
* @param {K} key - The key parameter is the key value associated with the node. It is used to
|
|
82
82
|
* identify and compare nodes in the Red-Black Tree.
|
|
83
83
|
* @param {V} [value] - The `value` parameter is an optional parameter that represents the value
|
|
84
84
|
* associated with the node. It is of type `V`, which is a generic type that can be replaced with any
|
|
@@ -88,8 +88,8 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
88
88
|
* @returns The method is returning a new instance of a RedBlackTreeNode with the specified key,
|
|
89
89
|
* value, and color.
|
|
90
90
|
*/
|
|
91
|
-
override createNode(key:
|
|
92
|
-
return new RedBlackTreeNode<V, N>(key, value, color) as N;
|
|
91
|
+
override createNode(key: K, value?: V, color: RBTNColor = RBTNColor.BLACK): N {
|
|
92
|
+
return new RedBlackTreeNode<K, V, N>(key, value, color) as N;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
/**
|
|
@@ -99,32 +99,42 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
99
99
|
* class.
|
|
100
100
|
* @returns a new instance of a RedBlackTree object.
|
|
101
101
|
*/
|
|
102
|
-
override createTree(options?: RBTreeOptions): TREE {
|
|
103
|
-
return new RedBlackTree<V, N, TREE>([], {
|
|
102
|
+
override createTree(options?: RBTreeOptions<K>): TREE {
|
|
103
|
+
return new RedBlackTree<K, V, N, TREE>([], {
|
|
104
104
|
iterationType: this.iterationType,
|
|
105
|
-
|
|
105
|
+
variant: this.variant, ...options
|
|
106
106
|
}) as TREE;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
/**
|
|
110
110
|
* The function checks if an exemplar is an instance of the RedBlackTreeNode class.
|
|
111
|
-
* @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<V, N>`.
|
|
111
|
+
* @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<K, V, N>`.
|
|
112
112
|
* @returns a boolean value indicating whether the exemplar is an instance of the RedBlackTreeNode
|
|
113
113
|
* class.
|
|
114
114
|
*/
|
|
115
|
-
override isNode(exemplar: BTNodeExemplar<V, N>): exemplar is N {
|
|
115
|
+
override isNode(exemplar: BTNodeExemplar<K, V, N>): exemplar is N {
|
|
116
116
|
return exemplar instanceof RedBlackTreeNode;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
/**
|
|
120
|
-
* The function
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* that is not a valid exemplar.
|
|
125
|
-
* @returns a variable `node` which is of type `N | undefined`.
|
|
120
|
+
* The function "isNotNodeInstance" checks if a potential key is a K.
|
|
121
|
+
* @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any
|
|
122
|
+
* data type.
|
|
123
|
+
* @returns a boolean value indicating whether the potentialKey is of type number or not.
|
|
126
124
|
*/
|
|
127
|
-
override
|
|
125
|
+
override isNotNodeInstance(potentialKey: BTNodeKeyOrNode<K, N>): potentialKey is K {
|
|
126
|
+
return !(potentialKey instanceof RedBlackTreeNode)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The function `exemplarToNode` takes an exemplar and converts it into a node object if possible.
|
|
131
|
+
* @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<K, V, N>`, where:
|
|
132
|
+
* @param {V} [value] - The `value` parameter is an optional value that can be passed to the
|
|
133
|
+
* `exemplarToNode` function. It represents the value associated with the exemplar node. If a value
|
|
134
|
+
* is provided, it will be used when creating the new node. If no value is provided, the new node
|
|
135
|
+
* @returns a node of type N or undefined.
|
|
136
|
+
*/
|
|
137
|
+
override exemplarToNode(exemplar: BTNodeExemplar<K, V, N>, value?: V): N | undefined {
|
|
128
138
|
let node: N | undefined;
|
|
129
139
|
|
|
130
140
|
if (exemplar === null || exemplar === undefined) {
|
|
@@ -138,8 +148,8 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
138
148
|
} else {
|
|
139
149
|
node = this.createNode(key, value, RBTNColor.RED);
|
|
140
150
|
}
|
|
141
|
-
} else if (this.
|
|
142
|
-
node = this.createNode(exemplar,
|
|
151
|
+
} else if (this.isNotNodeInstance(exemplar)) {
|
|
152
|
+
node = this.createNode(exemplar, value, RBTNColor.RED);
|
|
143
153
|
} else {
|
|
144
154
|
return;
|
|
145
155
|
}
|
|
@@ -152,13 +162,19 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
152
162
|
*/
|
|
153
163
|
|
|
154
164
|
/**
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
* `
|
|
165
|
+
* Time Complexity: O(log n) on average (where n is the number of nodes in the tree)
|
|
166
|
+
* Space Complexity: O(1)
|
|
167
|
+
*
|
|
168
|
+
* The `add` function adds a new node to a binary search tree and performs necessary rotations and
|
|
169
|
+
* color changes to maintain the red-black tree properties.
|
|
170
|
+
* @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be either a key, a node, or an
|
|
171
|
+
* entry.
|
|
172
|
+
* @param {V} [value] - The `value` parameter represents the value associated with the key that is
|
|
173
|
+
* being added to the binary search tree.
|
|
174
|
+
* @returns The method `add` returns either the newly added node (`N`) or `undefined`.
|
|
159
175
|
*/
|
|
160
|
-
override add(keyOrNodeOrEntry: BTNodeExemplar<V, N
|
|
161
|
-
const newNode = this.exemplarToNode(keyOrNodeOrEntry);
|
|
176
|
+
override add(keyOrNodeOrEntry: BTNodeExemplar<K, V, N>, value?: V): N | undefined {
|
|
177
|
+
const newNode = this.exemplarToNode(keyOrNodeOrEntry, value);
|
|
162
178
|
if (newNode === undefined) return;
|
|
163
179
|
|
|
164
180
|
newNode.left = this.Sentinel;
|
|
@@ -295,11 +311,12 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
295
311
|
*/
|
|
296
312
|
|
|
297
313
|
override isRealNode(node: N | undefined): node is N {
|
|
298
|
-
|
|
314
|
+
if (node === this.Sentinel || node === undefined) return false;
|
|
315
|
+
return node instanceof RedBlackTreeNode;
|
|
299
316
|
}
|
|
300
317
|
|
|
301
|
-
getNode<C extends BTNCallback<N,
|
|
302
|
-
identifier:
|
|
318
|
+
getNode<C extends BTNCallback<N, K>>(
|
|
319
|
+
identifier: K,
|
|
303
320
|
callback?: C,
|
|
304
321
|
beginRoot?: N | undefined,
|
|
305
322
|
iterationType?: IterationType
|
|
@@ -337,7 +354,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
337
354
|
* @param {C} callback - The `callback` parameter is a function that will be called for each node in
|
|
338
355
|
* the binary tree. It is used to determine if a node matches the given identifier. The `callback`
|
|
339
356
|
* function should take a single parameter of type `N` (the type of the nodes in the binary tree) and
|
|
340
|
-
* @param {
|
|
357
|
+
* @param {K | N | undefined} beginRoot - The `beginRoot` parameter is the starting point for
|
|
341
358
|
* searching for a node in a binary tree. It can be either a key value or a node object. If it is not
|
|
342
359
|
* provided, the search will start from the root of the binary tree.
|
|
343
360
|
* @param iterationType - The `iterationType` parameter is a variable that determines the type of
|
|
@@ -348,7 +365,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
348
365
|
getNode<C extends BTNCallback<N>>(
|
|
349
366
|
identifier: ReturnType<C> | undefined,
|
|
350
367
|
callback: C = this._defaultOneParamCallback as C,
|
|
351
|
-
beginRoot: BSTNodeKeyOrNode<N> = this.root,
|
|
368
|
+
beginRoot: BSTNodeKeyOrNode<K, N> = this.root,
|
|
352
369
|
iterationType = this.iterationType
|
|
353
370
|
): N | null | undefined {
|
|
354
371
|
if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|
|
@@ -357,38 +374,12 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
357
374
|
}
|
|
358
375
|
|
|
359
376
|
/**
|
|
360
|
-
* Time Complexity: O(log n)
|
|
377
|
+
* Time Complexity: O(log n)
|
|
361
378
|
* Space Complexity: O(1)
|
|
362
379
|
*/
|
|
363
380
|
|
|
364
381
|
/**
|
|
365
|
-
* Time Complexity: O(log n)
|
|
366
|
-
* Space Complexity: O(1)
|
|
367
|
-
*
|
|
368
|
-
* The function returns the successor of a given node in a red-black tree.
|
|
369
|
-
* @param {RedBlackTreeNode} x - RedBlackTreeNode - The node for which we want to find the successor.
|
|
370
|
-
* @returns the successor of the given RedBlackTreeNode.
|
|
371
|
-
*/
|
|
372
|
-
override getSuccessor(x: N): N | undefined {
|
|
373
|
-
if (x.right !== this.Sentinel) {
|
|
374
|
-
return this.getLeftMost(x.right) ?? undefined;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
let y: N | undefined = x.parent;
|
|
378
|
-
while (y !== this.Sentinel && y !== undefined && x === y.right) {
|
|
379
|
-
x = y;
|
|
380
|
-
y = y.parent;
|
|
381
|
-
}
|
|
382
|
-
return y;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Time Complexity: O(log n) on average (where n is the number of nodes in the tree)
|
|
387
|
-
* Space Complexity: O(1)
|
|
388
|
-
*/
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* Time Complexity: O(log n) on average (where n is the number of nodes in the tree)
|
|
382
|
+
* Time Complexity: O(log n)
|
|
392
383
|
* Space Complexity: O(1)
|
|
393
384
|
*
|
|
394
385
|
* The function returns the predecessor of a given node in a red-black tree.
|
|
@@ -397,12 +388,12 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
397
388
|
* @returns the predecessor of the given RedBlackTreeNode 'x'.
|
|
398
389
|
*/
|
|
399
390
|
override getPredecessor(x: N): N {
|
|
400
|
-
if (x.left
|
|
401
|
-
return this.getRightMost(x.left
|
|
391
|
+
if (this.isRealNode(x.left)) {
|
|
392
|
+
return this.getRightMost(x.left)!;
|
|
402
393
|
}
|
|
403
394
|
|
|
404
395
|
let y: N | undefined = x.parent;
|
|
405
|
-
while (
|
|
396
|
+
while (this.isRealNode(y) && x === y.left) {
|
|
406
397
|
x = y!;
|
|
407
398
|
y = y!.parent;
|
|
408
399
|
}
|
|
@@ -5,26 +5,28 @@
|
|
|
5
5
|
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
import type { BSTNodeKeyOrNode, BTNodeExemplar, TreeMultimapNodeNested, TreeMultimapOptions } from '../../types';
|
|
9
|
+
import {
|
|
10
|
+
BiTreeDeleteResult,
|
|
11
|
+
BTNCallback,
|
|
12
|
+
BTNodeKeyOrNode,
|
|
13
|
+
FamilyPosition,
|
|
14
|
+
IterationType,
|
|
15
|
+
TreeMultimapNested
|
|
14
16
|
} from '../../types';
|
|
15
|
-
import { BiTreeDeleteResult, BTNCallback, FamilyPosition, IterationType, TreeMultimapNested } from '../../types';
|
|
16
17
|
import { IBinaryTree } from '../../interfaces';
|
|
17
18
|
import { AVLTree, AVLTreeNode } from './avl-tree';
|
|
18
19
|
|
|
19
20
|
export class TreeMultimapNode<
|
|
21
|
+
K = any,
|
|
20
22
|
V = any,
|
|
21
|
-
N extends TreeMultimapNode<V, N> = TreeMultimapNodeNested<V>
|
|
22
|
-
> extends AVLTreeNode<V, N> {
|
|
23
|
+
N extends TreeMultimapNode<K, V, N> = TreeMultimapNodeNested<K, V>
|
|
24
|
+
> extends AVLTreeNode<K, V, N> {
|
|
23
25
|
count: number;
|
|
24
26
|
|
|
25
27
|
/**
|
|
26
28
|
* The constructor function initializes a BinaryTreeNode object with a key, value, and count.
|
|
27
|
-
* @param {
|
|
29
|
+
* @param {K} key - The `key` parameter is of type `K` and represents the unique identifier
|
|
28
30
|
* of the binary tree node.
|
|
29
31
|
* @param {V} [value] - The `value` parameter is an optional parameter of type `V`. It represents the value of the binary
|
|
30
32
|
* tree node. If no value is provided, it will be `undefined`.
|
|
@@ -32,7 +34,7 @@ export class TreeMultimapNode<
|
|
|
32
34
|
* occurs in a binary tree node. It has a default value of 1, which means that if no value is provided for the `count`
|
|
33
35
|
* parameter when creating a new instance of the `BinaryTreeNode` class.
|
|
34
36
|
*/
|
|
35
|
-
constructor(key:
|
|
37
|
+
constructor(key: K, value?: V, count = 1) {
|
|
36
38
|
super(key, value);
|
|
37
39
|
this.count = count;
|
|
38
40
|
}
|
|
@@ -41,12 +43,12 @@ export class TreeMultimapNode<
|
|
|
41
43
|
/**
|
|
42
44
|
* The only distinction between a TreeMultimap and a AVLTree lies in the ability of the former to store duplicate nodes through the utilization of counters.
|
|
43
45
|
*/
|
|
44
|
-
export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultimapNode<V, TreeMultimapNodeNested<V>>,
|
|
45
|
-
TREE extends TreeMultimap<V, N, TREE> = TreeMultimap<V, N, TreeMultimapNested<V, N>>>
|
|
46
|
-
extends AVLTree<V, N, TREE>
|
|
47
|
-
implements IBinaryTree<V, N, TREE> {
|
|
46
|
+
export class TreeMultimap<K = any, V = any, N extends TreeMultimapNode<K, V, N> = TreeMultimapNode<K, V, TreeMultimapNodeNested<K, V>>,
|
|
47
|
+
TREE extends TreeMultimap<K, V, N, TREE> = TreeMultimap<K, V, N, TreeMultimapNested<K, V, N>>>
|
|
48
|
+
extends AVLTree<K, V, N, TREE>
|
|
49
|
+
implements IBinaryTree<K, V, N, TREE> {
|
|
48
50
|
|
|
49
|
-
constructor(elements?: Iterable<BTNodeExemplar<V, N>>, options?: Partial<TreeMultimapOptions
|
|
51
|
+
constructor(elements?: Iterable<BTNodeExemplar<K, V, N>>, options?: Partial<TreeMultimapOptions<K>>) {
|
|
50
52
|
super([], options);
|
|
51
53
|
if (elements) this.addMany(elements);
|
|
52
54
|
}
|
|
@@ -62,43 +64,56 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|
|
62
64
|
|
|
63
65
|
/**
|
|
64
66
|
* The function creates a new BSTNode with the given key, value, and count.
|
|
65
|
-
* @param {
|
|
67
|
+
* @param {K} key - The key parameter is the unique identifier for the binary tree node. It is used to
|
|
66
68
|
* distinguish one node from another in the tree.
|
|
67
69
|
* @param {N} value - The `value` parameter represents the value that will be stored in the binary search tree node.
|
|
68
70
|
* @param {number} [count] - The "count" parameter is an optional parameter of type number. It represents the number of
|
|
69
71
|
* occurrences of the value in the binary search tree node. If not provided, the count will default to 1.
|
|
70
72
|
* @returns A new instance of the BSTNode class with the specified key, value, and count (if provided).
|
|
71
73
|
*/
|
|
72
|
-
override createNode(key:
|
|
74
|
+
override createNode(key: K, value?: V, count?: number): N {
|
|
73
75
|
return new TreeMultimapNode(key, value, count) as N;
|
|
74
76
|
}
|
|
75
77
|
|
|
76
|
-
override createTree(options?: TreeMultimapOptions): TREE {
|
|
77
|
-
return new TreeMultimap<V, N, TREE>([], {
|
|
78
|
+
override createTree(options?: TreeMultimapOptions<K>): TREE {
|
|
79
|
+
return new TreeMultimap<K, V, N, TREE>([], {
|
|
78
80
|
iterationType: this.iterationType,
|
|
79
|
-
|
|
81
|
+
variant: this.variant, ...options
|
|
80
82
|
}) as TREE;
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
/**
|
|
84
86
|
* The function checks if an exemplar is an instance of the TreeMultimapNode class.
|
|
85
|
-
* @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<V, N>`.
|
|
87
|
+
* @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<K, V, N>`.
|
|
86
88
|
* @returns a boolean value indicating whether the exemplar is an instance of the TreeMultimapNode
|
|
87
89
|
* class.
|
|
88
90
|
*/
|
|
89
|
-
override isNode(exemplar: BTNodeExemplar<V, N>): exemplar is N {
|
|
91
|
+
override isNode(exemplar: BTNodeExemplar<K, V, N>): exemplar is N {
|
|
90
92
|
return exemplar instanceof TreeMultimapNode;
|
|
91
93
|
}
|
|
92
94
|
|
|
95
|
+
/**
|
|
96
|
+
* The function "isNotNodeInstance" checks if a potential key is a K.
|
|
97
|
+
* @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any
|
|
98
|
+
* data type.
|
|
99
|
+
* @returns a boolean value indicating whether the potentialKey is of type number or not.
|
|
100
|
+
*/
|
|
101
|
+
override isNotNodeInstance(potentialKey: BTNodeKeyOrNode<K, N>): potentialKey is K {
|
|
102
|
+
return !(potentialKey instanceof TreeMultimapNode)
|
|
103
|
+
}
|
|
104
|
+
|
|
93
105
|
/**
|
|
94
106
|
* The function `exemplarToNode` converts an exemplar object into a node object.
|
|
95
|
-
* @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<V, N>`,
|
|
96
|
-
*
|
|
107
|
+
* @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<K, V, N>`, which means it
|
|
108
|
+
* can be one of the following:
|
|
109
|
+
* @param {V} [value] - The `value` parameter is an optional argument that represents the value
|
|
110
|
+
* associated with the node. It is of type `V`, which can be any data type. If no value is provided,
|
|
111
|
+
* it defaults to `undefined`.
|
|
97
112
|
* @param [count=1] - The `count` parameter is an optional parameter that specifies the number of
|
|
98
|
-
* times the
|
|
99
|
-
* @returns a
|
|
113
|
+
* times the value should be added to the node. If not provided, it defaults to 1.
|
|
114
|
+
* @returns a node of type `N` or `undefined`.
|
|
100
115
|
*/
|
|
101
|
-
override exemplarToNode(exemplar: BTNodeExemplar<V, N>, count = 1): N | undefined {
|
|
116
|
+
override exemplarToNode(exemplar: BTNodeExemplar<K, V, N>, value?: V, count = 1): N | undefined {
|
|
102
117
|
let node: N | undefined;
|
|
103
118
|
if (exemplar === undefined || exemplar === null) {
|
|
104
119
|
return;
|
|
@@ -111,8 +126,8 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|
|
111
126
|
} else {
|
|
112
127
|
node = this.createNode(key, value, count);
|
|
113
128
|
}
|
|
114
|
-
} else if (this.
|
|
115
|
-
node = this.createNode(exemplar,
|
|
129
|
+
} else if (this.isNotNodeInstance(exemplar)) {
|
|
130
|
+
node = this.createNode(exemplar, value, count);
|
|
116
131
|
} else {
|
|
117
132
|
return;
|
|
118
133
|
}
|
|
@@ -128,16 +143,20 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|
|
128
143
|
* Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity.
|
|
129
144
|
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
|
|
130
145
|
*
|
|
131
|
-
* The
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* @param [
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* @
|
|
146
|
+
* The function overrides the add method of a binary tree node and adds a new node to the tree.
|
|
147
|
+
* @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be either a key, a node, or an
|
|
148
|
+
* entry. It represents the key, node, or entry that you want to add to the binary tree.
|
|
149
|
+
* @param {V} [value] - The `value` parameter represents the value associated with the key in the
|
|
150
|
+
* binary tree node. It is an optional parameter, meaning it can be omitted when calling the `add`
|
|
151
|
+
* method.
|
|
152
|
+
* @param [count=1] - The `count` parameter represents the number of times the key-value pair should
|
|
153
|
+
* be added to the binary tree. By default, it is set to 1, meaning that the key-value pair will be
|
|
154
|
+
* added once. However, you can specify a different value for `count` if you want to add
|
|
155
|
+
* @returns The method is returning either the newly inserted node or `undefined` if the insertion
|
|
156
|
+
* was not successful.
|
|
138
157
|
*/
|
|
139
|
-
override add(keyOrNodeOrEntry: BTNodeExemplar<V, N>, count = 1): N | undefined {
|
|
140
|
-
const newNode = this.exemplarToNode(keyOrNodeOrEntry, count);
|
|
158
|
+
override add(keyOrNodeOrEntry: BTNodeExemplar<K, V, N>, value?: V, count = 1): N | undefined {
|
|
159
|
+
const newNode = this.exemplarToNode(keyOrNodeOrEntry, value, count);
|
|
141
160
|
if (newNode === undefined) return;
|
|
142
161
|
|
|
143
162
|
const orgNodeCount = newNode?.count || 0;
|
|
@@ -163,7 +182,7 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|
|
163
182
|
* either keys, nodes, or entries.
|
|
164
183
|
* @returns The method is returning an array of type `N | undefined`.
|
|
165
184
|
*/
|
|
166
|
-
override addMany(keysOrNodesOrEntries: Iterable<BTNodeExemplar<V, N>>): (N | undefined)[] {
|
|
185
|
+
override addMany(keysOrNodesOrEntries: Iterable<BTNodeExemplar<K, V, N>>): (N | undefined)[] {
|
|
167
186
|
return super.addMany(keysOrNodesOrEntries);
|
|
168
187
|
}
|
|
169
188
|
|
|
@@ -195,7 +214,7 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|
|
195
214
|
if (l > r) return;
|
|
196
215
|
const m = l + Math.floor((r - l) / 2);
|
|
197
216
|
const midNode = sorted[m];
|
|
198
|
-
this.add(
|
|
217
|
+
this.add(midNode.key, midNode.value, midNode.count);
|
|
199
218
|
buildBalanceBST(l, m - 1);
|
|
200
219
|
buildBalanceBST(m + 1, r);
|
|
201
220
|
};
|
|
@@ -211,7 +230,7 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|
|
211
230
|
if (l <= r) {
|
|
212
231
|
const m = l + Math.floor((r - l) / 2);
|
|
213
232
|
const midNode = sorted[m];
|
|
214
|
-
this.add(
|
|
233
|
+
this.add(midNode.key, midNode.value, midNode.count);
|
|
215
234
|
stack.push([m + 1, r]);
|
|
216
235
|
stack.push([l, m - 1]);
|
|
217
236
|
}
|
|
@@ -318,6 +337,24 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|
|
318
337
|
this._count = 0;
|
|
319
338
|
}
|
|
320
339
|
|
|
340
|
+
/**
|
|
341
|
+
* Time complexity: O(n)
|
|
342
|
+
* Space complexity: O(n)
|
|
343
|
+
*/
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Time complexity: O(n)
|
|
347
|
+
* Space complexity: O(n)
|
|
348
|
+
*
|
|
349
|
+
* The `clone` function creates a deep copy of a tree object.
|
|
350
|
+
* @returns The `clone()` method is returning a cloned instance of the `TREE` object.
|
|
351
|
+
*/
|
|
352
|
+
override clone(): TREE {
|
|
353
|
+
const cloned = this.createTree();
|
|
354
|
+
this.bfs(node => cloned.add(node.key, node.value, node.count));
|
|
355
|
+
return cloned;
|
|
356
|
+
}
|
|
357
|
+
|
|
321
358
|
/**
|
|
322
359
|
* Time Complexity: O(1) - constant time, as it performs basic pointer assignments.
|
|
323
360
|
* Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.
|
|
@@ -327,13 +364,13 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|
|
327
364
|
* @param {N | undefined} newNode - The `newNode` parameter represents the node that needs to be
|
|
328
365
|
* added to the binary tree. It can be of type `N` (which represents a node in the binary tree) or
|
|
329
366
|
* `undefined` if there is no node to add.
|
|
330
|
-
* @param {
|
|
367
|
+
* @param {K | N | undefined} parent - The `parent` parameter represents the parent node to
|
|
331
368
|
* which the new node will be added as a child. It can be either a node object (`N`) or a key value
|
|
332
|
-
* (`
|
|
369
|
+
* (`K`).
|
|
333
370
|
* @returns The method `_addTo` returns either the `parent.left` or `parent.right` node that was
|
|
334
371
|
* added, or `undefined` if no node was added.
|
|
335
372
|
*/
|
|
336
|
-
protected override _addTo(newNode: N | undefined, parent: BSTNodeKeyOrNode<N>): N | undefined {
|
|
373
|
+
protected override _addTo(newNode: N | undefined, parent: BSTNodeKeyOrNode<K, N>): N | undefined {
|
|
337
374
|
parent = this.ensureNode(parent);
|
|
338
375
|
if (parent) {
|
|
339
376
|
if (parent.left === undefined) {
|
|
@@ -361,14 +398,14 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|
|
361
398
|
|
|
362
399
|
/**
|
|
363
400
|
* The `_swapProperties` function swaps the key, value, count, and height properties between two nodes.
|
|
364
|
-
* @param {
|
|
365
|
-
* which the values will be swapped. It can be of type `
|
|
366
|
-
* @param {
|
|
401
|
+
* @param {K | N | undefined} srcNode - The `srcNode` parameter represents the source node from
|
|
402
|
+
* which the values will be swapped. It can be of type `K`, `N`, or `undefined`.
|
|
403
|
+
* @param {K | N | undefined} destNode - The `destNode` parameter represents the destination
|
|
367
404
|
* node where the values from the source node will be swapped to.
|
|
368
405
|
* @returns either the `destNode` object if both `srcNode` and `destNode` are defined, or `undefined`
|
|
369
406
|
* if either `srcNode` or `destNode` is undefined.
|
|
370
407
|
*/
|
|
371
|
-
protected override _swapProperties(srcNode: BSTNodeKeyOrNode<N>, destNode: BSTNodeKeyOrNode<N>): N | undefined {
|
|
408
|
+
protected override _swapProperties(srcNode: BSTNodeKeyOrNode<K, N>, destNode: BSTNodeKeyOrNode<K, N>): N | undefined {
|
|
372
409
|
srcNode = this.ensureNode(srcNode);
|
|
373
410
|
destNode = this.ensureNode(destNode);
|
|
374
411
|
if (srcNode && destNode) {
|