binary-tree-typed 1.53.7 → 1.54.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.
Files changed (68) hide show
  1. package/dist/common/index.js +5 -0
  2. package/dist/data-structures/base/iterable-entry-base.js +4 -4
  3. package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +34 -27
  4. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +63 -53
  5. package/dist/data-structures/binary-tree/avl-tree.d.ts +3 -14
  6. package/dist/data-structures/binary-tree/avl-tree.js +22 -25
  7. package/dist/data-structures/binary-tree/binary-tree.d.ts +33 -17
  8. package/dist/data-structures/binary-tree/binary-tree.js +45 -26
  9. package/dist/data-structures/binary-tree/bst.d.ts +67 -46
  10. package/dist/data-structures/binary-tree/bst.js +87 -54
  11. package/dist/data-structures/binary-tree/index.d.ts +1 -1
  12. package/dist/data-structures/binary-tree/index.js +1 -1
  13. package/dist/data-structures/binary-tree/{rb-tree.d.ts → red-black-tree.d.ts} +75 -16
  14. package/dist/data-structures/binary-tree/{rb-tree.js → red-black-tree.js} +93 -60
  15. package/dist/data-structures/binary-tree/tree-multi-map.d.ts +20 -16
  16. package/dist/data-structures/binary-tree/tree-multi-map.js +41 -28
  17. package/dist/data-structures/graph/abstract-graph.js +2 -2
  18. package/dist/data-structures/hash/hash-map.d.ts +31 -1
  19. package/dist/data-structures/hash/hash-map.js +35 -5
  20. package/dist/data-structures/heap/heap.d.ts +20 -3
  21. package/dist/data-structures/heap/heap.js +31 -11
  22. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +46 -11
  23. package/dist/data-structures/linked-list/doubly-linked-list.js +68 -21
  24. package/dist/data-structures/linked-list/singly-linked-list.d.ts +44 -11
  25. package/dist/data-structures/linked-list/singly-linked-list.js +70 -26
  26. package/dist/data-structures/queue/deque.d.ts +37 -8
  27. package/dist/data-structures/queue/deque.js +73 -29
  28. package/dist/data-structures/queue/queue.d.ts +41 -1
  29. package/dist/data-structures/queue/queue.js +51 -9
  30. package/dist/data-structures/stack/stack.d.ts +27 -10
  31. package/dist/data-structures/stack/stack.js +39 -20
  32. package/dist/data-structures/trie/trie.d.ts +8 -3
  33. package/dist/data-structures/trie/trie.js +8 -3
  34. package/dist/interfaces/binary-tree.d.ts +1 -1
  35. package/dist/types/data-structures/base/base.d.ts +1 -1
  36. package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +2 -2
  37. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +2 -2
  38. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +2 -2
  39. package/dist/types/data-structures/binary-tree/bst.d.ts +3 -3
  40. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +3 -3
  41. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +4 -4
  42. package/package.json +2 -2
  43. package/src/common/index.ts +7 -1
  44. package/src/data-structures/base/iterable-entry-base.ts +4 -4
  45. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +84 -65
  46. package/src/data-structures/binary-tree/avl-tree.ts +40 -34
  47. package/src/data-structures/binary-tree/binary-tree.ts +76 -32
  48. package/src/data-structures/binary-tree/bst.ts +121 -68
  49. package/src/data-structures/binary-tree/index.ts +1 -1
  50. package/src/data-structures/binary-tree/{rb-tree.ts → red-black-tree.ts} +116 -71
  51. package/src/data-structures/binary-tree/tree-multi-map.ts +59 -33
  52. package/src/data-structures/graph/abstract-graph.ts +2 -2
  53. package/src/data-structures/hash/hash-map.ts +37 -7
  54. package/src/data-structures/heap/heap.ts +33 -10
  55. package/src/data-structures/linked-list/doubly-linked-list.ts +75 -21
  56. package/src/data-structures/linked-list/singly-linked-list.ts +77 -27
  57. package/src/data-structures/queue/deque.ts +72 -28
  58. package/src/data-structures/queue/queue.ts +50 -7
  59. package/src/data-structures/stack/stack.ts +39 -20
  60. package/src/data-structures/trie/trie.ts +8 -3
  61. package/src/interfaces/binary-tree.ts +4 -1
  62. package/src/types/data-structures/base/base.ts +1 -1
  63. package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +2 -2
  64. package/src/types/data-structures/binary-tree/avl-tree.ts +2 -2
  65. package/src/types/data-structures/binary-tree/binary-tree.ts +2 -2
  66. package/src/types/data-structures/binary-tree/bst.ts +3 -3
  67. package/src/types/data-structures/binary-tree/rb-tree.ts +3 -3
  68. package/src/types/data-structures/binary-tree/tree-multi-map.ts +4 -4
