graph-typed 1.39.5 → 1.40.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/binary-tree/avl-tree.d.ts +6 -6
- package/dist/data-structures/binary-tree/avl-tree.js +13 -14
- package/dist/data-structures/binary-tree/binary-indexed-tree.d.ts +0 -3
- package/dist/data-structures/binary-tree/binary-indexed-tree.js +2 -11
- package/dist/data-structures/binary-tree/binary-tree.d.ts +12 -27
- package/dist/data-structures/binary-tree/binary-tree.js +25 -46
- package/dist/data-structures/binary-tree/bst.d.ts +7 -7
- package/dist/data-structures/binary-tree/bst.js +16 -16
- package/dist/data-structures/binary-tree/rb-tree.d.ts +3 -5
- package/dist/data-structures/binary-tree/rb-tree.js +5 -11
- package/dist/data-structures/binary-tree/segment-tree.d.ts +14 -30
- package/dist/data-structures/binary-tree/segment-tree.js +20 -68
- package/dist/data-structures/binary-tree/tree-multiset.d.ts +7 -7
- package/dist/data-structures/binary-tree/tree-multiset.js +24 -24
- package/dist/data-structures/graph/abstract-graph.d.ts +16 -35
- package/dist/data-structures/graph/abstract-graph.js +18 -57
- package/dist/data-structures/graph/directed-graph.d.ts +16 -22
- package/dist/data-structures/graph/directed-graph.js +17 -35
- package/dist/data-structures/graph/map-graph.d.ts +13 -19
- package/dist/data-structures/graph/map-graph.js +15 -33
- package/dist/data-structures/graph/undirected-graph.d.ts +12 -19
- package/dist/data-structures/graph/undirected-graph.js +15 -28
- package/dist/data-structures/hash/coordinate-map.d.ts +0 -1
- package/dist/data-structures/hash/coordinate-map.js +0 -3
- package/dist/data-structures/hash/coordinate-set.d.ts +0 -1
- package/dist/data-structures/hash/coordinate-set.js +0 -3
- package/dist/data-structures/hash/hash-map.d.ts +8 -14
- package/dist/data-structures/hash/hash-map.js +4 -22
- package/dist/data-structures/hash/hash-table.d.ts +10 -13
- package/dist/data-structures/hash/hash-table.js +8 -17
- package/dist/data-structures/heap/heap.d.ts +12 -6
- package/dist/data-structures/heap/heap.js +40 -22
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +34 -42
- package/dist/data-structures/linked-list/doubly-linked-list.js +67 -91
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +26 -32
- package/dist/data-structures/linked-list/singly-linked-list.js +64 -82
- package/dist/data-structures/linked-list/skip-linked-list.d.ts +29 -10
- package/dist/data-structures/linked-list/skip-linked-list.js +62 -17
- package/dist/data-structures/matrix/matrix.d.ts +1 -1
- package/dist/data-structures/matrix/matrix2d.d.ts +1 -1
- package/dist/data-structures/matrix/navigator.d.ts +4 -4
- package/dist/data-structures/queue/deque.d.ts +8 -12
- package/dist/data-structures/queue/deque.js +31 -43
- package/dist/data-structures/queue/queue.d.ts +20 -5
- package/dist/data-structures/queue/queue.js +35 -18
- package/dist/data-structures/stack/stack.d.ts +2 -1
- package/dist/data-structures/stack/stack.js +10 -7
- package/dist/data-structures/tree/tree.d.ts +3 -9
- package/dist/data-structures/tree/tree.js +3 -21
- package/dist/data-structures/trie/trie.d.ts +6 -12
- package/dist/data-structures/trie/trie.js +6 -24
- package/dist/interfaces/binary-tree.d.ts +3 -3
- package/dist/interfaces/graph.d.ts +2 -2
- package/dist/types/data-structures/binary-tree/bst.d.ts +1 -1
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree.ts +15 -17
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +3 -15
- package/src/data-structures/binary-tree/binary-tree.ts +35 -60
- package/src/data-structures/binary-tree/bst.ts +21 -22
- package/src/data-structures/binary-tree/rb-tree.ts +19 -27
- package/src/data-structures/binary-tree/segment-tree.ts +25 -92
- package/src/data-structures/binary-tree/tree-multiset.ts +26 -27
- package/src/data-structures/graph/abstract-graph.ts +42 -88
- package/src/data-structures/graph/directed-graph.ts +29 -55
- package/src/data-structures/graph/map-graph.ts +20 -45
- package/src/data-structures/graph/undirected-graph.ts +24 -41
- package/src/data-structures/hash/coordinate-map.ts +0 -4
- package/src/data-structures/hash/coordinate-set.ts +0 -4
- package/src/data-structures/hash/hash-map.ts +13 -37
- package/src/data-structures/hash/hash-table.ts +15 -27
- package/src/data-structures/hash/tree-map.ts +2 -1
- package/src/data-structures/hash/tree-set.ts +2 -1
- package/src/data-structures/heap/heap.ts +58 -30
- package/src/data-structures/heap/max-heap.ts +1 -1
- package/src/data-structures/heap/min-heap.ts +1 -1
- package/src/data-structures/linked-list/doubly-linked-list.ts +81 -115
- package/src/data-structures/linked-list/singly-linked-list.ts +76 -101
- package/src/data-structures/linked-list/skip-linked-list.ts +73 -25
- package/src/data-structures/matrix/matrix.ts +2 -2
- package/src/data-structures/matrix/matrix2d.ts +1 -1
- package/src/data-structures/matrix/navigator.ts +4 -4
- package/src/data-structures/matrix/vector2d.ts +2 -1
- package/src/data-structures/priority-queue/max-priority-queue.ts +1 -1
- package/src/data-structures/priority-queue/min-priority-queue.ts +1 -1
- package/src/data-structures/priority-queue/priority-queue.ts +1 -1
- package/src/data-structures/queue/deque.ts +38 -53
- package/src/data-structures/queue/queue.ts +38 -20
- package/src/data-structures/stack/stack.ts +13 -9
- package/src/data-structures/tree/tree.ts +7 -33
- package/src/data-structures/trie/trie.ts +14 -40
- package/src/interfaces/binary-tree.ts +3 -3
- package/src/interfaces/graph.ts +2 -2
- package/src/types/data-structures/binary-tree/bst.ts +1 -1
- package/src/types/data-structures/matrix/navigator.ts +1 -1
- package/src/types/utils/utils.ts +1 -1
- package/src/types/utils/validate-type.ts +2 -2
|
@@ -5,22 +5,21 @@
|
|
|
5
5
|
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
8
|
+
import type {BSTComparator, BSTNodeNested, BSTOptions, BTNCallback, BTNKey} from '../../types';
|
|
9
9
|
import {CP, IterationType} from '../../types';
|
|
10
10
|
import {BinaryTree, BinaryTreeNode} from './binary-tree';
|
|
11
11
|
import {IBinaryTree} from '../../interfaces';
|
|
12
12
|
import {Queue} from '../queue';
|
|
13
13
|
|
|
14
14
|
export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extends BinaryTreeNode<V, N> {
|
|
15
|
-
constructor(key: BTNKey,
|
|
16
|
-
super(key,
|
|
15
|
+
constructor(key: BTNKey, value?: V) {
|
|
16
|
+
super(key, value);
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>>
|
|
21
21
|
extends BinaryTree<V, N>
|
|
22
|
-
implements IBinaryTree<V, N>
|
|
23
|
-
{
|
|
22
|
+
implements IBinaryTree<V, N> {
|
|
24
23
|
/**
|
|
25
24
|
* The constructor function initializes a binary search tree object with an optional comparator
|
|
26
25
|
* function.
|
|
@@ -41,12 +40,12 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
41
40
|
* The function creates a new binary search tree node with the given key and value.
|
|
42
41
|
* @param {BTNKey} key - The key parameter is the key value that will be associated with
|
|
43
42
|
* the new node. It is used to determine the position of the node in the binary search tree.
|
|
44
|
-
* @param [
|
|
43
|
+
* @param [value] - The parameter `value` is an optional value that can be assigned to the node. It
|
|
45
44
|
* represents the value associated with the node in a binary search tree.
|
|
46
45
|
* @returns a new instance of the BSTNode class with the specified key and value.
|
|
47
46
|
*/
|
|
48
|
-
override createNode(key: BTNKey,
|
|
49
|
-
return new BSTNode<V, N>(key,
|
|
47
|
+
override createNode(key: BTNKey, value?: V): N {
|
|
48
|
+
return new BSTNode<V, N>(key, value) as N;
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
/**
|
|
@@ -54,25 +53,25 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
54
53
|
* into the tree.
|
|
55
54
|
* @param {BTNKey | N | null} keyOrNode - The `keyOrNode` parameter can be either a
|
|
56
55
|
* `BTNKey` (which can be a number or a string), a `BSTNode` object, or `null`.
|
|
57
|
-
* @param [
|
|
56
|
+
* @param [value] - The `value` parameter is the value to be assigned to the new node being added to the
|
|
58
57
|
* binary search tree.
|
|
59
58
|
* @returns the inserted node (N) if it was successfully added to the binary search tree. If the node
|
|
60
59
|
* was not added or if the parameters were invalid, it returns null or undefined.
|
|
61
60
|
*/
|
|
62
|
-
override add(keyOrNode: BTNKey | N | null,
|
|
61
|
+
override add(keyOrNode: BTNKey | N | null, value?: V): N | null | undefined {
|
|
63
62
|
// TODO support node as a parameter
|
|
64
63
|
let inserted: N | null = null;
|
|
65
64
|
let newNode: N | null = null;
|
|
66
65
|
if (keyOrNode instanceof BSTNode) {
|
|
67
66
|
newNode = keyOrNode;
|
|
68
67
|
} else if (typeof keyOrNode === 'number') {
|
|
69
|
-
newNode = this.createNode(keyOrNode,
|
|
68
|
+
newNode = this.createNode(keyOrNode, value);
|
|
70
69
|
} else if (keyOrNode === null) {
|
|
71
70
|
newNode = null;
|
|
72
71
|
}
|
|
73
72
|
if (this.root === null) {
|
|
74
73
|
this._setRoot(newNode);
|
|
75
|
-
this.
|
|
74
|
+
this._size = this.size + 1;
|
|
76
75
|
inserted = this.root;
|
|
77
76
|
} else {
|
|
78
77
|
let cur = this.root;
|
|
@@ -81,7 +80,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
81
80
|
if (cur !== null && newNode !== null) {
|
|
82
81
|
if (this._compare(cur.key, newNode.key) === CP.eq) {
|
|
83
82
|
if (newNode) {
|
|
84
|
-
cur.
|
|
83
|
+
cur.value = newNode.value;
|
|
85
84
|
}
|
|
86
85
|
//Duplicates are not accepted.
|
|
87
86
|
traversing = false;
|
|
@@ -94,7 +93,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
94
93
|
}
|
|
95
94
|
//Add to the left of the current node
|
|
96
95
|
cur.left = newNode;
|
|
97
|
-
this.
|
|
96
|
+
this._size = this.size + 1;
|
|
98
97
|
traversing = false;
|
|
99
98
|
inserted = cur.left;
|
|
100
99
|
} else {
|
|
@@ -109,7 +108,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
109
108
|
}
|
|
110
109
|
//Add to the right of the current node
|
|
111
110
|
cur.right = newNode;
|
|
112
|
-
this.
|
|
111
|
+
this._size = this.size + 1;
|
|
113
112
|
traversing = false;
|
|
114
113
|
inserted = cur.right;
|
|
115
114
|
} else {
|
|
@@ -128,7 +127,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
128
127
|
/**
|
|
129
128
|
* The `addMany` function is used to efficiently add multiple nodes to a binary search tree while
|
|
130
129
|
* maintaining balance.
|
|
131
|
-
* @param {[BTNKey | N, N['
|
|
130
|
+
* @param {[BTNKey | N, N['value']][]} keysOrNodes - The `arr` parameter in the `addMany` function
|
|
132
131
|
* represents an array of keys or nodes that need to be added to the binary search tree. It can be an
|
|
133
132
|
* array of `BTNKey` or `N` (which represents the node type in the binary search tree) or
|
|
134
133
|
* `null
|
|
@@ -154,15 +153,15 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
154
153
|
return super.addMany(keysOrNodes, data);
|
|
155
154
|
}
|
|
156
155
|
const inserted: (N | null | undefined)[] = [];
|
|
157
|
-
const combinedArr: [BTNKey | N, N['
|
|
156
|
+
const combinedArr: [BTNKey | N, N['value']][] = keysOrNodes.map((value, index) => [value, data?.[index]]);
|
|
158
157
|
let sorted = [];
|
|
159
158
|
|
|
160
|
-
function isNodeOrNullTuple(arr: [BTNKey | N, N['
|
|
159
|
+
function isNodeOrNullTuple(arr: [BTNKey | N, N['value']][]): arr is [N, N['value']][] {
|
|
161
160
|
for (const [keyOrNode] of arr) if (keyOrNode instanceof BSTNode) return true;
|
|
162
161
|
return false;
|
|
163
162
|
}
|
|
164
163
|
|
|
165
|
-
function isBinaryTreeKeyOrNullTuple(arr: [BTNKey | N, N['
|
|
164
|
+
function isBinaryTreeKeyOrNullTuple(arr: [BTNKey | N, N['value']][]): arr is [BTNKey, N['value']][] {
|
|
166
165
|
for (const [keyOrNode] of arr) if (typeof keyOrNode === 'number') return true;
|
|
167
166
|
return false;
|
|
168
167
|
}
|
|
@@ -178,7 +177,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
178
177
|
throw new Error('Invalid input keysOrNodes');
|
|
179
178
|
}
|
|
180
179
|
sortedKeysOrNodes = sorted.map(([keyOrNode]) => keyOrNode);
|
|
181
|
-
sortedData = sorted.map(([,
|
|
180
|
+
sortedData = sorted.map(([, value]) => value);
|
|
182
181
|
const recursive = (arr: (BTNKey | null | N)[], data?: (V | undefined)[]) => {
|
|
183
182
|
if (arr.length === 0) return;
|
|
184
183
|
|
|
@@ -426,7 +425,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
426
425
|
if (l > r) return;
|
|
427
426
|
const m = l + Math.floor((r - l) / 2);
|
|
428
427
|
const midNode = sorted[m];
|
|
429
|
-
this.add(midNode.key, midNode.
|
|
428
|
+
this.add(midNode.key, midNode.value);
|
|
430
429
|
buildBalanceBST(l, m - 1);
|
|
431
430
|
buildBalanceBST(m + 1, r);
|
|
432
431
|
};
|
|
@@ -442,7 +441,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
442
441
|
if (l <= r) {
|
|
443
442
|
const m = l + Math.floor((r - l) / 2);
|
|
444
443
|
const midNode = sorted[m];
|
|
445
|
-
this.add(midNode.key, midNode.
|
|
444
|
+
this.add(midNode.key, midNode.value);
|
|
446
445
|
stack.push([m + 1, r]);
|
|
447
446
|
stack.push([l, m - 1]);
|
|
448
447
|
}
|
|
@@ -3,42 +3,34 @@ import {IBinaryTree} from '../../interfaces';
|
|
|
3
3
|
import {BST, BSTNode} from './bst';
|
|
4
4
|
|
|
5
5
|
export class RBTreeNode<V = any, N extends RBTreeNode<V, N> = RBTreeNodeNested<V>> extends BSTNode<V, N> {
|
|
6
|
-
constructor(key: BTNKey,
|
|
7
|
-
super(key,
|
|
8
|
-
this.
|
|
6
|
+
constructor(key: BTNKey, value?: V) {
|
|
7
|
+
super(key, value);
|
|
8
|
+
this.color = RBColor.RED;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
color: RBColor;
|
|
12
12
|
|
|
13
|
-
get color(): RBColor {
|
|
14
|
-
return this._color;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
set color(value: RBColor) {
|
|
18
|
-
this._color = value;
|
|
19
|
-
}
|
|
20
13
|
}
|
|
21
14
|
|
|
22
15
|
export class RBTree<V, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNested<V>>>
|
|
23
16
|
extends BST<V, N>
|
|
24
|
-
implements IBinaryTree<V, N>
|
|
25
|
-
{
|
|
17
|
+
implements IBinaryTree<V, N> {
|
|
26
18
|
constructor(options?: RBTreeOptions) {
|
|
27
19
|
super(options);
|
|
28
20
|
}
|
|
29
21
|
|
|
30
|
-
override createNode(key: BTNKey,
|
|
31
|
-
return new RBTreeNode(key,
|
|
22
|
+
override createNode(key: BTNKey, value?: V): N {
|
|
23
|
+
return new RBTreeNode(key, value) as N;
|
|
32
24
|
}
|
|
33
25
|
|
|
34
|
-
// override add(keyOrNode: BTNKey | N | null,
|
|
35
|
-
// const inserted = super.add(keyOrNode,
|
|
26
|
+
// override add(keyOrNode: BTNKey | N | null, value?: V): N | null | undefined {
|
|
27
|
+
// const inserted = super.add(keyOrNode, value);
|
|
36
28
|
// if (inserted) this._fixInsertViolation(inserted);
|
|
37
29
|
// return inserted;
|
|
38
30
|
// }
|
|
39
31
|
//
|
|
40
32
|
// // Method for fixing insert violations in a red-black tree
|
|
41
|
-
//
|
|
33
|
+
// protected _fixInsertViolation(node: N) {
|
|
42
34
|
// while (node !== this.root! && node.color === RBColor.RED && node.parent!.color === RBColor.RED) {
|
|
43
35
|
// const parent = node.parent!;
|
|
44
36
|
// const grandparent = parent.parent!;
|
|
@@ -101,7 +93,7 @@ export class RBTree<V, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNest
|
|
|
101
93
|
// }
|
|
102
94
|
//
|
|
103
95
|
// // Left rotation operation
|
|
104
|
-
//
|
|
96
|
+
// protected _rotateLeft(node: N) {
|
|
105
97
|
// const rightChild = node.right;
|
|
106
98
|
// node.right = rightChild!.left;
|
|
107
99
|
//
|
|
@@ -125,7 +117,7 @@ export class RBTree<V, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNest
|
|
|
125
117
|
// }
|
|
126
118
|
//
|
|
127
119
|
// // Right rotation operation
|
|
128
|
-
//
|
|
120
|
+
// protected _rotateRight(node: N) {
|
|
129
121
|
// const leftChild = node.left;
|
|
130
122
|
// node.left = leftChild!.right;
|
|
131
123
|
//
|
|
@@ -148,12 +140,12 @@ export class RBTree<V, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNest
|
|
|
148
140
|
// node.parent = leftChild;
|
|
149
141
|
// }
|
|
150
142
|
//
|
|
151
|
-
//
|
|
143
|
+
// protected _isNodeRed(node: N | null | undefined): boolean {
|
|
152
144
|
// return node ? node.color === RBColor.RED : false;
|
|
153
145
|
// }
|
|
154
146
|
//
|
|
155
147
|
// // Find the sibling node
|
|
156
|
-
//
|
|
148
|
+
// protected _findSibling(node: N): N | null | undefined {
|
|
157
149
|
// if (!node.parent) {
|
|
158
150
|
// return undefined;
|
|
159
151
|
// }
|
|
@@ -162,7 +154,7 @@ export class RBTree<V, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNest
|
|
|
162
154
|
// }
|
|
163
155
|
//
|
|
164
156
|
// // Remove a node
|
|
165
|
-
//
|
|
157
|
+
// protected _removeNode(node: N, replacement: N | null | undefined): void {
|
|
166
158
|
// if (node === this.root && !replacement) {
|
|
167
159
|
// // If there's only the root node and no replacement, simply delete the root node
|
|
168
160
|
// this._setRoot(null);
|
|
@@ -230,7 +222,7 @@ export class RBTree<V, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNest
|
|
|
230
222
|
// }
|
|
231
223
|
//
|
|
232
224
|
// // Repair operation after node deletion
|
|
233
|
-
//
|
|
225
|
+
// protected _fixDeleteViolation(node: N | null | undefined) {
|
|
234
226
|
// let sibling;
|
|
235
227
|
//
|
|
236
228
|
// while (node && node !== this.root && !this._isNodeRed(node)) {
|
|
@@ -327,7 +319,7 @@ export class RBTree<V, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNest
|
|
|
327
319
|
// }
|
|
328
320
|
// }
|
|
329
321
|
//
|
|
330
|
-
//
|
|
322
|
+
// protected _findMin(node: N): N {
|
|
331
323
|
// while (node.left) {
|
|
332
324
|
// node = node.left;
|
|
333
325
|
// }
|
|
@@ -335,7 +327,7 @@ export class RBTree<V, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNest
|
|
|
335
327
|
// }
|
|
336
328
|
//
|
|
337
329
|
// // Get the replacement node
|
|
338
|
-
//
|
|
330
|
+
// protected _getReplacementNode(node: N): N | null | undefined {
|
|
339
331
|
// if (node.left && node.right) {
|
|
340
332
|
// return this._findSuccessor(node);
|
|
341
333
|
// }
|
|
@@ -348,7 +340,7 @@ export class RBTree<V, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNest
|
|
|
348
340
|
// }
|
|
349
341
|
//
|
|
350
342
|
// // Find the successor node
|
|
351
|
-
//
|
|
343
|
+
// protected _findSuccessor(node: N): N | null | undefined {
|
|
352
344
|
// if (node.right) {
|
|
353
345
|
// // If the node has a right child, find the minimum node in the right subtree as the successor
|
|
354
346
|
// return this._findMin(node.right);
|
|
@@ -9,70 +9,18 @@
|
|
|
9
9
|
import type {SegmentTreeNodeVal} from '../../types';
|
|
10
10
|
|
|
11
11
|
export class SegmentTreeNode {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
set start(v: number) {
|
|
25
|
-
this._start = v;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
private _end = 0;
|
|
29
|
-
|
|
30
|
-
get end(): number {
|
|
31
|
-
return this._end;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
set end(v: number) {
|
|
35
|
-
this._end = v;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
private _val: SegmentTreeNodeVal | null = null;
|
|
39
|
-
|
|
40
|
-
get val(): SegmentTreeNodeVal | null {
|
|
41
|
-
return this._val;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
set val(v: SegmentTreeNodeVal | null) {
|
|
45
|
-
this._val = v;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
private _sum = 0;
|
|
49
|
-
|
|
50
|
-
get sum(): number {
|
|
51
|
-
return this._sum;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
set sum(v: number) {
|
|
55
|
-
this._sum = v;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
private _left: SegmentTreeNode | null = null;
|
|
59
|
-
|
|
60
|
-
get left(): SegmentTreeNode | null {
|
|
61
|
-
return this._left;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
set left(v: SegmentTreeNode | null) {
|
|
65
|
-
this._left = v;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
private _right: SegmentTreeNode | null = null;
|
|
69
|
-
|
|
70
|
-
get right(): SegmentTreeNode | null {
|
|
71
|
-
return this._right;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
set right(v: SegmentTreeNode | null) {
|
|
75
|
-
this._right = v;
|
|
12
|
+
start = 0;
|
|
13
|
+
end = 0;
|
|
14
|
+
value: SegmentTreeNodeVal | null = null;
|
|
15
|
+
sum = 0;
|
|
16
|
+
left: SegmentTreeNode | null = null;
|
|
17
|
+
right: SegmentTreeNode | null = null;
|
|
18
|
+
|
|
19
|
+
constructor(start: number, end: number, sum: number, value?: SegmentTreeNodeVal | null) {
|
|
20
|
+
this.start = start;
|
|
21
|
+
this.end = end;
|
|
22
|
+
this.sum = sum;
|
|
23
|
+
this.value = value || null;
|
|
76
24
|
}
|
|
77
25
|
}
|
|
78
26
|
|
|
@@ -101,24 +49,25 @@ export class SegmentTree {
|
|
|
101
49
|
}
|
|
102
50
|
}
|
|
103
51
|
|
|
104
|
-
|
|
52
|
+
protected _values: number[] = [];
|
|
105
53
|
|
|
106
54
|
get values(): number[] {
|
|
107
55
|
return this._values;
|
|
108
56
|
}
|
|
109
57
|
|
|
110
|
-
|
|
58
|
+
protected _start = 0;
|
|
59
|
+
|
|
111
60
|
get start(): number {
|
|
112
61
|
return this._start;
|
|
113
62
|
}
|
|
114
63
|
|
|
115
|
-
|
|
64
|
+
protected _end: number;
|
|
116
65
|
|
|
117
66
|
get end(): number {
|
|
118
67
|
return this._end;
|
|
119
68
|
}
|
|
120
69
|
|
|
121
|
-
|
|
70
|
+
protected _root: SegmentTreeNode | null;
|
|
122
71
|
|
|
123
72
|
get root(): SegmentTreeNode | null {
|
|
124
73
|
return this._root;
|
|
@@ -154,30 +103,30 @@ export class SegmentTree {
|
|
|
154
103
|
* updated.
|
|
155
104
|
* @param {number} sum - The `sum` parameter represents the new value that should be assigned to the `sum` property of
|
|
156
105
|
* the `SegmentTreeNode` at the specified `index`.
|
|
157
|
-
* @param {SegmentTreeNodeVal} [
|
|
106
|
+
* @param {SegmentTreeNodeVal} [value] - The `value` parameter is an optional value that can be assigned to the `value`
|
|
158
107
|
* property of the `SegmentTreeNode` object. It is not currently used in the code, but you can uncomment the line `//
|
|
159
|
-
* cur.
|
|
108
|
+
* cur.value = value;` and pass a value for `value` in the
|
|
160
109
|
* @returns The function does not return anything.
|
|
161
110
|
*/
|
|
162
|
-
updateNode(index: number, sum: number,
|
|
111
|
+
updateNode(index: number, sum: number, value?: SegmentTreeNodeVal) {
|
|
163
112
|
const root = this.root || null;
|
|
164
113
|
if (!root) {
|
|
165
114
|
return;
|
|
166
115
|
}
|
|
167
|
-
const dfs = (cur: SegmentTreeNode, index: number, sum: number,
|
|
116
|
+
const dfs = (cur: SegmentTreeNode, index: number, sum: number, value?: SegmentTreeNodeVal) => {
|
|
168
117
|
if (cur.start === cur.end && cur.start === index) {
|
|
169
118
|
cur.sum = sum;
|
|
170
|
-
if (
|
|
119
|
+
if (value !== undefined) cur.value = value;
|
|
171
120
|
return;
|
|
172
121
|
}
|
|
173
122
|
const mid = cur.start + Math.floor((cur.end - cur.start) / 2);
|
|
174
123
|
if (index <= mid) {
|
|
175
124
|
if (cur.left) {
|
|
176
|
-
dfs(cur.left, index, sum,
|
|
125
|
+
dfs(cur.left, index, sum, value);
|
|
177
126
|
}
|
|
178
127
|
} else {
|
|
179
128
|
if (cur.right) {
|
|
180
|
-
dfs(cur.right, index, sum,
|
|
129
|
+
dfs(cur.right, index, sum, value);
|
|
181
130
|
}
|
|
182
131
|
}
|
|
183
132
|
if (cur.left && cur.right) {
|
|
@@ -185,7 +134,7 @@ export class SegmentTree {
|
|
|
185
134
|
}
|
|
186
135
|
};
|
|
187
136
|
|
|
188
|
-
dfs(root, index, sum,
|
|
137
|
+
dfs(root, index, sum, value);
|
|
189
138
|
}
|
|
190
139
|
|
|
191
140
|
/**
|
|
@@ -238,20 +187,4 @@ export class SegmentTree {
|
|
|
238
187
|
};
|
|
239
188
|
return dfs(root, indexA, indexB);
|
|
240
189
|
}
|
|
241
|
-
|
|
242
|
-
protected _setValues(value: number[]) {
|
|
243
|
-
this._values = value;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
protected _setStart(value: number) {
|
|
247
|
-
this._start = value;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
protected _setEnd(value: number) {
|
|
251
|
-
this._end = value;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
protected _setRoot(v: SegmentTreeNode | null) {
|
|
255
|
-
this._root = v;
|
|
256
|
-
}
|
|
257
190
|
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
8
|
import type {BTNKey, TreeMultisetNodeNested, TreeMultisetOptions} from '../../types';
|
|
9
|
-
import {BinaryTreeDeletedResult, CP, FamilyPosition, IterationType
|
|
9
|
+
import {BinaryTreeDeletedResult, BTNCallback, CP, FamilyPosition, IterationType} from '../../types';
|
|
10
10
|
import {IBinaryTree} from '../../interfaces';
|
|
11
11
|
import {AVLTree, AVLTreeNode} from './avl-tree';
|
|
12
12
|
|
|
@@ -20,14 +20,14 @@ export class TreeMultisetNode<
|
|
|
20
20
|
* The constructor function initializes a BinaryTreeNode object with a key, value, and count.
|
|
21
21
|
* @param {BTNKey} key - The `key` parameter is of type `BTNKey` and represents the unique identifier
|
|
22
22
|
* of the binary tree node.
|
|
23
|
-
* @param {V} [
|
|
23
|
+
* @param {V} [value] - The `value` parameter is an optional parameter of type `V`. It represents the value of the binary
|
|
24
24
|
* tree node. If no value is provided, it will be `undefined`.
|
|
25
25
|
* @param {number} [count=1] - The `count` parameter is a number that represents the number of times a particular value
|
|
26
26
|
* occurs in a binary tree node. It has a default value of 1, which means that if no value is provided for the `count`
|
|
27
27
|
* parameter when creating a new instance of the `BinaryTreeNode` class.
|
|
28
28
|
*/
|
|
29
|
-
constructor(key: BTNKey,
|
|
30
|
-
super(key,
|
|
29
|
+
constructor(key: BTNKey, value?: V, count = 1) {
|
|
30
|
+
super(key, value);
|
|
31
31
|
this.count = count;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -37,8 +37,7 @@ export class TreeMultisetNode<
|
|
|
37
37
|
*/
|
|
38
38
|
export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultisetNode<V, TreeMultisetNodeNested<V>>>
|
|
39
39
|
extends AVLTree<V, N>
|
|
40
|
-
implements IBinaryTree<V, N>
|
|
41
|
-
{
|
|
40
|
+
implements IBinaryTree<V, N> {
|
|
42
41
|
/**
|
|
43
42
|
* The constructor function for a TreeMultiset class in TypeScript, which extends another class and sets an option to
|
|
44
43
|
* merge duplicated values.
|
|
@@ -59,13 +58,13 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
|
|
|
59
58
|
* The function creates a new BSTNode with the given key, value, and count.
|
|
60
59
|
* @param {BTNKey} key - The key parameter is the unique identifier for the binary tree node. It is used to
|
|
61
60
|
* distinguish one node from another in the tree.
|
|
62
|
-
* @param {N}
|
|
61
|
+
* @param {N} value - The `value` parameter represents the value that will be stored in the binary search tree node.
|
|
63
62
|
* @param {number} [count] - The "count" parameter is an optional parameter of type number. It represents the number of
|
|
64
63
|
* occurrences of the value in the binary search tree node. If not provided, the count will default to 1.
|
|
65
64
|
* @returns A new instance of the BSTNode class with the specified key, value, and count (if provided).
|
|
66
65
|
*/
|
|
67
|
-
override createNode(key: BTNKey,
|
|
68
|
-
return new TreeMultisetNode(key,
|
|
66
|
+
override createNode(key: BTNKey, value?: V, count?: number): N {
|
|
67
|
+
return new TreeMultisetNode(key, value, count) as N;
|
|
69
68
|
}
|
|
70
69
|
|
|
71
70
|
/**
|
|
@@ -74,26 +73,26 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
|
|
|
74
73
|
* @param {BTNKey | N | null} keyOrNode - The `keyOrNode` parameter can be either a
|
|
75
74
|
* `BTNKey` (which represents the key of the node to be added), a `N` (which represents a
|
|
76
75
|
* node to be added), or `null` (which represents a null node).
|
|
77
|
-
* @param [
|
|
76
|
+
* @param [value] - The `value` parameter represents the value associated with the key that is being
|
|
78
77
|
* added to the binary tree.
|
|
79
78
|
* @param [count=1] - The `count` parameter represents the number of occurrences of the key/value
|
|
80
79
|
* pair that will be added to the binary tree. It has a default value of 1, which means that if no
|
|
81
80
|
* count is specified, the default count will be 1.
|
|
82
81
|
* @returns The function `add` returns a value of type `N | null | undefined`.
|
|
83
82
|
*/
|
|
84
|
-
override add(keyOrNode: BTNKey | N | null,
|
|
83
|
+
override add(keyOrNode: BTNKey | N | null, value?: V, count = 1): N | null | undefined {
|
|
85
84
|
let inserted: N | null | undefined = undefined,
|
|
86
85
|
newNode: N | null;
|
|
87
86
|
if (keyOrNode instanceof TreeMultisetNode) {
|
|
88
|
-
newNode = this.createNode(keyOrNode.key, keyOrNode.
|
|
87
|
+
newNode = this.createNode(keyOrNode.key, keyOrNode.value, keyOrNode.count);
|
|
89
88
|
} else if (keyOrNode === null) {
|
|
90
89
|
newNode = null;
|
|
91
90
|
} else {
|
|
92
|
-
newNode = this.createNode(keyOrNode,
|
|
91
|
+
newNode = this.createNode(keyOrNode, value, count);
|
|
93
92
|
}
|
|
94
93
|
if (!this.root) {
|
|
95
94
|
this._setRoot(newNode);
|
|
96
|
-
this.
|
|
95
|
+
this._size = this.size + 1;
|
|
97
96
|
newNode && this._setCount(this.count + newNode.count);
|
|
98
97
|
inserted = this.root;
|
|
99
98
|
} else {
|
|
@@ -103,7 +102,7 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
|
|
|
103
102
|
if (cur) {
|
|
104
103
|
if (newNode) {
|
|
105
104
|
if (this._compare(cur.key, newNode.key) === CP.eq) {
|
|
106
|
-
cur.
|
|
105
|
+
cur.value = newNode.value;
|
|
107
106
|
cur.count += newNode.count;
|
|
108
107
|
this._setCount(this.count + newNode.count);
|
|
109
108
|
traversing = false;
|
|
@@ -113,7 +112,7 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
|
|
|
113
112
|
if (cur.left === undefined) {
|
|
114
113
|
//Add to the left of the current node
|
|
115
114
|
cur.left = newNode;
|
|
116
|
-
this.
|
|
115
|
+
this._size = this.size + 1;
|
|
117
116
|
this._setCount(this.count + newNode.count);
|
|
118
117
|
|
|
119
118
|
traversing = false;
|
|
@@ -127,7 +126,7 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
|
|
|
127
126
|
if (cur.right === undefined) {
|
|
128
127
|
//Add to the right of the current node
|
|
129
128
|
cur.right = newNode;
|
|
130
|
-
this.
|
|
129
|
+
this._size = this.size + 1;
|
|
131
130
|
this._setCount(this.count + newNode.count);
|
|
132
131
|
|
|
133
132
|
traversing = false;
|
|
@@ -162,7 +161,7 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
|
|
|
162
161
|
if (parent.left === undefined) {
|
|
163
162
|
parent.left = newNode;
|
|
164
163
|
if (newNode !== null) {
|
|
165
|
-
this.
|
|
164
|
+
this._size = this.size + 1;
|
|
166
165
|
this._setCount(this.count + newNode.count);
|
|
167
166
|
}
|
|
168
167
|
|
|
@@ -170,7 +169,7 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
|
|
|
170
169
|
} else if (parent.right === undefined) {
|
|
171
170
|
parent.right = newNode;
|
|
172
171
|
if (newNode !== null) {
|
|
173
|
-
this.
|
|
172
|
+
this._size = (this.size + 1);
|
|
174
173
|
this._setCount(this.count + newNode.count);
|
|
175
174
|
}
|
|
176
175
|
return parent.right;
|
|
@@ -199,7 +198,7 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
|
|
|
199
198
|
const keyOrNode = keysOrNodes[i];
|
|
200
199
|
|
|
201
200
|
if (keyOrNode instanceof TreeMultisetNode) {
|
|
202
|
-
inserted.push(this.add(keyOrNode.key, keyOrNode.
|
|
201
|
+
inserted.push(this.add(keyOrNode.key, keyOrNode.value, keyOrNode.count));
|
|
203
202
|
continue;
|
|
204
203
|
}
|
|
205
204
|
|
|
@@ -233,7 +232,7 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
|
|
|
233
232
|
if (l > r) return;
|
|
234
233
|
const m = l + Math.floor((r - l) / 2);
|
|
235
234
|
const midNode = sorted[m];
|
|
236
|
-
this.add(midNode.key, midNode.
|
|
235
|
+
this.add(midNode.key, midNode.value, midNode.count);
|
|
237
236
|
buildBalanceBST(l, m - 1);
|
|
238
237
|
buildBalanceBST(m + 1, r);
|
|
239
238
|
};
|
|
@@ -249,7 +248,7 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
|
|
|
249
248
|
if (l <= r) {
|
|
250
249
|
const m = l + Math.floor((r - l) / 2);
|
|
251
250
|
const midNode = sorted[m];
|
|
252
|
-
this.add(midNode.key, midNode.
|
|
251
|
+
this.add(midNode.key, midNode.value, midNode.count);
|
|
253
252
|
stack.push([m + 1, r]);
|
|
254
253
|
stack.push([l, m - 1]);
|
|
255
254
|
}
|
|
@@ -321,7 +320,7 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
|
|
|
321
320
|
}
|
|
322
321
|
}
|
|
323
322
|
}
|
|
324
|
-
this.
|
|
323
|
+
this._size = this.size - 1;
|
|
325
324
|
// TODO How to handle when the count of target node is lesser than current node's count
|
|
326
325
|
this._setCount(this.count - orgCurrent.count);
|
|
327
326
|
}
|
|
@@ -351,18 +350,18 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
|
|
|
351
350
|
* @returns The method is returning the `destNode` after swapping its properties with the `srcNode`.
|
|
352
351
|
*/
|
|
353
352
|
protected override _swap(srcNode: N, destNode: N): N {
|
|
354
|
-
const {key,
|
|
355
|
-
const tempNode = this.createNode(key,
|
|
353
|
+
const {key, value, count, height} = destNode;
|
|
354
|
+
const tempNode = this.createNode(key, value, count);
|
|
356
355
|
if (tempNode) {
|
|
357
356
|
tempNode.height = height;
|
|
358
357
|
|
|
359
358
|
destNode.key = srcNode.key;
|
|
360
|
-
destNode.
|
|
359
|
+
destNode.value = srcNode.value;
|
|
361
360
|
destNode.count = srcNode.count;
|
|
362
361
|
destNode.height = srcNode.height;
|
|
363
362
|
|
|
364
363
|
srcNode.key = tempNode.key;
|
|
365
|
-
srcNode.
|
|
364
|
+
srcNode.value = tempNode.value;
|
|
366
365
|
srcNode.count = tempNode.count;
|
|
367
366
|
srcNode.height = tempNode.height;
|
|
368
367
|
}
|