heap-typed 2.0.5 → 2.1.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 (101) hide show
  1. package/dist/data-structures/base/iterable-element-base.d.ts +186 -83
  2. package/dist/data-structures/base/iterable-element-base.js +149 -107
  3. package/dist/data-structures/base/iterable-entry-base.d.ts +95 -119
  4. package/dist/data-structures/base/iterable-entry-base.js +59 -116
  5. package/dist/data-structures/base/linear-base.d.ts +250 -192
  6. package/dist/data-structures/base/linear-base.js +137 -274
  7. package/dist/data-structures/binary-tree/avl-tree-counter.d.ts +126 -158
  8. package/dist/data-structures/binary-tree/avl-tree-counter.js +171 -205
  9. package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +100 -69
  10. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +135 -87
  11. package/dist/data-structures/binary-tree/avl-tree.d.ts +138 -149
  12. package/dist/data-structures/binary-tree/avl-tree.js +208 -195
  13. package/dist/data-structures/binary-tree/binary-tree.d.ts +476 -632
  14. package/dist/data-structures/binary-tree/binary-tree.js +598 -869
  15. package/dist/data-structures/binary-tree/bst.d.ts +258 -306
  16. package/dist/data-structures/binary-tree/bst.js +505 -481
  17. package/dist/data-structures/binary-tree/red-black-tree.d.ts +107 -179
  18. package/dist/data-structures/binary-tree/red-black-tree.js +114 -209
  19. package/dist/data-structures/binary-tree/tree-counter.d.ts +132 -154
  20. package/dist/data-structures/binary-tree/tree-counter.js +172 -203
  21. package/dist/data-structures/binary-tree/tree-multi-map.d.ts +72 -69
  22. package/dist/data-structures/binary-tree/tree-multi-map.js +105 -85
  23. package/dist/data-structures/graph/abstract-graph.d.ts +238 -233
  24. package/dist/data-structures/graph/abstract-graph.js +267 -237
  25. package/dist/data-structures/graph/directed-graph.d.ts +108 -224
  26. package/dist/data-structures/graph/directed-graph.js +146 -233
  27. package/dist/data-structures/graph/map-graph.d.ts +49 -55
  28. package/dist/data-structures/graph/map-graph.js +56 -59
  29. package/dist/data-structures/graph/undirected-graph.d.ts +103 -146
  30. package/dist/data-structures/graph/undirected-graph.js +129 -149
  31. package/dist/data-structures/hash/hash-map.d.ts +164 -338
  32. package/dist/data-structures/hash/hash-map.js +270 -457
  33. package/dist/data-structures/heap/heap.d.ts +214 -289
  34. package/dist/data-structures/heap/heap.js +340 -349
  35. package/dist/data-structures/heap/max-heap.d.ts +11 -47
  36. package/dist/data-structures/heap/max-heap.js +11 -66
  37. package/dist/data-structures/heap/min-heap.d.ts +12 -47
  38. package/dist/data-structures/heap/min-heap.js +11 -66
  39. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +231 -347
  40. package/dist/data-structures/linked-list/doubly-linked-list.js +368 -494
  41. package/dist/data-structures/linked-list/singly-linked-list.d.ts +261 -310
  42. package/dist/data-structures/linked-list/singly-linked-list.js +447 -466
  43. package/dist/data-structures/linked-list/skip-linked-list.d.ts +0 -107
  44. package/dist/data-structures/linked-list/skip-linked-list.js +0 -100
  45. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +12 -56
  46. package/dist/data-structures/priority-queue/max-priority-queue.js +11 -78
  47. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +11 -57
  48. package/dist/data-structures/priority-queue/min-priority-queue.js +10 -79
  49. package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -61
  50. package/dist/data-structures/priority-queue/priority-queue.js +8 -83
  51. package/dist/data-structures/queue/deque.d.ts +227 -254
  52. package/dist/data-structures/queue/deque.js +309 -348
  53. package/dist/data-structures/queue/queue.d.ts +180 -201
  54. package/dist/data-structures/queue/queue.js +265 -248
  55. package/dist/data-structures/stack/stack.d.ts +124 -102
  56. package/dist/data-structures/stack/stack.js +181 -125
  57. package/dist/data-structures/trie/trie.d.ts +164 -165
  58. package/dist/data-structures/trie/trie.js +189 -172
  59. package/dist/interfaces/binary-tree.d.ts +56 -6
  60. package/dist/interfaces/graph.d.ts +16 -0
  61. package/dist/types/data-structures/base/base.d.ts +1 -1
  62. package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -0
  63. package/dist/types/utils/utils.d.ts +1 -0
  64. package/dist/utils/utils.d.ts +1 -1
  65. package/dist/utils/utils.js +2 -1
  66. package/package.json +2 -2
  67. package/src/data-structures/base/iterable-element-base.ts +238 -115
  68. package/src/data-structures/base/iterable-entry-base.ts +96 -120
  69. package/src/data-structures/base/linear-base.ts +271 -277
  70. package/src/data-structures/binary-tree/avl-tree-counter.ts +198 -216
  71. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +192 -101
  72. package/src/data-structures/binary-tree/avl-tree.ts +239 -206
  73. package/src/data-structures/binary-tree/binary-tree.ts +664 -893
  74. package/src/data-structures/binary-tree/bst.ts +568 -570
  75. package/src/data-structures/binary-tree/red-black-tree.ts +161 -222
  76. package/src/data-structures/binary-tree/tree-counter.ts +199 -218
  77. package/src/data-structures/binary-tree/tree-multi-map.ts +131 -97
  78. package/src/data-structures/graph/abstract-graph.ts +339 -264
  79. package/src/data-structures/graph/directed-graph.ts +146 -236
  80. package/src/data-structures/graph/map-graph.ts +63 -60
  81. package/src/data-structures/graph/undirected-graph.ts +129 -152
  82. package/src/data-structures/hash/hash-map.ts +274 -496
  83. package/src/data-structures/heap/heap.ts +389 -402
  84. package/src/data-structures/heap/max-heap.ts +12 -76
  85. package/src/data-structures/heap/min-heap.ts +13 -76
  86. package/src/data-structures/linked-list/doubly-linked-list.ts +426 -530
  87. package/src/data-structures/linked-list/singly-linked-list.ts +495 -517
  88. package/src/data-structures/linked-list/skip-linked-list.ts +1 -108
  89. package/src/data-structures/priority-queue/max-priority-queue.ts +12 -87
  90. package/src/data-structures/priority-queue/min-priority-queue.ts +11 -88
  91. package/src/data-structures/priority-queue/priority-queue.ts +3 -92
  92. package/src/data-structures/queue/deque.ts +381 -357
  93. package/src/data-structures/queue/queue.ts +310 -264
  94. package/src/data-structures/stack/stack.ts +217 -131
  95. package/src/data-structures/trie/trie.ts +240 -175
  96. package/src/interfaces/binary-tree.ts +240 -6
  97. package/src/interfaces/graph.ts +37 -0
  98. package/src/types/data-structures/base/base.ts +5 -5
  99. package/src/types/data-structures/graph/abstract-graph.ts +5 -0
  100. package/src/types/utils/utils.ts +2 -0
  101. package/src/utils/utils.ts +9 -14