@@ -2,9 +2,10 @@ import type {
2
2
  BinaryTreeDeleteResult,
3
3
  BTNRep,
4
4
  CRUD,
5
+ EntryCallback,
5
6
  OptNode,
6
7
  RBTNColor,
7
- RBTreeOptions,
8
+ RedBlackTreeOptions,
8
9
  RedBlackTreeNested,
9
10
  RedBlackTreeNodeNested
10
11
  } from '../../types';
@@ -31,39 +32,82 @@ export class RedBlackTreeNode<
31
32
  super(key, value);
32
33
  this._color = color;
33
34
  }
34
-
35
- protected _color: RBTNColor;
36
-
37
- /**
38
- * The function returns the color value of a variable.
39
- * @returns The color value stored in the private variable `_color`.
40
- */
41
- get color(): RBTNColor {
42
- return this._color;
43
- }
44
-
45
- /**
46
- * The function sets the color property to the specified value.
47
- * @param {RBTNColor} value - The value parameter is of type RBTNColor.
48
- */
49
- set color(value: RBTNColor) {
50
- this._color = value;
51
- }
52
35
  }
53
36
 
54
37
  /**
55
38
  * 1. Efficient self-balancing, but not completely balanced. Compared with AVLTree, the addition and deletion efficiency is high but the query efficiency is slightly lower.
56
39
  * 2. It is BST itself. Compared with Heap which is not completely ordered, RedBlackTree is completely ordered.
40
+ * @example
41
+ * // Find elements in a range
42
+ * const bst = new RedBlackTree<number>([10, 5, 15, 3, 7, 12, 18]);
43
+ * console.log(bst.search(new Range(5, 10))); // [5, 10, 7]
44
+ * console.log(bst.search(new Range(4, 12))); // [5, 10, 12, 7]
45
+ * console.log(bst.search(new Range(15, 20))); // [15, 18]
46
+ * @example
47
+ * // using Red-Black Tree as a price-based index for stock data
48
+ * // Define the structure of individual stock records
49
+ * interface StockRecord {
50
+ * price: number; // Stock price (key for indexing)
51
+ * symbol: string; // Stock ticker symbol
52
+ * volume: number; // Trade volume
53
+ * }
54
+ *
55
+ * // Simulate stock market data as it might come from an external feed
56
+ * const marketStockData: StockRecord[] = [
57
+ * { price: 142.5, symbol: 'AAPL', volume: 1000000 },
58
+ * { price: 335.2, symbol: 'MSFT', volume: 800000 },
59
+ * { price: 3285.04, symbol: 'AMZN', volume: 500000 },
60
+ * { price: 267.98, symbol: 'META', volume: 750000 },
61
+ * { price: 234.57, symbol: 'GOOGL', volume: 900000 }
62
+ * ];
63
+ *
64
+ * // Extend the stock record type to include metadata for database usage
65
+ * type StockTableRecord = StockRecord & { lastUpdated: Date };
66
+ *
67
+ * // Create a Red-Black Tree to index stock records by price
68
+ * // Simulates a database index with stock price as the key for quick lookups
69
+ * const priceIndex = new RedBlackTree<number, StockTableRecord, StockRecord>(marketStockData, {
70
+ * toEntryFn: stockRecord => [
71
+ * stockRecord.price, // Use stock price as the key
72
+ * {
73
+ * ...stockRecord,
74
+ * lastUpdated: new Date() // Add a timestamp for when the record was indexed
75
+ * }
76
+ * ]
77
+ * });
78
+ *
79
+ * // Query the stock with the highest price
80
+ * const highestPricedStock = priceIndex.getRightMost();
81
+ * console.log(priceIndex.get(highestPricedStock)?.symbol); // 'AMZN' // Amazon has the highest price
82
+ *
83
+ * // Query stocks within a specific price range (200 to 400)
84
+ * const stocksInRange = priceIndex.rangeSearch(
85
+ * [200, 400], // Price range
86
+ * node => priceIndex.get(node)?.symbol // Extract stock symbols for the result
87
+ * );
88
+ * console.log(stocksInRange); // ['GOOGL', 'MSFT', 'META']
57
89
  */
58
90
  export class RedBlackTree<
59
91
  K = any,
60
92
  V = any,
61
93
  R = object,
94
+ MK = any,
95
+ MV = any,
96
+ MR = object,
62
97
  NODE extends RedBlackTreeNode<K, V, NODE> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>,
