data-structure-typed 1.50.5 → 1.50.6
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/CHANGELOG.md +1 -1
- package/README.md +13 -13
- package/benchmark/report.html +13 -13
- package/benchmark/report.json +168 -144
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +19 -19
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +158 -135
- package/dist/cjs/data-structures/binary-tree/rb-tree.js +415 -386
- package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +1 -0
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +84 -76
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
- package/dist/mjs/data-structures/binary-tree/binary-tree.js +19 -19
- package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +158 -135
- package/dist/mjs/data-structures/binary-tree/rb-tree.js +412 -386
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.d.ts +1 -0
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.js +84 -76
- package/dist/umd/data-structure-typed.js +477 -431
- package/dist/umd/data-structure-typed.min.js +2 -2
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +1 -1
- package/src/data-structures/binary-tree/binary-tree.ts +19 -19
- package/src/data-structures/binary-tree/rb-tree.ts +437 -395
- package/src/data-structures/binary-tree/tree-multi-map.ts +85 -82
- package/test/performance/data-structures/binary-tree/rb-tree.test.ts +26 -16
- package/test/unit/data-structures/binary-tree/overall.test.ts +23 -21
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +168 -105
- package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +311 -192
|
@@ -51,6 +51,7 @@ export declare class TreeMultiMap<K = any, V = any, NODE extends TreeMultiMapNod
|
|
|
51
51
|
* @returns the sum of the count property of all nodes in the tree.
|
|
52
52
|
*/
|
|
53
53
|
get count(): number;
|
|
54
|
+
getMutableCount(): number;
|
|
54
55
|
/**
|
|
55
56
|
* The function creates a new TreeMultiMapNode object with the specified key, value, and count.
|
|
56
57
|
* @param {K} key - The key parameter represents the key of the node being created. It is of type K,
|
|
@@ -54,10 +54,12 @@ export class TreeMultiMap extends RedBlackTree {
|
|
|
54
54
|
* @returns the sum of the count property of all nodes in the tree.
|
|
55
55
|
*/
|
|
56
56
|
get count() {
|
|
57
|
+
return this._count;
|
|
58
|
+
}
|
|
59
|
+
getMutableCount() {
|
|
57
60
|
let sum = 0;
|
|
58
61
|
this.dfs(node => (sum += node.count));
|
|
59
62
|
return sum;
|
|
60
|
-
// return this._count;
|
|
61
63
|
}
|
|
62
64
|
/**
|
|
63
65
|
* The function creates a new TreeMultiMapNode object with the specified key, value, and count.
|
|
@@ -153,14 +155,15 @@ export class TreeMultiMap extends RedBlackTree {
|
|
|
153
155
|
*/
|
|
154
156
|
add(keyOrNodeOrEntry, value, count = 1) {
|
|
155
157
|
const newNode = this.keyValueOrEntryToNode(keyOrNodeOrEntry, value, count);
|
|
156
|
-
|
|
158
|
+
const orgCount = newNode?.count || 0;
|
|
159
|
+
const isSuccessAdded = super.add(newNode);
|
|
160
|
+
if (isSuccessAdded) {
|
|
161
|
+
this._count += orgCount;
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
157
165
|
return false;
|
|
158
|
-
const orgNodeCount = newNode?.count || 0;
|
|
159
|
-
const inserted = super.add(newNode);
|
|
160
|
-
if (inserted) {
|
|
161
|
-
this._count += orgNodeCount;
|
|
162
166
|
}
|
|
163
|
-
return true;
|
|
164
167
|
}
|
|
165
168
|
/**
|
|
166
169
|
* Time Complexity: O(log n)
|
|
@@ -187,86 +190,91 @@ export class TreeMultiMap extends RedBlackTree {
|
|
|
187
190
|
* @returns an array of BinaryTreeDeleteResult<NODE> objects.
|
|
188
191
|
*/
|
|
189
192
|
delete(identifier, callback = this._defaultOneParamCallback, ignoreCount = false) {
|
|
190
|
-
const deleteResults = [];
|
|
191
193
|
if (identifier === null)
|
|
192
|
-
return
|
|
193
|
-
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
if (node && identifier && callback(node) <= identifier) {
|
|
206
|
-
node = node.right;
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
node = node?.left;
|
|
210
|
-
}
|
|
194
|
+
return [];
|
|
195
|
+
const results = [];
|
|
196
|
+
const nodeToDelete = this.isRealNode(identifier) ? identifier : this.getNode(identifier, callback);
|
|
197
|
+
if (!nodeToDelete) {
|
|
198
|
+
return results;
|
|
199
|
+
}
|
|
200
|
+
let originalColor = nodeToDelete.color;
|
|
201
|
+
let replacementNode;
|
|
202
|
+
if (!this.isRealNode(nodeToDelete.left)) {
|
|
203
|
+
replacementNode = nodeToDelete.right;
|
|
204
|
+
if (ignoreCount || nodeToDelete.count <= 1) {
|
|
205
|
+
this._transplant(nodeToDelete, nodeToDelete.right);
|
|
206
|
+
this._count -= nodeToDelete.count;
|
|
211
207
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
208
|
+
else {
|
|
209
|
+
nodeToDelete.count--;
|
|
210
|
+
this._count--;
|
|
211
|
+
results.push({ deleted: nodeToDelete, needBalanced: undefined });
|
|
212
|
+
return results;
|
|
215
213
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
214
|
+
}
|
|
215
|
+
else if (!this.isRealNode(nodeToDelete.right)) {
|
|
216
|
+
replacementNode = nodeToDelete.left;
|
|
217
|
+
if (ignoreCount || nodeToDelete.count <= 1) {
|
|
218
|
+
this._transplant(nodeToDelete, nodeToDelete.left);
|
|
219
|
+
this._count -= nodeToDelete.count;
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
nodeToDelete.count--;
|
|
223
|
+
this._count--;
|
|
224
|
+
results.push({ deleted: nodeToDelete, needBalanced: undefined });
|
|
225
|
+
return results;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
const successor = this.getLeftMost(nodeToDelete.right);
|
|
230
|
+
if (successor) {
|
|
231
|
+
originalColor = successor.color;
|
|
232
|
+
replacementNode = successor.right;
|
|
233
|
+
if (successor.parent === nodeToDelete) {
|
|
234
|
+
if (this.isRealNode(replacementNode)) {
|
|
235
|
+
replacementNode.parent = successor;
|
|
236
|
+
}
|
|
230
237
|
}
|
|
231
238
|
else {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
currentNode = parentNode.right;
|
|
236
|
-
if (parentNode.parent === targetNode) {
|
|
237
|
-
// Target node's right child becomes its parent's left child
|
|
238
|
-
currentNode.parent = parentNode;
|
|
239
|
+
if (ignoreCount || nodeToDelete.count <= 1) {
|
|
240
|
+
this._transplant(successor, successor.right);
|
|
241
|
+
this._count -= nodeToDelete.count;
|
|
239
242
|
}
|
|
240
243
|
else {
|
|
241
|
-
|
|
242
|
-
this.
|
|
243
|
-
|
|
244
|
-
|
|
244
|
+
nodeToDelete.count--;
|
|
245
|
+
this._count--;
|
|
246
|
+
results.push({ deleted: nodeToDelete, needBalanced: undefined });
|
|
247
|
+
return results;
|
|
248
|
+
}
|
|
249
|
+
successor.right = nodeToDelete.right;
|
|
250
|
+
if (this.isRealNode(successor.right)) {
|
|
251
|
+
successor.right.parent = successor;
|
|
245
252
|
}
|
|
246
|
-
// Replace the target node with its in-order successor
|
|
247
|
-
this._rbTransplant(targetNode, parentNode);
|
|
248
|
-
parentNode.left = targetNode.left;
|
|
249
|
-
parentNode.left.parent = parentNode;
|
|
250
|
-
parentNode.color = targetNode.color;
|
|
251
253
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
this.
|
|
254
|
+
if (ignoreCount || nodeToDelete.count <= 1) {
|
|
255
|
+
this._transplant(nodeToDelete, successor);
|
|
256
|
+
this._count -= nodeToDelete.count;
|
|
255
257
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
this.
|
|
258
|
+
else {
|
|
259
|
+
nodeToDelete.count--;
|
|
260
|
+
this._count--;
|
|
261
|
+
results.push({ deleted: nodeToDelete, needBalanced: undefined });
|
|
262
|
+
return results;
|
|
263
|
+
}
|
|
264
|
+
successor.left = nodeToDelete.left;
|
|
265
|
+
if (this.isRealNode(successor.left)) {
|
|
266
|
+
successor.left.parent = successor;
|
|
267
|
+
}
|
|
268
|
+
successor.color = nodeToDelete.color;
|
|
264
269
|
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
+
}
|
|
271
|
+
this._size--;
|
|
272
|
+
// If the original color was black, fix the tree
|
|
273
|
+
if (originalColor === RBTNColor.BLACK) {
|
|
274
|
+
this._deleteFixup(replacementNode);
|
|
275
|
+
}
|
|
276
|
+
results.push({ deleted: nodeToDelete, needBalanced: undefined });
|
|
277
|
+
return results;
|
|
270
278
|
}
|
|
271
279
|
/**
|
|
272
280
|
* Time Complexity: O(1)
|