@@ -5,9 +5,11 @@
5
5
  * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
6
6
  * @license MIT License
7
7
  */
8
+
8
9
  import type {
9
10
  AVLTreeCounterOptions,
10
11
  BinaryTreeDeleteResult,
12
+ BinaryTreeOptions,
11
13
  BSTNOptKeyOrNode,
12
14
  EntryCallback,
13
15
  IterationType
@@ -15,18 +17,22 @@ import type {
15
17
  import { IBinaryTree } from '../../interfaces';
16
18
  import { AVLTree, AVLTreeNode } from './avl-tree';
17
19
 
20
+ /**
21
+ * AVL node with an extra 'count' field; keeps parent/child links.
22
+ * @remarks Time O(1), Space O(1)
23
+ * @template K
24
+ * @template V
25
+ */
18
26
  export class AVLTreeCounterNode<K = any, V = any> extends AVLTreeNode<K, V> {
19
27
  override parent?: AVLTreeCounterNode<K, V> = undefined;
20
28
 
21
29
  /**
22
- * The constructor function initializes a BinaryTreeNode object with a key, value, and count.
23
- * @param {K} key - The `key` parameter is of type `K` and represents the unique identifier
24
- * of the binary tree node.
25
- * @param {V} [value] - The `value` parameter is an optional parameter of type `V`. It represents the value of the binary
26
- * tree node. If no value is provided, it will be `undefined`.
27
- * @param {number} [count=1] - The `count` parameter is a number that represents the number of times a particular value
28
- * occurs in a binary tree node. It has a default value of 1, which means that if no value is provided for the `count`
29
- * parameter when creating a new instance of the `BinaryTreeNode` class.
30
+ * Create an AVL counter node.
31
+ * @remarks Time O(1), Space O(1)
32
+ * @param key - Key of the node.
33
+ * @param [value] - Associated value (ignored in map mode).
34
+ * @param [count] - Initial count for this node (default 1).
35
+ * @returns New AVLTreeCounterNode instance.
30
36
  */
31
37
  constructor(key: K, value?: V, count = 1) {
32
38
  super(key, value);
@@ -35,10 +41,21 @@ export class AVLTreeCounterNode<K = any, V = any> extends AVLTreeNode<K, V> {
35
41
 
36
42
  override _left?: AVLTreeCounterNode<K, V> | null | undefined = undefined;
37
43
 
44
+ /**
45
+ * Get the left child pointer.
46
+ * @remarks Time O(1), Space O(1)
47
+ * @returns Left child node, or null/undefined.
48
+ */
38
49
  override get left(): AVLTreeCounterNode<K, V> | null | undefined {
39
50
  return this._left;
40
51
  }
41
52
 
53
+ /**
54
+ * Set the left child and update its parent pointer.
55
+ * @remarks Time O(1), Space O(1)
56
+ * @param v - New left child node, or null/undefined.
57
+ * @returns void
58
+ */
42
59
  override set left(v: AVLTreeCounterNode<K, V> | null | undefined) {
43
60
  if (v) {
44
61
  v.parent = this;
@@ -48,10 +65,21 @@ export class AVLTreeCounterNode<K = any, V = any> extends AVLTreeNode<K, V> {
48
65
 
49
66
  override _right?: AVLTreeCounterNode<K, V> | null | undefined = undefined;
50
67
 
68
+ /**
69
+ * Get the right child pointer.
70
+ * @remarks Time O(1), Space O(1)
71
+ * @returns Right child node, or null/undefined.
72
+ */
51
73
  override get right(): AVLTreeCounterNode<K, V> | null | undefined {
52
74
  return this._right;
53
75
  }
54
76
 
77
+ /**
78
+ * Set the right child and update its parent pointer.
79
+ * @remarks Time O(1), Space O(1)
80
+ * @param v - New right child node, or null/undefined.
81
+ * @returns void
82
+ */
55
83
  override set right(v: AVLTreeCounterNode<K, V> | null | undefined) {
56
84
  if (v) {
57
85
  v.parent = this;
@@ -61,19 +89,22 @@ export class AVLTreeCounterNode<K = any, V = any> extends AVLTreeNode<K, V> {
61
89
  }
62
90
 
63
91
  /**
64
- * The only distinction between a AVLTreeCounter and a AVLTree lies in the ability of the former to store duplicate nodes through the utilization of counters.
92
+ * AVL tree that tracks an aggregate 'count' across nodes; supports balanced insert/delete and map-like mode.
93
+ * @remarks Time O(1), Space O(1)
94
+ * @template K
95
+ * @template V
96
+ * @template R
65
97
  */
66
- export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR = object>
67
- extends AVLTree<K, V, R, MK, MV, MR>
68
- implements IBinaryTree<K, V, R, MK, MV, MR>
98
+ export class AVLTreeCounter<K = any, V = any, R extends object = object>
99
+ extends AVLTree<K, V, R>
100
+ implements IBinaryTree<K, V, R>
69
101
  {
70
102
  /**
71
- * The constructor initializes a new AVLTreeCounter object with optional initial elements.
72
- * @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter is an
73
- * iterable object that can contain either keys, nodes, entries, or raw elements.
74
- * @param [options] - The `options` parameter is an optional object that can be used to customize the
75
- * behavior of the AVLTreeCounter. It can include properties such as `compareKeys` and
76
- * `compareValues` functions to define custom comparison logic for keys and values, respectively.
103
+ * Create a AVLTreeCounter instance
104
+ * @remarks Time O(n), Space O(n)
105
+ * @param keysNodesEntriesOrRaws
106
+ * @param options
107
+ * @returns New AVLTreeCounterNode instance.
77
108
  */
78
109
  constructor(
79
110
  keysNodesEntriesOrRaws: Iterable<
@@ -87,22 +118,14 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
87
118
 
88
119
  protected _count = 0;
89
120
 
90
- /**
91
- * The function calculates the sum of the count property of all nodes in a tree using depth-first
92
- * search.
93
- * @returns the sum of the count property of all nodes in the tree.
94
- */
95
121
  get count(): number {
96
122
  return this._count;
97
123
  }
98
124
 
99
125
  /**
100
- * Time Complexity: O(n)
101
- * Space Complexity: O(1)
102
- *
103
- * The function calculates the sum of the count property of all nodes in a tree using depth-first
104
- * search.
105
- * @returns the sum of the count property of all nodes in the tree.
126
+ * Compute the total count by traversing the tree (sums node.count).
127
+ * @remarks Time O(N), Space O(H)
128
+ * @returns Total count recomputed from nodes.
106
129
  */
107
130
  getComputedCount(): number {
108
131
  let sum = 0;
@@ -110,45 +133,14 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
110
133
  return sum;
111
134
  }
112
135
 
113
- /**
114
- * The function creates a new AVLTreeCounterNode with the specified key, value, and count.
115
- * @param {K} key - The key parameter represents the key of the node being created. It is of type K,
116
- * which is a generic type that can be replaced with any specific type when using the function.
117
- * @param {V} [value] - The `value` parameter is an optional parameter that represents the value
118
- * associated with the key in the node. It is of type `V`, which can be any data type.
119
- * @param {number} [count] - The `count` parameter represents the number of occurrences of a
120
- * key-value pair in the AVLTreeCounterNode. It is an optional parameter, so it can be omitted when
121
- * calling the `createNode` method. If provided, it specifies the initial count for the node.
122
- * @returns a new instance of the AVLTreeCounterNode class, casted as AVLTreeCounterNode<K, V>.
123
- */
124
- override createNode(key: K, value?: V, count?: number): AVLTreeCounterNode<K, V> {
136
+ override _createNode(key: K, value?: V, count?: number): AVLTreeCounterNode<K, V> {
125
137
  return new AVLTreeCounterNode(key, this._isMapMode ? undefined : value, count) as AVLTreeCounterNode<K, V>;
126
138
  }
127
139
 
128
140
  /**
129
- * The function creates a new AVLTreeCounter object with the specified options and returns it.
130
- * @param [options] - The `options` parameter is an optional object that contains additional
131
- * configuration options for creating the AVLTreeCounter. It can have the following properties:
132
- * @returns a new instance of the AVLTreeCounter class, with the specified options, as a TREE
133
- * object.
134
- */
135
- override createTree(options?: AVLTreeCounterOptions<K, V, R>) {
136
- return new AVLTreeCounter<K, V, R, MK, MV, MR>([], {
137
- iterationType: this.iterationType,
138
- isMapMode: this._isMapMode,
139
- specifyComparable: this._specifyComparable,
140
- toEntryFn: this._toEntryFn,
141
- isReverse: this._isReverse,
142
- ...options
143
- });
144
- }
145
-
146
- /**
147
- * The function checks if the input is an instance of AVLTreeCounterNode.
148
- * @param {K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined} keyNodeOrEntry - The parameter
149
- * `keyNodeOrEntry` can be of type `R` or `K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined`.
150
- * @returns a boolean value indicating whether the input parameter `keyNodeOrEntry` is
151
- * an instance of the `AVLTreeCounterNode` class.
141
+ * Type guard: check whether the input is an AVLTreeCounterNode.
142
+ * @remarks Time O(1), Space O(1)
143
+ * @returns True if the value is an AVLTreeCounterNode.
152
144
  */
153
145
  override isNode(
154
146
  keyNodeOrEntry: K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined
@@ -157,21 +149,12 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
157
149
  }
158
150
 
159
151
  /**
160
- * Time Complexity: O(log n)
161
- * Space Complexity: O(1)
162
- *
163
- * The function overrides the add method of a TypeScript class to add a new node to a data structure
164
- * and update the count.
165
- * @param {K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined} keyNodeOrEntry - The
166
- * `keyNodeOrEntry` parameter can accept a value of type `R`, which can be any type. It
167
- * can also accept a value of type `K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined`, which represents a key, node,
168
- * entry, or raw element
169
- * @param {V} [value] - The `value` parameter represents the value associated with the key in the
170
- * data structure. It is an optional parameter, so it can be omitted if not needed.
171
- * @param [count=1] - The `count` parameter represents the number of times the key-value pair should
172
- * be added to the data structure. By default, it is set to 1, meaning that the key-value pair will
173
- * be added once. However, you can specify a different value for `count` if you want to add
174
- * @returns a boolean value.
152
+ * Insert or increment a node and update aggregate count.
153
+ * @remarks Time O(log N), Space O(1)
154
+ * @param keyNodeOrEntry - Key, node, or [key, value] entry to insert.
155
+ * @param [value] - Value when a bare key is provided (ignored in map mode).
156
+ * @param [count] - How much to increase the node's count (default 1).
157
+ * @returns True if inserted/updated; false if ignored.
175
158
  */
176
159
  override add(
177
160
  keyNodeOrEntry: K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
@@ -190,23 +173,11 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
190
173
  }
191
174
 
192
175
  /**
193
- * Time Complexity: O(log n)
194
- * Space Complexity: O(1)
195
- *
196
- * The function overrides the delete method in a binary tree data structure, handling deletion of
197
- * nodes and maintaining balance in the tree.
198
- * @param {K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined} keyNodeOrEntry - The `predicate`
199
- * parameter in the `delete` method is used to specify the condition for deleting a node from the
200
- * binary tree. It can be a key, node, or entry that determines which
201
- * node(s) should be deleted.
202
- * @param [ignoreCount=false] - The `ignoreCount` parameter in the `override delete` method is a
203
- * boolean flag that determines whether to ignore the count of the node being deleted. If
204
- * `ignoreCount` is set to `true`, the method will delete the node regardless of its count. If
205
- * `ignoreCount` is set to
206
- * @returns The `delete` method overrides the default delete behavior in a binary tree data
207
- * structure. It takes a predicate or node to be deleted and an optional flag to ignore count. The
208
- * method returns an array of `BinaryTreeDeleteResult` objects, each containing information about the
209
- * deleted node and whether balancing is needed in the tree.
176
+ * Delete a node (or decrement its count) and rebalance if needed.
177
+ * @remarks Time O(log N), Space O(1)
178
+ * @param keyNodeOrEntry - Key, node, or [key, value] entry identifying the node.
179
+ * @param [ignoreCount] - If true, remove the node regardless of its count.
180
+ * @returns Array of deletion results including deleted node and a rebalance hint when present.
210
181
  */
211
182
  override delete(
212
183
  keyNodeOrEntry: K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
@@ -254,7 +225,7 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
254
225
  }
255
226
  }
256
227
  this._size = this._size - 1;
257
- // TODO How to handle when the count of target node is lesser than current node's count
228
+
258
229
  if (orgCurrent) this._count -= orgCurrent.count;
259
230
  }
260
231
 
@@ -268,11 +239,9 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
268
239
  }
269
240
 
270
241
  /**
271
- * Time Complexity: O(1)
272
- * Space Complexity: O(1)
273
- *
274
- * The "clear" function overrides the parent class's "clear" function and also resets the count to
275
- * zero.
242
+ * Remove all nodes and reset aggregate counters.
243
+ * @remarks Time O(N), Space O(1)
244
+ * @returns void
276
245
  */
277
246
  override clear() {
278
247
  super.clear();
@@ -280,115 +249,138 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
280
249
  }
281
250
 
282
251
  /**
283
- * Time Complexity: O(n log n)
284
- * Space Complexity: O(log n)
285
- *
286
- * The `perfectlyBalance` function takes a sorted array of nodes and builds a balanced binary search
287
- * tree using either a recursive or iterative approach.
288
- * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that
289
- * specifies the type of iteration to use when building the balanced binary search tree. It has a
290
- * default value of `this.iterationType`, which means it will use the iteration type currently set in
291
- * the object.
292
- * @returns The function `perfectlyBalance` returns a boolean value. It returns `true` if the
293
- * balancing operation is successful, and `false` if there are no nodes to balance.
252
+ * Rebuild the tree into a perfectly balanced form using in-order nodes.
253
+ * @remarks Time O(N), Space O(N)
254
+ * @param [iterationType] - Traversal style to use when constructing the balanced tree.
255
+ * @returns True if rebalancing succeeded (tree not empty).
294
256
  */
295
257
  override perfectlyBalance(iterationType: IterationType = this.iterationType): boolean {
296
- const sorted = this.dfs(node => node, 'IN'),
297
- n = sorted.length;
298
- if (sorted.length < 1) return false;
299
-
300
- this.clear();
301
-
302
- if (iterationType === 'RECURSIVE') {
303
- const buildBalanceBST = (l: number, r: number) => {
304
- if (l > r) return;
305
- const m = l + Math.floor((r - l) / 2);
306
- const midNode = sorted[m];
307
- if (this._isMapMode) this.add(midNode.key, undefined, midNode.count);
308
- else this.add(midNode.key, midNode.value, midNode.count);
309
- buildBalanceBST(l, m - 1);
310
- buildBalanceBST(m + 1, r);
311
- };
312
-
313
- buildBalanceBST(0, n - 1);
314
- return true;
315
- } else {
316
- const stack: [[number, number]] = [[0, n - 1]];
317
- while (stack.length > 0) {
318
- const popped = stack.pop();
319
- if (popped) {
320
- const [l, r] = popped;
321
- if (l <= r) {
322
- const m = l + Math.floor((r - l) / 2);
323
- const midNode = sorted[m];
324
- if (this._isMapMode) this.add(midNode.key, undefined, midNode.count);
325
- else this.add(midNode.key, midNode.value, midNode.count);
326
- stack.push([m + 1, r]);
327
- stack.push([l, m - 1]);
328
- }
329
- }
330
- }
331
- return true;
332
- }
258
+ const nodes = this.dfs(node => node, 'IN', false, this._root, iterationType);
259
+ const n = nodes.length;
260
+ if (n === 0) return false;
261
+
262
+ let total = 0;
263
+ for (const nd of nodes) total += nd ? nd.count : 0;
264
+
265
+ this._clearNodes();
266
+
267
+ const build = (l: number, r: number, parent?: any): any => {
268
+ if (l > r) return undefined;
269
+ const m = l + ((r - l) >> 1);
270
+ const root = nodes[m];
271
+ root.left = build(l, m - 1, root);
272
+ root.right = build(m + 1, r, root);
273
+ root.parent = parent;
274
+ const lh = root.left ? root.left.height : -1;
275
+ const rh = root.right ? root.right.height : -1;
276
+ root.height = Math.max(lh, rh) + 1;
277
+ return root;
278
+ };
279
+
280
+ const newRoot = build(0, n - 1, undefined);
281
+ this._setRoot(newRoot);
282
+ this._size = n;
283
+ this._count = total;
284
+ return true;
333
285
  }
334
286
 
335
287
  /**
336
- * Time complexity: O(n)
337
- * Space complexity: O(n)
338
- *
339
- * The function overrides the clone method to create a deep copy of a tree object.
340
- * @returns The `clone()` method is returning a cloned instance of the `TREE` object.
288
+ * Deep copy this tree, preserving map mode and aggregate counts.
289
+ * @remarks Time O(N), Space O(N)
290
+ * @returns A deep copy of this tree.
341
291
  */
342
- override clone() {
343
- const cloned = this.createTree();
344
- if (this._isMapMode) this.bfs(node => cloned.add(node.key, undefined, node.count));
345
- else this.bfs(node => cloned.add(node.key, node.value, node.count));
346
- if (this._isMapMode) cloned._store = this._store;
347
- return cloned;
292
+ override clone(): this {
293
+ const out = this._createInstance();
294
+
295
+ if (this._isMapMode) {
296
+ this.bfs(node => out.add(node.key, undefined, node.count));
297
+ } else {
298
+ this.bfs(node => out.add(node.key, node.value, node.count));
299
+ }
300
+
301
+ if (this._isMapMode) out._store = this._store;
302
+
303
+ return out as this;
348
304
  }
349
305
 
350
306
  /**
351
- * The `map` function in TypeScript overrides the default behavior to create a new AVLTreeCounter
352
- * with modified entries based on a provided callback.
353
- * @param callback - The `callback` parameter is a function that will be called for each entry in the
354
- * AVLTreeCounter. It takes four arguments:
355
- * @param [options] - The `options` parameter in the `override map` function is of type
356
- * `AVLTreeCounterOptions<MK, MV, MR>`. This parameter allows you to provide additional
357
- * configuration options when creating a new `AVLTreeCounter` instance within the `map` function.
358
- * These options
359
- * @param {any} [thisArg] - The `thisArg` parameter in the `override map` function is used to specify
360
- * the value of `this` when executing the `callback` function. It allows you to set the context
361
- * (value of `this`) for the callback function. This can be useful when you want to access properties
362
- * or
363
- * @returns The `map` method is returning a new `AVLTreeCounter` instance with the entries
364
- * transformed by the provided `callback` function. Each entry in the original tree is passed to the
365
- * `callback` function along with the index and the original tree itself. The transformed entries are
366
- * then added to the new `AVLTreeCounter` instance, which is returned at the end.
307
+ * Create a new AVLTreeCounter by mapping each [key, value] entry.
308
+ * @remarks Time O(N log N), Space O(N)
309
+ * @template MK
310
+ * @template MV
311
+ * @template MR
312
+ * @param callback - Function mapping (key, value, index, tree) → [newKey, newValue].
313
+ * @param [options] - Options for the output tree.
314
+ * @param [thisArg] - Value for `this` inside the callback.
315
+ * @returns A new AVLTreeCounter with mapped entries.
367
316
  */
368
- override map<MK, MV, MR>(
317
+ override map<MK = K, MV = V, MR extends object = object>(
369
318
  callback: EntryCallback<K, V | undefined, [MK, MV]>,
370
- options?: AVLTreeCounterOptions<MK, MV, MR>,
371
- thisArg?: any
319
+ options?: Partial<BinaryTreeOptions<MK, MV, MR>>,
320
+ thisArg?: unknown
372
321
  ): AVLTreeCounter<MK, MV, MR> {
373
- const newTree = new AVLTreeCounter<MK, MV, MR>([], options);
322
+ const out = this._createLike<MK, MV, MR>([], options);
323
+
374
324
  let index = 0;
375
325
  for (const [key, value] of this) {
376
- newTree.add(callback.call(thisArg, key, value, index++, this));
326
+ out.add(callback.call(thisArg, key, value, index++, this));
377
327
  }
378
- return newTree;
328
+ return out;
329
+ }
330
+
331
+ /**
332
+ * (Protected) Create an empty instance of the same concrete class.
333
+ * @remarks Time O(1), Space O(1)
334
+ * @template TK
335
+ * @template TV
336
+ * @template TR
337
+ * @param [options] - Optional constructor options for the like-kind instance.
338
+ * @returns An empty like-kind instance.
339
+ */
340
+ protected override _createInstance<TK = K, TV = V, TR extends object = R>(
341
+ options?: Partial<AVLTreeCounterOptions<TK, TV, TR>>
342
+ ): this {
343
+ const Ctor = this.constructor as unknown as new (
344
+ iter?: Iterable<
345
+ TK | AVLTreeCounterNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR
346
+ >,
347
+ opts?: AVLTreeCounterOptions<TK, TV, TR>
348
+ ) => AVLTreeCounter<TK, TV, TR>;
349
+ return new Ctor([], { ...this._snapshotOptions<TK, TV, TR>(), ...(options ?? {}) }) as unknown as this;
350
+ }
351
+
352
+ /**
353
+ * (Protected) Create a like-kind instance and seed it from an iterable.
354
+ * @remarks Time O(N log N), Space O(N)
355
+ * @template TK
356
+ * @template TV
357
+ * @template TR
358
+ * @param iter - Iterable used to seed the new tree.
359
+ * @param [options] - Options merged with the current snapshot.
360
+ * @returns A like-kind AVLTreeCounter built from the iterable.
361
+ */
362
+ protected override _createLike<TK = K, TV = V, TR extends object = R>(
363
+ iter: Iterable<
364
+ TK | AVLTreeCounterNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR
365
+ > = [],
366
+ options?: Partial<AVLTreeCounterOptions<TK, TV, TR>>
367
+ ): AVLTreeCounter<TK, TV, TR> {
368
+ const Ctor = this.constructor as unknown as new (
369
+ iter?: Iterable<
370
+ TK | AVLTreeCounterNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR
371
+ >,
372
+ opts?: AVLTreeCounterOptions<TK, TV, TR>
373
+ ) => AVLTreeCounter<TK, TV, TR>;
374
+ return new Ctor(iter, { ...this._snapshotOptions<TK, TV, TR>(), ...(options ?? {}) });
379
375
  }
380
376
 
381
377
  /**
382
- * The function `keyValueNodeEntryRawToNodeAndValue` converts a key, value, entry, or raw element into
383
- * a node object.
384
- * @param {K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined} keyNodeOrEntry - The
385
- * `keyNodeOrEntry` parameter can be of type `R` or `K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined`.
386
- * @param {V} [value] - The `value` parameter is an optional value that can be passed to the
387
- * `override` function. It represents the value associated with the key in the data structure. If no
388
- * value is provided, it will default to `undefined`.
389
- * @param [count=1] - The `count` parameter is an optional parameter that specifies the number of
390
- * times the key-value pair should be added to the data structure. If not provided, it defaults to 1.
391
- * @returns either a AVLTreeCounterNode<K, V> object or undefined.
378
+ * (Protected) Normalize input into a node plus its effective value and count.
379
+ * @remarks Time O(1), Space O(1)
380
+ * @param keyNodeOrEntry - Key, node, or [key, value] entry.
381
+ * @param [value] - Value used when a bare key is provided.
382
+ * @param [count] - Count increment to apply (default 1).
383
+ * @returns Tuple [node, value] where node may be undefined.
392
384
  */
393
385
  protected override _keyValueNodeOrEntryToNodeAndValue(
394
386
  keyNodeOrEntry: K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
@@ -402,24 +394,18 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
402
394
  const [key, entryValue] = keyNodeOrEntry;
403
395
  if (key === undefined || key === null) return [undefined, undefined];
404
396
  const finalValue = value ?? entryValue;
405
- return [this.createNode(key, finalValue, count), finalValue];
397
+ return [this._createNode(key, finalValue, count), finalValue];
406
398
  }
407
399
 
408
- return [this.createNode(keyNodeOrEntry, value, count), value];
400
+ return [this._createNode(keyNodeOrEntry, value, count), value];
409
401
  }
410
402
 
411
403
  /**
412
- * Time Complexity: O(1)
413
- * Space Complexity: O(1)
414
- *
415
- * The `_swapProperties` function swaps the properties (key, value, count, height) between two nodes
416
- * in a binary search tree.
417
- * @param {BSTNOptKeyOrNode<K, AVLTreeCounterNode<K, V>>} srcNode - The `srcNode` parameter represents the source node
418
- * that will be swapped with the `destNode`.
419
- * @param {BSTNOptKeyOrNode<K, AVLTreeCounterNode<K, V>>} destNode - The `destNode` parameter represents the destination
420
- * node where the properties will be swapped with the source node.
421
- * @returns The method is returning the `destNode` after swapping its properties with the `srcNode`.
422
- * If either `srcNode` or `destNode` is undefined, it returns `undefined`.
404
+ * (Protected) Swap keys/values/counters between the source and destination nodes.
405
+ * @remarks Time O(1), Space O(1)
406
+ * @param srcNode - Source node (or key) whose properties will be moved.
407
+ * @param destNode - Destination node (or key) to receive properties.
408
+ * @returns Destination node after swap, or undefined.
423
409
  */
424
410
  protected override _swapProperties(
425
411
  srcNode: BSTNOptKeyOrNode<K, AVLTreeCounterNode<K, V>>,
@@ -429,7 +415,7 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
429
415
  destNode = this.ensureNode(destNode);
430
416
  if (srcNode && destNode) {
431
417
  const { key, value, count, height } = destNode;
432
- const tempNode = this.createNode(key, value, count);
418
+ const tempNode = this._createNode(key, value, count);
433
419
  if (tempNode) {
434
420
  tempNode.height = height;
435
421
 
@@ -450,15 +436,11 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
450
436
  }
451
437
 
452
438
  /**
453
- * Time Complexity: O(1)
454
- * Space Complexity: O(1)
455
- *
456
- * The function replaces an old node with a new node and updates the count property of the new node.
457
- * @param {AVLTreeCounterNode<K, V>} oldNode - The oldNode parameter represents the node that needs to be replaced in the
458
- * data structure. It is of type AVLTreeCounterNode<K, V>.
459
- * @param {AVLTreeCounterNode<K, V>} newNode - The `newNode` parameter is an instance of the `AVLTreeCounterNode<K, V>` class.
460
- * @returns The method is returning the result of calling the `_replaceNode` method from the
461
- * superclass, which is of type `AVLTreeCounterNode<K, V>`.
439
+ * (Protected) Replace one node by another and adjust counters accordingly.
440
+ * @remarks Time O(1), Space O(1)
441
+ * @param oldNode - Node being replaced.
442
+ * @param newNode - Replacement node.
443
+ * @returns The new node after replacement.
462
444
  */
463
445
  protected override _replaceNode(
464
446
  oldNode: AVLTreeCounterNode<K, V>,