63
- TREE extends RedBlackTree<K, V, R, NODE, TREE> = RedBlackTree<K, V, R, NODE, RedBlackTreeNested<K, V, R, NODE>>
98
+ TREE extends RedBlackTree<K, V, R, MK, MV, MR, NODE, TREE> = RedBlackTree<
99
+ K,
100
+ V,
101
+ R,
102
+ MK,
103
+ MV,
104
+ MR,
105
+ NODE,
106
+ RedBlackTreeNested<K, V, R, MK, MV, MR, NODE>
107
+ >
64
108
  >
65
- extends BST<K, V, R, NODE, TREE>
66
- implements IBinaryTree<K, V, R, NODE, TREE>
109
+ extends BST<K, V, R, MK, MV, MR, NODE, TREE>
110
+ implements IBinaryTree<K, V, R, MK, MV, MR, NODE, TREE>
67
111
  {
68
112
  /**
69
113
  * This is the constructor function for a Red-Black Tree data structure in TypeScript.
@@ -71,11 +115,11 @@ export class RedBlackTree<
71
115
  * iterable object that can contain either keys, nodes, entries, or raw elements. It is used to
72
116
  * initialize the RBTree with the provided elements.
73
117
  * @param [options] - The `options` parameter is an optional object that can be passed to the
74
- * constructor. It is of type `RBTreeOptions<K, V, R>`. This object can contain various options for
118
+ * constructor. It is of type `RedBlackTreeOptions<K, V, R>`. This object can contain various options for
75
119
  * configuring the behavior of the Red-Black Tree. The specific properties and their meanings would
76
120
  * depend on the implementation
77
121
  */
78
- constructor(keysNodesEntriesOrRaws: Iterable<R | BTNRep<K, V, NODE>> = [], options?: RBTreeOptions<K, V, R>) {
122
+ constructor(keysNodesEntriesOrRaws: Iterable<R | BTNRep<K, V, NODE>> = [], options?: RedBlackTreeOptions<K, V, R>) {
79
123
  super([], options);
80
124
 
81
125
  this._root = this.NIL;
@@ -119,11 +163,11 @@ export class RedBlackTree<
119
163
  * configuration options for creating the Red-Black Tree. It has the following properties:
120
164
  * @returns a new instance of a RedBlackTree object.
121
165
  */
122
- override createTree(options?: RBTreeOptions<K, V, R>): TREE {
123
- return new RedBlackTree<K, V, R, NODE, TREE>([], {
166
+ override createTree(options?: RedBlackTreeOptions<K, V, R>): TREE {
167
+ return new RedBlackTree<K, V, R, MK, MV, MR, NODE, TREE>([], {
124
168
  iterationType: this.iterationType,
125
169
  isMapMode: this._isMapMode,
126
- extractComparable: this._extractComparable,
170
+ specifyComparable: this._specifyComparable,
127
171
  toEntryFn: this._toEntryFn,
128
172
  ...options
129
173
  }) as TREE;
@@ -143,42 +187,6 @@ export class RedBlackTree<
143
187
  return keyNodeEntryOrRaw instanceof RedBlackTreeNode;
144
188
  }
145
189
 
146
- // /**
147
- // * Time Complexity: O(1)
148
- // * Space Complexity: O(1)
149
- // */
150
- //
151
- // /**
152
- // * Time Complexity: O(1)
153
- // * Space Complexity: O(1)
154
- // *
155
- // * The function `keyValueNodeEntryRawToNodeAndValue` takes a key, value, or entry and returns a node if it is
156
- // * valid, otherwise it returns undefined.
157
- // * @param {BTNRep<K, V, NODE>} keyNodeEntryOrRaw - The key, value, or entry to convert.
158
- // * @param {V} [value] - The value associated with the key (if `keyNodeEntryOrRaw` is a key).
159
- // * @returns {NODE | undefined} - The corresponding Red-Black Tree node, or `undefined` if conversion fails.
160
- // */
161
- // override keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R, value?: V): NODE | undefined {
162
- //
163
- // if (keyNodeEntryOrRaw === null || keyNodeEntryOrRaw === undefined) return;
164
- // if (this.isNode(keyNodeEntryOrRaw)) return keyNodeEntryOrRaw;
165
- //
166
- // if (this._toEntryFn) {
167
- // const [key, entryValue] = this._toEntryFn(keyNodeEntryOrRaw as R);
168
- // if (this.isKey(key)) return this.createNode(key, value ?? entryValue, 'RED');
169
- // }
170
- //
171
- // if (this.isEntry(keyNodeEntryOrRaw)) {
172
- // const [key, value] = keyNodeEntryOrRaw;
173
- // if (key === undefined || key === null) return;
174
- // else return this.createNode(key, value, 'RED');
175
- // }
176
- //
177
- // if (this.isKey(keyNodeEntryOrRaw)) return this.createNode(keyNodeEntryOrRaw, value, 'RED');
178
- //
179
- // return ;
180
- // }
181
-
182
190
  /**
183
191
  * Time Complexity: O(1)
184
192
  * Space Complexity: O(1)
@@ -207,7 +215,7 @@ export class RedBlackTree<
207
215
  * returns true. If the node cannot be added or updated, the method returns false.
208
216
  */
209
217
  override add(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R, value?: V): boolean {
210
- const [newNode, newValue] = this.keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
218
+ const [newNode, newValue] = this._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
211
219
  if (!this.isRealNode(newNode)) return false;
212
220
 
213
221
  const insertStatus = this._insert(newNode);
@@ -260,8 +268,10 @@ export class RedBlackTree<
260
268
  let replacementNode: NODE | undefined;
261
269
 
262
270
  if (!this.isRealNode(nodeToDelete.left)) {
263
- replacementNode = nodeToDelete.right;
264
- this._transplant(nodeToDelete, nodeToDelete.right);
271
+ if (nodeToDelete.right !== null) {
272
+ replacementNode = nodeToDelete.right;
273
+ this._transplant(nodeToDelete, nodeToDelete.right);
274
+ }
265
275
  } else if (!this.isRealNode(nodeToDelete.right)) {
266
276
  replacementNode = nodeToDelete.left;
267
277
  this._transplant(nodeToDelete, nodeToDelete.left);
@@ -269,15 +279,17 @@ export class RedBlackTree<
269
279
  const successor = this.getLeftMost(node => node, nodeToDelete.right);
270
280
  if (successor) {
271
281
  originalColor = successor.color;
272
- replacementNode = successor.right;
282
+ if (successor.right !== null) replacementNode = successor.right;
273
283
 
274
284
  if (successor.parent === nodeToDelete) {
275
285
  if (this.isRealNode(replacementNode)) {
276
286
  replacementNode.parent = successor;
277
287
  }
278
288
  } else {
279
- this._transplant(successor, successor.right);
280
- successor.right = nodeToDelete.right;
289
+ if (successor.right !== null) {
290
+ this._transplant(successor, successor.right);
291
+ successor.right = nodeToDelete.right;
292
+ }
281
293
  if (this.isRealNode(successor.right)) {
282
294
  successor.right.parent = successor;
283
295
  }
@@ -370,7 +382,7 @@ export class RedBlackTree<
370
382
 
371
383
  if (!parent) {
372
384
  this._setRoot(node);
373
- } else if (node.key < parent.key) {
385
+ } else if (this._compare(node.key, parent.key) < 0) {
374
386
  parent.left = node;
375
387
  } else {
376
388
  parent.right = node;
@@ -448,7 +460,7 @@ export class RedBlackTree<
448
460
  } else {
449
461
  // Symmetric case for the right child (left and right exchanged)
450
462
  // Follow the same logic as above with left and right exchanged
451
- const y: NODE | undefined = z?.parent?.parent?.left;
463
+ const y: NODE | undefined = z?.parent?.parent?.left ?? undefined;
452
464
  if (y?.color === 'RED') {
453
465
  z.parent.color = 'BLACK';
454
466
  y.color = 'BLACK';
@@ -625,4 +637,37 @@ export class RedBlackTree<
625
637
  x.right = y;
626
638
  y.parent = x;
627
639
  }
640
+
641
+ /**
642
+ * Time Complexity: O(n)
643
+ * Space Complexity: O(n)
644
+ *
645
+ * The `map` function in TypeScript overrides the default behavior to create a new Red-Black Tree by
646
+ * applying a callback to each entry in the original tree.
647
+ * @param callback - A function that will be called for each entry in the tree, with parameters
648
+ * representing the key, value, index, and the tree itself. It should return an entry for the new
649
+ * tree.
650
+ * @param [options] - The `options` parameter in the `map` method is of type `RedBlackTreeOptions<MK, MV,
651
+ * MR>`. This parameter allows you to specify additional options or configurations for the Red-Black
652
+ * Tree that will be created during the mapping process. These options could include things like
653
+ * custom comparators
654
+ * @param {any} [thisArg] - The `thisArg` parameter in the `override map` function is used to specify
655
+ * the value of `this` when executing the `callback` function. It allows you to set the context
656
+ * (value of `this`) for the callback function. This can be useful when you want to access properties
657
+ * or
658
+ * @returns A new Red-Black Tree is being returned, where each entry has been transformed using the
659
+ * provided callback function.
660
+ */
661
+ override map(
662
+ callback: EntryCallback<K, V | undefined, [MK, MV]>,
663
+ options?: RedBlackTreeOptions<MK, MV, MR>,
664
+ thisArg?: any
665
+ ): RedBlackTree<MK, MV, MR> {
666
+ const newTree = new RedBlackTree<MK, MV, MR>([], options);
667
+ let index = 0;
668
+ for (const [key, value] of this) {
669
+ newTree.add(callback.call(thisArg, key, value, index++, this));
670
+ }
671
+ return newTree;
672
+ }
628
673
  }
@@ -9,6 +9,7 @@ import type {
9
9
  BinaryTreeDeleteResult,
10
10
  BSTNOptKeyOrNode,
11
11
  BTNRep,
12
+ EntryCallback,
12
13
  IterationType,
13
14
  OptNode,
14
15
  RBTNColor,
@@ -17,7 +18,7 @@ import type {
17
18
  TreeMultiMapOptions
18
19
  } from '../../types';
19
20
  import { IBinaryTree } from '../../interfaces';
20
- import { RedBlackTree, RedBlackTreeNode } from './rb-tree';
21
+ import { RedBlackTree, RedBlackTreeNode } from './red-black-tree';
21
22
 
22
23
  export class TreeMultiMapNode<
23
24
  K = any,
@@ -40,36 +41,29 @@ export class TreeMultiMapNode<
40
41
  super(key, value, color);
41
42
  this.count = count;
42
43
  }
43
-
44
- protected _count: number = 1;
45
-
46
- /**
47
- * The function returns the value of the private variable _count.
48
- * @returns The count property of the object, which is of type number.
49
- */
50
- get count(): number {
51
- return this._count;
52
- }
53
-
54
- /**
55
- * The above function sets the value of the count property.
56
- * @param {number} value - The value parameter is of type number, which means it can accept any
57
- * numeric value.
58
- */
59
- set count(value: number) {
60
- this._count = value;
61
- }
62
44
  }
63
45
 
64
46
  export class TreeMultiMap<
65
47
  K = any,
66
48
  V = any,
67
49
  R = object,
50
+ MK = any,
51
+ MV = any,
52
+ MR = object,
68
53
  NODE extends TreeMultiMapNode<K, V, NODE> = TreeMultiMapNode<K, V, TreeMultiMapNodeNested<K, V>>,
69
- TREE extends TreeMultiMap<K, V, R, NODE, TREE> = TreeMultiMap<K, V, R, NODE, TreeMultiMapNested<K, V, R, NODE>>
54
+ TREE extends TreeMultiMap<K, V, R, MK, MV, MR, NODE, TREE> = TreeMultiMap<
55
+ K,
56
+ V,
57
+ R,
58
+ MK,
59
+ MV,
60
+ MR,
61
+ NODE,
62
+ TreeMultiMapNested<K, V, R, MK, MV, MR, NODE>
63
+ >
70
64
  >
71
- extends RedBlackTree<K, V, R, NODE, TREE>
72
- implements IBinaryTree<K, V, R, NODE, TREE>
65
+ extends RedBlackTree<K, V, R, MK, MV, MR, NODE, TREE>
66
+ implements IBinaryTree<K, V, R, MK, MV, MR, NODE, TREE>
73
67
  {
74
68
  /**
75
69
  * The constructor function initializes a TreeMultiMap object with optional initial data.
@@ -136,10 +130,10 @@ export class TreeMultiMap<
136
130
  * existing `iterationType` property. The returned value is casted as `TREE`.
137
131
  */
138
132
  override createTree(options?: TreeMultiMapOptions<K, V, R>): TREE {
139
- return new TreeMultiMap<K, V, R, NODE, TREE>([], {
133
+ return new TreeMultiMap<K, V, R, MK, MV, MR, NODE, TREE>([], {
140
134
  iterationType: this.iterationType,
141
135
  isMapMode: this._isMapMode,
142
- extractComparable: this._extractComparable,
136
+ specifyComparable: this._specifyComparable,
143
137
  toEntryFn: this._toEntryFn,
144
138
  ...options
145
139
  }) as TREE;
@@ -157,7 +151,7 @@ export class TreeMultiMap<
157
151
  * times the key-value pair should be added to the data structure. If not provided, it defaults to 1.
158
152
  * @returns either a NODE object or undefined.
159
153
  */
160
- override keyValueNodeEntryRawToNodeAndValue(
154
+ protected override _keyValueNodeEntryRawToNodeAndValue(
161
155
  keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
162
156
  value?: V,
163
157
  count = 1
@@ -212,7 +206,7 @@ export class TreeMultiMap<
212
206
  * was successful, and false otherwise.
213
207
  */
214
208
  override add(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R, value?: V, count = 1): boolean {
215
- const [newNode, newValue] = this.keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value, count);
209
+ const [newNode, newValue] = this._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value, count);
216
210
  const orgCount = newNode?.count || 0;
217
211
  const isSuccessAdded = super.add(newNode, newValue);
218
212
 
@@ -256,10 +250,12 @@ export class TreeMultiMap<
256
250
  let replacementNode: NODE | undefined;
257
251
 
258
252
  if (!this.isRealNode(nodeToDelete.left)) {
259
- replacementNode = nodeToDelete.right;
253
+ if (nodeToDelete.right !== null) replacementNode = nodeToDelete.right;
260
254
  if (ignoreCount || nodeToDelete.count <= 1) {
261
- this._transplant(nodeToDelete, nodeToDelete.right);
262
- this._count -= nodeToDelete.count;
255
+ if (nodeToDelete.right !== null) {
256
+ this._transplant(nodeToDelete, nodeToDelete.right);
257
+ this._count -= nodeToDelete.count;
258
+ }
263
259
  } else {
264
260
  nodeToDelete.count--;
265
261
  this._count--;
@@ -281,7 +277,7 @@ export class TreeMultiMap<
281
277
  const successor = this.getLeftMost(node => node, nodeToDelete.right);
282
278
  if (successor) {
283
279
  originalColor = successor.color;
284
- replacementNode = successor.right;
280
+ if (successor.right !== null) replacementNode = successor.right;
285
281
 
286
282
  if (successor.parent === nodeToDelete) {
287
283
  if (this.isRealNode(replacementNode)) {
@@ -289,8 +285,10 @@ export class TreeMultiMap<
289
285
  }
290
286
  } else {
291
287
  if (ignoreCount || nodeToDelete.count <= 1) {
292
- this._transplant(successor, successor.right);
293
- this._count -= nodeToDelete.count;
288
+ if (successor.right !== null) {
289
+ this._transplant(successor, successor.right);
290
+ this._count -= nodeToDelete.count;
291
+ }
294
292
  } else {
295
293
  nodeToDelete.count--;
296
294
  this._count--;
@@ -466,4 +464,32 @@ export class TreeMultiMap<
466
464
  newNode.count = oldNode.count + newNode.count;
467
465
  return super._replaceNode(oldNode, newNode);
468
466
  }
467
+
468
+ /**
469
+ * The `map` function in TypeScript overrides the default behavior to create a new TreeMultiMap with
470
+ * modified entries based on a provided callback.
471
+ * @param callback - The `callback` parameter is a function that will be called for each entry in the
472
+ * map. It takes four arguments:
473
+ * @param [options] - The `options` parameter in the `override map` function is of type
474
+ * `TreeMultiMapOptions<MK, MV, MR>`. This parameter allows you to provide additional configuration
475
+ * options when creating a new `TreeMultiMap` instance within the `map` function. These options could
476
+ * include things like
477
+ * @param {any} [thisArg] - The `thisArg` parameter in the `override map` function is used to specify
478
+ * the value of `this` when executing the `callback` function. It allows you to set the context
479
+ * (value of `this`) for the callback function when it is called within the `map` function. This
480
+ * @returns A new TreeMultiMap instance is being returned, which is populated with entries generated
481
+ * by the provided callback function.
482
+ */
483
+ override map(
484
+ callback: EntryCallback<K, V | undefined, [MK, MV]>,
485
+ options?: TreeMultiMapOptions<MK, MV, MR>,
486
+ thisArg?: any
487
+ ): TreeMultiMap<MK, MV, MR> {
488
+ const newTree = new TreeMultiMap<MK, MV, MR>([], options);
489
+ let index = 0;
490
+ for (const [key, value] of this) {
491
+ newTree.add(callback.call(thisArg, key, value, index++, this));
492
+ }
493
+ return newTree;
494
+ }
469
495
  }
@@ -947,7 +947,7 @@ export abstract class AbstractGraph<
947
947
  const filtered: [VertexKey, V | undefined][] = [];
948
948
  let index = 0;
949
949
  for (const [key, value] of this) {
950
- if (predicate.call(thisArg, value, key, index, this)) {
950
+ if (predicate.call(thisArg, key, value, index, this)) {
951
951
  filtered.push([key, value]);
952
952
  }
953
953
  index++;
@@ -972,7 +972,7 @@ export abstract class AbstractGraph<
972
972
  const mapped: T[] = [];
973
973
  let index = 0;
974
974
  for (const [key, value] of this) {
975
- mapped.push(callback.call(thisArg, value, key, index, this));
975
+ mapped.push(callback.call(thisArg, key, value, index, this));
976
976
  index++;
977
977
  }
978
978
  return mapped;
@@ -97,6 +97,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
97
97
  }
98
98
 
99
99
  /**
100
+ * Time Complexity: O(1)
101
+ * Space Complexity: O(1)
102
+ *
100
103
  * The function checks if a given element is an array with exactly two elements.
101
104
  * @param {any} rawElement - The `rawElement` parameter is of type `any`, which means it can be any
102
105
  * data type.
@@ -107,6 +110,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
107
110
  }
108
111
 
109
112
  /**
113
+ * Time Complexity: O(1)
114
+ * Space Complexity: O(1)
115
+ *
110
116
  * The function checks if the size of an object is equal to zero and returns a boolean value.
111
117
  * @returns A boolean value indicating whether the size of the object is 0 or not.
112
118
  */
@@ -115,6 +121,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
115
121
  }
116
122
 
117
123
  /**
124
+ * Time Complexity: O(1)
125
+ * Space Complexity: O(1)
126
+ *
118
127
  * The clear() function resets the state of an object by clearing its internal store, object map, and
119
128
  * size.
120
129
  */
@@ -125,6 +134,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
125
134
  }
126
135
 
127
136
  /**
137
+ * Time Complexity: O(1)
138
+ * Space Complexity: O(1)
139
+ *
128
140
  * The `set` function adds a key-value pair to a map-like data structure, incrementing the size if
129
141
  * the key is not already present.
130
142
  * @param {K} key - The key parameter is the key used to identify the value in the data structure. It
@@ -150,6 +162,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
150
162
  }
151
163
 
152
164
  /**
165
+ * Time Complexity: O(k)
166
+ * Space Complexity: O(k)
167
+ *
153
168
  * The function `setMany` takes an iterable collection of objects, maps each object to a key-value
154
169
  * pair using a mapping function, and sets each key-value pair in the current object.
155
170
  * @param entryOrRawElements - The `entryOrRawElements` parameter is an iterable collection of elements of a type
@@ -175,6 +190,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
175
190
  }
176
191
 
177
192
  /**
193
+ * Time Complexity: O(1)
194
+ * Space Complexity: O(1)
195
+ *
178
196
  * The `get` function retrieves a value from a map based on a given key, either from an object map or
179
197
  * a string map.
180
198
  * @param {K} key - The `key` parameter is the key used to retrieve a value from the map. It can be
@@ -192,6 +210,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
192
210
  }
193
211
 
194
212
  /**
213
+ * Time Complexity: O(1)
214
+ * Space Complexity: O(1)
215
+ *
195
216
  * The `has` function checks if a given key exists in the `_objMap` or `_store` based on whether it
196
217
  * is an object key or not.
197
218
  * @param {K} key - The parameter "key" is of type K, which means it can be any type.
@@ -207,6 +228,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
207
228
  }
208
229
 
209
230
  /**
231
+ * Time Complexity: O(1)
232
+ * Space Complexity: O(1)
233
+ *
210
234
  * The `delete` function removes an element from a map-like data structure based on the provided key.
211
235
  * @param {K} key - The `key` parameter is the key of the element that you want to delete from the
212
236
  * data structure.
@@ -263,7 +287,7 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
263
287
  const resultMap = new HashMap<K, VM>();
264
288
  let index = 0;
265
289
  for (const [key, value] of this) {
266
- resultMap.set(key, callbackfn.call(thisArg, value, key, index++, this));
290
+ resultMap.set(key, callbackfn.call(thisArg, key, value, index++, this));
267
291
  }
268
292
  return resultMap;
269
293
  }
@@ -288,7 +312,7 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
288
312
  const filteredMap = new HashMap<K, V>();
289
313
  let index = 0;
290
314
  for (const [key, value] of this) {
291
- if (predicate.call(thisArg, value, key, index++, this)) {
315
+ if (predicate.call(thisArg, key, value, index++, this)) {
292
316
  filteredMap.set(key, value);
293
317
  }
294
318
  }
@@ -579,6 +603,9 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
579
603
  }
580
604
 
581
605
  /**
606
+ * Time Complexity: O(k)
607
+ * Space Complexity: O(k)
608
+ *
582
609
  * The function `setMany` takes an iterable collection, converts each element into a key-value pair
583
610
  * using a provided function, and sets each key-value pair in the current object, returning an array
584
611
  * of booleans indicating the success of each set operation.
@@ -605,6 +632,9 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
605
632
  }
606
633
 
607
634
  /**
635
+ * Time Complexity: O(1)
636
+ * Space Complexity: O(1)
637
+ *
608
638
  * The function checks if a given key exists in a map, using different logic depending on whether the
609
639
  * key is a weak key or not.
610
640
  * @param {K} key - The `key` parameter is the key that is being checked for existence in the map.
@@ -796,7 +826,7 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
796
826
  const filteredMap = new LinkedHashMap<K, V>();
797
827
  let index = 0;
798
828
  for (const [key, value] of this) {
799
- if (predicate.call(thisArg, value, key, index, this)) {
829
+ if (predicate.call(thisArg, key, value, index, this)) {
800
830
  filteredMap.set(key, value);
801
831
  }
802
832
  index++;
@@ -821,12 +851,12 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
821
851
  * @returns a new `LinkedHashMap` object with the values mapped according to the provided callback
822
852
  * function.
823
853
  */
824
- map<VM>(callback: EntryCallback<K, V, VM>, thisArg?: any): LinkedHashMap<K, VM> {
825
- const mappedMap = new LinkedHashMap<K, VM>();
854
+ map<MK, MV>(callback: EntryCallback<K, V, [MK, MV]>, thisArg?: any): LinkedHashMap<MK, MV> {
855
+ const mappedMap = new LinkedHashMap<MK, MV>();
826
856
  let index = 0;
827
857
  for (const [key, value] of this) {
828
- const newValue = callback.call(thisArg, value, key, index, this);
829
- mappedMap.set(key, newValue);
858
+ const [newKey, newValue] = callback.call(thisArg, key, value, index, this);
859
+ mappedMap.set(newKey, newValue);
830
860
  index++;
831
861
  }
832
862
  return mappedMap;
@@ -207,12 +207,7 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R, Heap<E, R>
207
207
  if (comparator) this._comparator = comparator;
208
208
  }
209
209
 
210
- if (elements) {
211
- for (const el of elements) {
212
- if (this.toElementFn) this.add(this.toElementFn(el as R));
213
- else this.add(el as E);
214
- }
215
- }
210
+ this.addMany(elements);
216
211
  }
217
212
 
218
213
  protected _elements: E[] = [];
@@ -254,14 +249,42 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R, Heap<E, R>
254
249
  * Time Complexity: O(log n)
255
250
  * Space Complexity: O(1)
256
251
  *
257
- * Insert an element into the heap and maintain the heap properties.
258
- * @param element - The element to be inserted.
252
+ * The add function pushes an element into an array and then triggers a bubble-up operation.
253
+ * @param {E} element - The `element` parameter represents the element that you want to add to the
254
+ * data structure.
255
+ * @returns The `add` method is returning a boolean value, which is the result of calling the
256
+ * `_bubbleUp` method with the index `this.elements.length - 1` as an argument.
259
257
  */
260
258
  add(element: E): boolean {
261
- this._elements.push(element);
259
+ this._elements.push(element as E);
262
260
  return this._bubbleUp(this.elements.length - 1);
263
261
  }
264
262
 
263
+ /**
264
+ * Time Complexity: O(k log n)
265
+ * Space Complexity: O(1)
266
+ *
267
+ * The `addMany` function iterates over elements and adds them to a collection, returning an array of
268
+ * boolean values indicating success or failure.
269
+ * @param {Iterable<E> | Iterable<R>} elements - The `elements` parameter in the `addMany` method is
270
+ * an iterable containing elements of type `E` or `R`. The method iterates over each element in the
271
+ * iterable and adds them to the data structure. If a transformation function `_toElementFn` is
272
+ * provided, it transforms the element
273
+ * @returns The `addMany` method returns an array of boolean values indicating whether each element
274
+ * in the input iterable was successfully added to the data structure.
275
+ */
276
+ addMany(elements: Iterable<E> | Iterable<R>): boolean[] {
277
+ const ans: boolean[] = [];
278
+ for (const el of elements) {
279
+ if (this._toElementFn) {
280
+ ans.push(this.add(this._toElementFn(el as R)));
281
+ continue;
282
+ }
283
+ ans.push(this.add(el as E));
284
+ }
285
+ return ans;
286
+ }
287
+
265
288
  /**
266
289
  * Time Complexity: O(log n)
267
290
  * Space Complexity: O(1)
@@ -473,7 +496,7 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R, Heap<E, R>
473
496
  }
474
497
 
475
498
  /**
476
- * Time Complexity: O(n log n)
499
+ * Time Complexity: O(n)
477
500
  * Space Complexity: O(n)
478
501
  *
479
502
  * The `map` function creates a new heap by applying a callback function to each element of the