binary-tree-typed 2.5.0 → 2.5.2

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 (90) hide show
  1. package/dist/cjs/index.cjs +771 -68
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs-legacy/index.cjs +771 -68
  4. package/dist/cjs-legacy/index.cjs.map +1 -1
  5. package/dist/esm/index.mjs +771 -69
  6. package/dist/esm/index.mjs.map +1 -1
  7. package/dist/esm-legacy/index.mjs +771 -69
  8. package/dist/esm-legacy/index.mjs.map +1 -1
  9. package/dist/types/common/error.d.ts +9 -0
  10. package/dist/types/common/index.d.ts +1 -1
  11. package/dist/types/data-structures/base/index.d.ts +1 -0
  12. package/dist/types/data-structures/base/iterable-entry-base.d.ts +8 -8
  13. package/dist/types/data-structures/base/linear-base.d.ts +3 -3
  14. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +288 -0
  15. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +336 -0
  16. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +618 -18
  17. package/dist/types/data-structures/binary-tree/bst.d.ts +676 -1
  18. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +456 -0
  19. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +144 -1
  20. package/dist/types/data-structures/binary-tree/tree-map.d.ts +3307 -399
  21. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +3285 -360
  22. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +2674 -325
  23. package/dist/types/data-structures/binary-tree/tree-set.d.ts +3072 -287
  24. package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -4
  25. package/dist/types/data-structures/graph/directed-graph.d.ts +240 -0
  26. package/dist/types/data-structures/graph/undirected-graph.d.ts +216 -0
  27. package/dist/types/data-structures/hash/hash-map.d.ts +274 -10
  28. package/dist/types/data-structures/heap/heap.d.ts +336 -0
  29. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +411 -3
  30. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +363 -3
  31. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +434 -2
  32. package/dist/types/data-structures/matrix/matrix.d.ts +192 -0
  33. package/dist/types/data-structures/queue/deque.d.ts +364 -4
  34. package/dist/types/data-structures/queue/queue.d.ts +288 -0
  35. package/dist/types/data-structures/stack/stack.d.ts +240 -0
  36. package/dist/types/data-structures/trie/trie.d.ts +292 -4
  37. package/dist/types/interfaces/graph.d.ts +1 -1
  38. package/dist/types/types/common.d.ts +2 -2
  39. package/dist/types/types/data-structures/binary-tree/bst.d.ts +1 -0
  40. package/dist/types/types/data-structures/binary-tree/tree-map.d.ts +5 -0
  41. package/dist/types/types/data-structures/binary-tree/tree-multi-set.d.ts +4 -0
  42. package/dist/types/types/data-structures/binary-tree/tree-set.d.ts +4 -0
  43. package/dist/types/types/data-structures/heap/heap.d.ts +1 -0
  44. package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +1 -0
  45. package/dist/types/types/utils/validate-type.d.ts +4 -4
  46. package/dist/umd/binary-tree-typed.js +773 -71
  47. package/dist/umd/binary-tree-typed.js.map +1 -1
  48. package/dist/umd/binary-tree-typed.min.js +5 -5
  49. package/dist/umd/binary-tree-typed.min.js.map +1 -1
  50. package/package.json +2 -2
  51. package/src/common/error.ts +19 -1
  52. package/src/common/index.ts +1 -1
  53. package/src/data-structures/base/index.ts +1 -0
  54. package/src/data-structures/base/iterable-element-base.ts +3 -2
  55. package/src/data-structures/base/iterable-entry-base.ts +8 -8
  56. package/src/data-structures/base/linear-base.ts +3 -3
  57. package/src/data-structures/binary-tree/avl-tree.ts +299 -0
  58. package/src/data-structures/binary-tree/binary-indexed-tree.ts +341 -5
  59. package/src/data-structures/binary-tree/binary-tree.ts +606 -6
  60. package/src/data-structures/binary-tree/bst.ts +946 -7
  61. package/src/data-structures/binary-tree/red-black-tree.ts +472 -0
  62. package/src/data-structures/binary-tree/segment-tree.ts +145 -2
  63. package/src/data-structures/binary-tree/tree-map.ts +3423 -499
  64. package/src/data-structures/binary-tree/tree-multi-map.ts +3537 -596
  65. package/src/data-structures/binary-tree/tree-multi-set.ts +2855 -495
  66. package/src/data-structures/binary-tree/tree-set.ts +3209 -413
  67. package/src/data-structures/graph/abstract-graph.ts +6 -6
  68. package/src/data-structures/graph/directed-graph.ts +240 -0
  69. package/src/data-structures/graph/undirected-graph.ts +216 -0
  70. package/src/data-structures/hash/hash-map.ts +281 -19
  71. package/src/data-structures/heap/heap.ts +340 -4
  72. package/src/data-structures/heap/max-heap.ts +2 -2
  73. package/src/data-structures/linked-list/doubly-linked-list.ts +411 -3
  74. package/src/data-structures/linked-list/singly-linked-list.ts +363 -3
  75. package/src/data-structures/linked-list/skip-linked-list.ts +439 -7
  76. package/src/data-structures/matrix/matrix.ts +202 -10
  77. package/src/data-structures/priority-queue/max-priority-queue.ts +2 -2
  78. package/src/data-structures/queue/deque.ts +365 -5
  79. package/src/data-structures/queue/queue.ts +288 -0
  80. package/src/data-structures/stack/stack.ts +240 -0
  81. package/src/data-structures/trie/trie.ts +295 -7
  82. package/src/interfaces/graph.ts +1 -1
  83. package/src/types/common.ts +2 -2
  84. package/src/types/data-structures/binary-tree/bst.ts +1 -0
  85. package/src/types/data-structures/binary-tree/tree-map.ts +6 -0
  86. package/src/types/data-structures/binary-tree/tree-multi-set.ts +5 -0
  87. package/src/types/data-structures/binary-tree/tree-set.ts +5 -0
  88. package/src/types/data-structures/heap/heap.ts +1 -0
  89. package/src/types/data-structures/priority-queue/priority-queue.ts +1 -0
  90. package/src/types/utils/validate-type.ts +4 -4
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  import type { Comparator, TreeMultiSetOptions } from '../../types';
12
- import { ERR } from '../../common';
12
+ import { ERR, raise } from '../../common';
13
13
  import { RedBlackTree } from './red-black-tree';
14
14
  import { TreeSet } from './tree-set';
15
15
 
@@ -35,7 +35,7 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
35
35
  const toElementFn = options.toElementFn;
36
36
  const comparator = options.comparator ?? TreeSet.createDefaultComparator<K>();
37
37
  this.#isDefaultComparator = options.comparator === undefined;
38
- this.#core = new RedBlackTree<K, number>([], { comparator, isMapMode: options.isMapMode });
38
+ this.#core = new RedBlackTree<K, number>([], { comparator, isMapMode: options.isMapMode, enableOrderStatistic: options.enableOrderStatistic });
39
39
 
40
40
  for (const item of elements) {
41
41
  const k = toElementFn ? toElementFn(item as R) : (item as K);
@@ -51,18 +51,18 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
51
51
  if (!this.#isDefaultComparator) return;
52
52
 
53
53
  if (typeof key === 'number') {
54
- if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN('TreeMultiSet'));
54
+ if (Number.isNaN(key)) raise(TypeError, ERR.invalidNaN('TreeMultiSet'));
55
55
  return;
56
56
  }
57
57
 
58
58
  if (typeof key === 'string') return;
59
59
 
60
60
  if (key instanceof Date) {
61
- if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate('TreeMultiSet'));
61
+ if (Number.isNaN(key.getTime())) raise(TypeError, ERR.invalidDate('TreeMultiSet'));
62
62
  return;
63
63
  }
64
64
 
65
- throw new TypeError(ERR.comparatorRequired('TreeMultiSet'));
65
+ raise(TypeError, ERR.comparatorRequired('TreeMultiSet'));
66
66
  }
67
67
 
68
68
  /**
@@ -70,7 +70,7 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
70
70
  * @remarks Time O(1), Space O(1)
71
71
  */
72
72
  private _validateCount(n: number): void {
73
- if (!Number.isSafeInteger(n) || n < 0) throw new RangeError(ERR.invalidArgument('count must be a safe integer >= 0.', 'TreeMultiSet'));
73
+ if (!Number.isSafeInteger(n) || n < 0) raise(RangeError, ERR.invalidArgument('count must be a safe integer >= 0.', 'TreeMultiSet'));
74
74
  }
75
75
 
76
76
  /**
@@ -86,6 +86,30 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
86
86
  * @remarks Time O(1), Space O(1)
87
87
 
88
88
 
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+
101
+
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+
110
+
111
+
112
+
89
113
  * @example
90
114
  * // Unique key count
91
115
  * const ms = new TreeMultiSet<number>();
@@ -138,17 +162,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
138
162
 
139
163
 
140
164
 
141
- * @example
142
- * // Check empty
143
- * console.log(new TreeMultiSet().isEmpty()); // true;
144
- */
145
- isEmpty(): boolean {
146
- return this.size === 0;
147
- }
148
-
149
- /**
150
- * Whether the multiset contains the given key.
151
- * @remarks Time O(log n), Space O(1)
152
165
 
153
166
 
154
167
 
@@ -190,38 +203,8 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
190
203
 
191
204
 
192
205
 
193
- * @example
194
- * // Check existence
195
- * const ms = new TreeMultiSet<number>();
196
- * ms.add(1);
197
- * console.log(ms.has(1)); // true;
198
- * console.log(ms.has(2)); // false;
199
- */
200
- has(key: K): boolean {
201
- this._validateKey(key);
202
- return this.count(key) > 0;
203
- }
204
-
205
- /**
206
- * Returns the count of occurrences for the given key.
207
- * @remarks Time O(log n), Space O(1)
208
206
 
209
207
 
210
- * @example
211
- * // Get occurrence count
212
- * const ms = new TreeMultiSet<number>();
213
- * ms.add(1, 5);
214
- * console.log(ms.count(1)); // 5;
215
- */
216
- count(key: K): number {
217
- this._validateKey(key);
218
- return this.#core.get(key) ?? 0;
219
- }
220
-
221
- /**
222
- * Add `n` occurrences of `key`.
223
- * @returns True if the multiset changed.
224
- * @remarks Time O(log n), Space O(1)
225
208
 
226
209
 
227
210
 
@@ -254,60 +237,10 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
254
237
 
255
238
 
256
239
 
257
- * @example
258
- * // Add elements
259
- * const ms = new TreeMultiSet<number>();
260
- * ms.add(1);
261
- * ms.add(1);
262
- * ms.add(2);
263
- * console.log(ms.count(1)); // 2;
264
- * console.log(ms.size); // 3;
265
- */
266
- add(key: K, n = 1): boolean {
267
- this._validateKey(key);
268
- this._validateCount(n);
269
- if (n === 0) return false;
270
-
271
- const old = this.#core.get(key) ?? 0;
272
- const next = old + n;
273
- this.#core.set(key, next);
274
- this._size += n;
275
- return true;
276
- }
277
-
278
- /**
279
- * Set count for `key` to exactly `n`.
280
- * @returns True if changed.
281
- * @remarks Time O(log n), Space O(1)
282
240
 
283
241
 
284
- * @example
285
- * // Set occurrence count
286
- * const ms = new TreeMultiSet<number>();
287
- * ms.setCount(1, 3);
288
- * console.log(ms.count(1)); // 3;
289
- */
290
- setCount(key: K, n: number): boolean {
291
- this._validateKey(key);
292
- this._validateCount(n);
293
-
294
- const old = this.#core.get(key) ?? 0;
295
- if (old === n) return false;
296
-
297
- if (n === 0) {
298
- if (old !== 0) this.#core.delete(key);
299
- } else {
300
- this.#core.set(key, n);
301
- }
302
-
303
- this._size += n - old;
304
- return true;
305
- }
306
-
307
- /**
308
- * Delete `n` occurrences of `key` (default 1).
309
- * @returns True if any occurrence was removed.
310
- * @remarks Time O(log n), Space O(1)
242
+
243
+
311
244
 
312
245
 
313
246
 
@@ -350,71 +283,20 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
350
283
 
351
284
 
352
285
  * @example
353
- * // Remove one occurrence
354
- * const ms = new TreeMultiSet<number>();
355
- * ms.add(1, 3);
356
- * ms.delete(1);
357
- * console.log(ms.count(1)); // 2;
286
+ * // Check empty
287
+ * console.log(new TreeMultiSet().isEmpty()); // true;
358
288
  */
359
- delete(key: K, n = 1): boolean {
360
- this._validateKey(key);
361
- this._validateCount(n);
362
- if (n === 0) return false;
363
-
364
- const old = this.#core.get(key) ?? 0;
365
- if (old === 0) return false;
366
-
367
- const removed = Math.min(old, n);
368
- const next = old - removed;
369
-
370
- if (next === 0) this.#core.delete(key);
371
- else this.#core.set(key, next);
372
-
373
- this._size -= removed;
374
- return true;
289
+ isEmpty(): boolean {
290
+ return this.size === 0;
375
291
  }
376
292
 
377
293
  /**
378
- * Delete all occurrences of the given key.
379
- * @returns True if any occurrence was removed.
294
+ * Whether the multiset contains the given key.
380
295
  * @remarks Time O(log n), Space O(1)
381
296
 
382
297
 
383
- * @example
384
- * // Remove all occurrences
385
- * const ms = new TreeMultiSet<number>();
386
- * ms.add(1, 3);
387
- * ms.deleteAll(1);
388
- * console.log(ms.has(1)); // false;
389
- */
390
- deleteAll(key: K): boolean {
391
- this._validateKey(key);
392
- const old = this.#core.get(key) ?? 0;
393
- if (old === 0) return false;
394
- this.#core.delete(key);
395
- this._size -= old;
396
- return true;
397
- }
398
-
399
- /**
400
- * Iterates over distinct keys (each key yielded once).
401
- * @remarks Time O(n), Space O(1)
402
298
 
403
299
 
404
- * @example
405
- * // Iterate unique keys
406
- * const ms = new TreeMultiSet<number>();
407
- * ms.add(1, 2);
408
- * ms.add(2);
409
- * console.log([...ms.keysDistinct()]); // [1, 2];
410
- */
411
- *keysDistinct(): IterableIterator<K> {
412
- yield* this.#core.keys();
413
- }
414
-
415
- /**
416
- * Iterates over entries as [key, count] pairs.
417
- * @remarks Time O(n), Space O(1)
418
300
 
419
301
 
420
302
 
@@ -453,31 +335,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
453
335
 
454
336
 
455
337
 
456
- * @example
457
- * // Iterate entries
458
- * const ms = new TreeMultiSet<number>();
459
- * ms.add(1, 2);
460
- * console.log([...ms.entries()].length); // > 0;
461
- */
462
- *entries(): IterableIterator<[K, number]> {
463
- for (const [k, v] of this.#core) {
464
- yield [k, v ?? 0];
465
- }
466
- }
467
-
468
- /**
469
- * Expanded iteration (default). Each key is yielded `count(key)` times.
470
- * @remarks Time O(size), Space O(1) where size is total occurrences
471
- */
472
- *[Symbol.iterator](): Iterator<K> {
473
- for (const [k, c] of this.entries()) {
474
- for (let i = 0; i < c; i++) yield k;
475
- }
476
- }
477
-
478
- /**
479
- * Returns an array with all elements (expanded).
480
- * @remarks Time O(size), Space O(size)
481
338
 
482
339
 
483
340
 
@@ -516,63 +373,10 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
516
373
 
517
374
 
518
375
 
519
- * @example
520
- * // All elements (with duplicates)
521
- * const ms = new TreeMultiSet<number>();
522
- * ms.add(1, 2);
523
- * ms.add(2);
524
- * console.log(ms.toArray()); // [1, 1, 2];
525
- */
526
- toArray(): K[] {
527
- return [...this];
528
- }
529
-
530
- /**
531
- * Returns an array with distinct keys only.
532
- * @remarks Time O(n), Space O(n)
533
376
 
534
377
 
535
- * @example
536
- * // Unique keys only
537
- * const ms = new TreeMultiSet<number>();
538
- * ms.add(1, 3);
539
- * ms.add(2);
540
- * console.log(ms.toDistinctArray()); // [1, 2];
541
- */
542
- toDistinctArray(): K[] {
543
- return [...this.keysDistinct()];
544
- }
545
-
546
- /**
547
- * Returns an array of [key, count] entries.
548
- * @remarks Time O(n), Space O(n)
549
378
 
550
379
 
551
- * @example
552
- * // Key-count pairs
553
- * const ms = new TreeMultiSet<number>();
554
- * ms.add(1, 2);
555
- * ms.add(3);
556
- * console.log(ms.toEntries()); // [[1, 2], [3, 1]];
557
- */
558
- toEntries(): Array<[K, number]> {
559
- return [...this.entries()];
560
- }
561
-
562
- /**
563
- * Expose comparator for advanced usage/testing (read-only).
564
- * @remarks Time O(1), Space O(1)
565
- */
566
- get comparator(): Comparator<K> {
567
- return this.#core.comparator;
568
- }
569
-
570
- // ━━━ clear ━━━
571
-
572
- /**
573
- * Remove all elements from the multiset.
574
- * @remarks Time O(1), Space O(1)
575
-
576
380
 
577
381
 
578
382
 
@@ -611,99 +415,101 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
611
415
 
612
416
 
613
417
 
614
- * @example
615
- * // Remove all
616
- * const ms = new TreeMultiSet<number>();
617
- * ms.add(1);
618
- * ms.clear();
619
- * console.log(ms.isEmpty()); // true;
620
- */
621
- clear(): void {
622
- this.#core.clear();
623
- this._size = 0;
624
- }
625
-
626
- // ━━━ Navigable methods ━━━
627
-
628
- /**
629
- * Returns the smallest key, or undefined if empty.
630
- * @remarks Time O(log n), Space O(1)
631
-
632
418
 
633
419
 
634
- * @example
635
- * // Smallest element
636
- * const ms = new TreeMultiSet<number>();
637
- * ms.add(3);
638
- * ms.add(1);
639
- * console.log(ms.first()); // 1;
640
- */
641
- first(): K | undefined {
642
- return this.#core.getLeftMost();
643
- }
644
-
645
- /**
646
- * Returns the largest key, or undefined if empty.
647
- * @remarks Time O(log n), Space O(1)
648
-
649
420
 
650
421
 
651
- * @example
652
- * // Largest element
653
- * const ms = new TreeMultiSet<number>();
654
- * ms.add(1);
655
- * ms.add(3);
656
- * console.log(ms.last()); // 3;
657
- */
658
- last(): K | undefined {
659
- return this.#core.getRightMost();
660
- }
661
-
662
- /**
663
- * Removes all occurrences of the smallest key and returns it.
664
- * @remarks Time O(log n), Space O(1)
665
-
422
+
423
+
424
+
425
+
426
+
427
+
428
+
429
+
430
+
431
+
432
+
433
+
434
+
435
+
436
+
437
+
438
+
439
+
440
+
441
+
442
+
443
+
444
+
445
+
446
+
447
+
448
+
449
+
450
+
451
+
452
+
453
+
454
+
666
455
 
667
456
 
668
457
  * @example
669
- * // Remove and return smallest
458
+ * // Check existence
670
459
  * const ms = new TreeMultiSet<number>();
671
- * ms.add(2);
672
460
  * ms.add(1);
673
- * console.log(ms.pollFirst()); // 1;
674
- * console.log(ms.has(1)); // false;
461
+ * console.log(ms.has(1)); // true;
462
+ * console.log(ms.has(2)); // false;
675
463
  */
676
- pollFirst(): K | undefined {
677
- const key = this.first();
678
- if (key === undefined) return undefined;
679
- this.deleteAll(key);
680
- return key;
464
+ has(key: K): boolean {
465
+ this._validateKey(key);
466
+ return this.count(key) > 0;
681
467
  }
682
468
 
683
469
  /**
684
- * Removes all occurrences of the largest key and returns it.
470
+ * Returns the count of occurrences for the given key.
685
471
  * @remarks Time O(log n), Space O(1)
686
-
472
+
473
+
474
+
475
+
476
+
477
+
478
+
479
+
480
+
481
+
482
+
483
+
484
+
485
+
486
+
487
+
488
+
489
+
490
+
491
+
492
+
493
+
494
+
495
+
687
496
 
688
497
 
689
498
  * @example
690
- * // Remove and return largest
499
+ * // Get occurrence count
691
500
  * const ms = new TreeMultiSet<number>();
692
- * ms.add(1);
693
- * ms.add(3);
694
- * console.log(ms.pollLast()); // 3;
501
+ * ms.add(1, 5);
502
+ * console.log(ms.count(1)); // 5;
695
503
  */
696
- pollLast(): K | undefined {
697
- const key = this.last();
698
- if (key === undefined) return undefined;
699
- this.deleteAll(key);
700
- return key;
504
+ count(key: K): number {
505
+ this._validateKey(key);
506
+ return this.#core.get(key) ?? 0;
701
507
  }
702
508
 
703
509
  /**
704
- * Returns the smallest key >= given key, or undefined.
510
+ * Add `n` occurrences of `key`.
511
+ * @returns True if the multiset changed.
705
512
  * @remarks Time O(log n), Space O(1)
706
-
707
513
 
708
514
 
709
515
 
@@ -733,23 +539,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
733
539
 
734
540
 
735
541
 
736
- * @example
737
- * // Least key ≥ target
738
- * const ms = new TreeMultiSet<number>();
739
- * ms.add(10);
740
- * ms.add(20);
741
- * ms.add(30);
742
- * console.log(ms.ceiling(15)); // 20;
743
- */
744
- ceiling(key: K): K | undefined {
745
- this._validateKey(key);
746
- return this.#core.ceiling(key);
747
- }
748
-
749
- /**
750
- * Returns the largest key <= given key, or undefined.
751
- * @remarks Time O(log n), Space O(1)
752
-
753
542
 
754
543
 
755
544
 
@@ -779,23 +568,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
779
568
 
780
569
 
781
570
 
782
- * @example
783
- * // Greatest key ≤ target
784
- * const ms = new TreeMultiSet<number>();
785
- * ms.add(10);
786
- * ms.add(20);
787
- * ms.add(30);
788
- * console.log(ms.floor(25)); // 20;
789
- */
790
- floor(key: K): K | undefined {
791
- this._validateKey(key);
792
- return this.#core.floor(key);
793
- }
794
-
795
- /**
796
- * Returns the smallest key > given key, or undefined.
797
- * @remarks Time O(log n), Space O(1)
798
-
799
571
 
800
572
 
801
573
 
@@ -825,22 +597,2637 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
825
597
 
826
598
 
827
599
 
828
- * @example
829
- * // Least key > target
830
- * const ms = new TreeMultiSet<number>();
831
- * ms.add(10);
832
- * ms.add(20);
833
- * console.log(ms.higher(10)); // 20;
834
- */
835
- higher(key: K): K | undefined {
836
- this._validateKey(key);
837
- return this.#core.higher(key);
838
- }
839
-
840
- /**
841
- * Returns the largest key < given key, or undefined.
842
- * @remarks Time O(log n), Space O(1)
843
-
600
+
601
+
602
+
603
+
604
+
605
+
606
+
607
+
608
+
609
+
610
+
611
+
612
+
613
+
614
+
615
+
616
+
617
+
618
+
619
+
620
+
621
+
622
+
623
+
624
+
625
+
626
+
627
+
628
+
629
+
630
+
631
+
632
+
633
+
634
+
635
+
636
+
637
+
638
+
639
+
640
+
641
+
642
+
643
+
644
+
645
+
646
+
647
+
648
+
649
+
650
+
651
+
652
+
653
+
654
+
655
+
656
+
657
+
658
+
659
+
660
+
661
+
662
+
663
+
664
+
665
+ * @example
666
+ * // Add elements
667
+ * const ms = new TreeMultiSet<number>();
668
+ * ms.add(1);
669
+ * ms.add(1);
670
+ * ms.add(2);
671
+ * console.log(ms.count(1)); // 2;
672
+ * console.log(ms.size); // 3;
673
+ */
674
+ add(key: K, n = 1): boolean {
675
+ this._validateKey(key);
676
+ this._validateCount(n);
677
+ if (n === 0) return false;
678
+
679
+ const old = this.#core.get(key) ?? 0;
680
+ const next = old + n;
681
+ this.#core.set(key, next);
682
+ this._size += n;
683
+ return true;
684
+ }
685
+
686
+ /**
687
+ * Set count for `key` to exactly `n`.
688
+ * @returns True if changed.
689
+ * @remarks Time O(log n), Space O(1)
690
+
691
+
692
+
693
+
694
+
695
+
696
+
697
+
698
+
699
+
700
+
701
+
702
+
703
+
704
+
705
+
706
+
707
+
708
+
709
+
710
+
711
+
712
+
713
+
714
+
715
+
716
+ * @example
717
+ * // Set occurrence count
718
+ * const ms = new TreeMultiSet<number>();
719
+ * ms.setCount(1, 3);
720
+ * console.log(ms.count(1)); // 3;
721
+ */
722
+ setCount(key: K, n: number): boolean {
723
+ this._validateKey(key);
724
+ this._validateCount(n);
725
+
726
+ const old = this.#core.get(key) ?? 0;
727
+ if (old === n) return false;
728
+
729
+ if (n === 0) {
730
+ if (old !== 0) this.#core.delete(key);
731
+ } else {
732
+ this.#core.set(key, n);
733
+ }
734
+
735
+ this._size += n - old;
736
+ return true;
737
+ }
738
+
739
+ /**
740
+ * Delete `n` occurrences of `key` (default 1).
741
+ * @returns True if any occurrence was removed.
742
+ * @remarks Time O(log n), Space O(1)
743
+
744
+
745
+
746
+
747
+
748
+
749
+
750
+
751
+
752
+
753
+
754
+
755
+
756
+
757
+
758
+
759
+
760
+
761
+
762
+
763
+
764
+
765
+
766
+
767
+
768
+
769
+
770
+
771
+
772
+
773
+
774
+
775
+
776
+
777
+
778
+
779
+
780
+
781
+
782
+
783
+
784
+
785
+
786
+
787
+
788
+
789
+
790
+
791
+
792
+
793
+
794
+
795
+
796
+
797
+
798
+
799
+
800
+
801
+
802
+
803
+
804
+
805
+
806
+
807
+
808
+
809
+
810
+
811
+
812
+
813
+
814
+
815
+
816
+
817
+
818
+
819
+
820
+
821
+
822
+
823
+
824
+
825
+
826
+
827
+
828
+
829
+
830
+
831
+
832
+
833
+
834
+
835
+
836
+
837
+
838
+
839
+
840
+
841
+
842
+
843
+
844
+
845
+
846
+
847
+
848
+
849
+
850
+
851
+
852
+
853
+
854
+
855
+
856
+
857
+
858
+
859
+
860
+
861
+
862
+
863
+
864
+
865
+
866
+
867
+
868
+
869
+
870
+
871
+
872
+
873
+
874
+
875
+
876
+
877
+
878
+
879
+
880
+
881
+
882
+
883
+
884
+
885
+
886
+
887
+
888
+
889
+
890
+
891
+
892
+
893
+
894
+
895
+
896
+
897
+
898
+
899
+
900
+
901
+
902
+
903
+
904
+ * @example
905
+ * // Remove one occurrence
906
+ * const ms = new TreeMultiSet<number>();
907
+ * ms.add(1, 3);
908
+ * ms.delete(1);
909
+ * console.log(ms.count(1)); // 2;
910
+ */
911
+ delete(key: K, n = 1): boolean {
912
+ this._validateKey(key);
913
+ this._validateCount(n);
914
+ if (n === 0) return false;
915
+
916
+ const old = this.#core.get(key) ?? 0;
917
+ if (old === 0) return false;
918
+
919
+ const removed = Math.min(old, n);
920
+ const next = old - removed;
921
+
922
+ if (next === 0) this.#core.delete(key);
923
+ else this.#core.set(key, next);
924
+
925
+ this._size -= removed;
926
+ return true;
927
+ }
928
+
929
+ /**
930
+ * Delete all occurrences of the given key.
931
+ * @returns True if any occurrence was removed.
932
+ * @remarks Time O(log n), Space O(1)
933
+
934
+
935
+
936
+
937
+
938
+
939
+
940
+
941
+
942
+
943
+
944
+
945
+
946
+
947
+
948
+
949
+
950
+
951
+
952
+
953
+
954
+
955
+
956
+
957
+
958
+
959
+ * @example
960
+ * // Remove all occurrences
961
+ * const ms = new TreeMultiSet<number>();
962
+ * ms.add(1, 3);
963
+ * ms.deleteAll(1);
964
+ * console.log(ms.has(1)); // false;
965
+ */
966
+ deleteAll(key: K): boolean {
967
+ this._validateKey(key);
968
+ const old = this.#core.get(key) ?? 0;
969
+ if (old === 0) return false;
970
+ this.#core.delete(key);
971
+ this._size -= old;
972
+ return true;
973
+ }
974
+
975
+ /**
976
+ * Iterates over distinct keys (each key yielded once).
977
+ * @remarks Time O(n), Space O(1)
978
+
979
+
980
+
981
+
982
+
983
+
984
+
985
+
986
+
987
+
988
+
989
+
990
+
991
+
992
+
993
+
994
+
995
+
996
+
997
+
998
+
999
+
1000
+
1001
+
1002
+
1003
+
1004
+ * @example
1005
+ * // Iterate unique keys
1006
+ * const ms = new TreeMultiSet<number>();
1007
+ * ms.add(1, 2);
1008
+ * ms.add(2);
1009
+ * console.log([...ms.keysDistinct()]); // [1, 2];
1010
+ */
1011
+ *keysDistinct(): IterableIterator<K> {
1012
+ yield* this.#core.keys();
1013
+ }
1014
+
1015
+ /**
1016
+ * Iterates over entries as [key, count] pairs.
1017
+ * @remarks Time O(n), Space O(1)
1018
+
1019
+
1020
+
1021
+
1022
+
1023
+
1024
+
1025
+
1026
+
1027
+
1028
+
1029
+
1030
+
1031
+
1032
+
1033
+
1034
+
1035
+
1036
+
1037
+
1038
+
1039
+
1040
+
1041
+
1042
+
1043
+
1044
+
1045
+
1046
+
1047
+
1048
+
1049
+
1050
+
1051
+
1052
+
1053
+
1054
+
1055
+
1056
+
1057
+
1058
+
1059
+
1060
+
1061
+
1062
+
1063
+
1064
+
1065
+
1066
+
1067
+
1068
+
1069
+
1070
+
1071
+
1072
+
1073
+
1074
+
1075
+
1076
+
1077
+
1078
+
1079
+
1080
+
1081
+
1082
+
1083
+
1084
+
1085
+
1086
+
1087
+
1088
+
1089
+
1090
+
1091
+
1092
+
1093
+
1094
+
1095
+
1096
+
1097
+
1098
+
1099
+
1100
+
1101
+
1102
+
1103
+
1104
+
1105
+
1106
+
1107
+
1108
+
1109
+
1110
+
1111
+
1112
+
1113
+
1114
+
1115
+
1116
+
1117
+
1118
+
1119
+
1120
+
1121
+
1122
+
1123
+
1124
+
1125
+
1126
+
1127
+
1128
+
1129
+
1130
+
1131
+
1132
+
1133
+
1134
+
1135
+
1136
+
1137
+
1138
+
1139
+
1140
+
1141
+
1142
+
1143
+
1144
+
1145
+
1146
+
1147
+
1148
+
1149
+
1150
+
1151
+
1152
+
1153
+
1154
+
1155
+
1156
+
1157
+
1158
+
1159
+
1160
+
1161
+
1162
+
1163
+
1164
+
1165
+
1166
+
1167
+
1168
+
1169
+
1170
+
1171
+
1172
+
1173
+
1174
+
1175
+
1176
+ * @example
1177
+ * // Iterate entries
1178
+ * const ms = new TreeMultiSet<number>();
1179
+ * ms.add(1, 2);
1180
+ * console.log([...ms.entries()].length); // > 0;
1181
+ */
1182
+ *entries(): IterableIterator<[K, number]> {
1183
+ for (const [k, v] of this.#core) {
1184
+ yield [k, v ?? 0];
1185
+ }
1186
+ }
1187
+
1188
+ /**
1189
+ * Expanded iteration (default). Each key is yielded `count(key)` times.
1190
+ * @remarks Time O(size), Space O(1) where size is total occurrences
1191
+ */
1192
+ *[Symbol.iterator](): Iterator<K> {
1193
+ for (const [k, c] of this.entries()) {
1194
+ for (let i = 0; i < c; i++) yield k;
1195
+ }
1196
+ }
1197
+
1198
+ /**
1199
+ * Returns an array with all elements (expanded).
1200
+ * @remarks Time O(size), Space O(size)
1201
+
1202
+
1203
+
1204
+
1205
+
1206
+
1207
+
1208
+
1209
+
1210
+
1211
+
1212
+
1213
+
1214
+
1215
+
1216
+
1217
+
1218
+
1219
+
1220
+
1221
+
1222
+
1223
+
1224
+
1225
+
1226
+
1227
+
1228
+
1229
+
1230
+
1231
+
1232
+
1233
+
1234
+
1235
+
1236
+
1237
+
1238
+
1239
+
1240
+
1241
+
1242
+
1243
+
1244
+
1245
+
1246
+
1247
+
1248
+
1249
+
1250
+
1251
+
1252
+
1253
+
1254
+
1255
+
1256
+
1257
+
1258
+
1259
+
1260
+
1261
+
1262
+
1263
+
1264
+
1265
+
1266
+
1267
+
1268
+
1269
+
1270
+
1271
+
1272
+
1273
+
1274
+
1275
+
1276
+
1277
+
1278
+
1279
+
1280
+
1281
+
1282
+
1283
+
1284
+
1285
+
1286
+
1287
+
1288
+
1289
+
1290
+
1291
+
1292
+
1293
+
1294
+
1295
+
1296
+
1297
+
1298
+
1299
+
1300
+
1301
+
1302
+
1303
+
1304
+
1305
+
1306
+
1307
+
1308
+
1309
+
1310
+
1311
+
1312
+
1313
+
1314
+
1315
+
1316
+
1317
+
1318
+
1319
+
1320
+
1321
+
1322
+
1323
+
1324
+
1325
+
1326
+
1327
+
1328
+
1329
+
1330
+
1331
+
1332
+
1333
+
1334
+
1335
+
1336
+
1337
+
1338
+
1339
+
1340
+
1341
+
1342
+
1343
+
1344
+
1345
+
1346
+
1347
+
1348
+
1349
+
1350
+
1351
+
1352
+
1353
+
1354
+
1355
+
1356
+
1357
+
1358
+
1359
+ * @example
1360
+ * // All elements (with duplicates)
1361
+ * const ms = new TreeMultiSet<number>();
1362
+ * ms.add(1, 2);
1363
+ * ms.add(2);
1364
+ * console.log(ms.toArray()); // [1, 1, 2];
1365
+ */
1366
+ toArray(): K[] {
1367
+ return [...this];
1368
+ }
1369
+
1370
+ /**
1371
+ * Returns an array with distinct keys only.
1372
+ * @remarks Time O(n), Space O(n)
1373
+
1374
+
1375
+
1376
+
1377
+
1378
+
1379
+
1380
+
1381
+
1382
+
1383
+
1384
+
1385
+
1386
+
1387
+
1388
+
1389
+
1390
+
1391
+
1392
+
1393
+
1394
+
1395
+
1396
+
1397
+
1398
+
1399
+ * @example
1400
+ * // Unique keys only
1401
+ * const ms = new TreeMultiSet<number>();
1402
+ * ms.add(1, 3);
1403
+ * ms.add(2);
1404
+ * console.log(ms.toDistinctArray()); // [1, 2];
1405
+ */
1406
+ toDistinctArray(): K[] {
1407
+ return [...this.keysDistinct()];
1408
+ }
1409
+
1410
+ /**
1411
+ * Returns an array of [key, count] entries.
1412
+ * @remarks Time O(n), Space O(n)
1413
+
1414
+
1415
+
1416
+
1417
+
1418
+
1419
+
1420
+
1421
+
1422
+
1423
+
1424
+
1425
+
1426
+
1427
+
1428
+
1429
+
1430
+
1431
+
1432
+
1433
+
1434
+
1435
+
1436
+
1437
+
1438
+
1439
+ * @example
1440
+ * // Key-count pairs
1441
+ * const ms = new TreeMultiSet<number>();
1442
+ * ms.add(1, 2);
1443
+ * ms.add(3);
1444
+ * console.log(ms.toEntries()); // [[1, 2], [3, 1]];
1445
+ */
1446
+ toEntries(): Array<[K, number]> {
1447
+ return [...this.entries()];
1448
+ }
1449
+
1450
+ /**
1451
+ * Expose comparator for advanced usage/testing (read-only).
1452
+ * @remarks Time O(1), Space O(1)
1453
+ */
1454
+ get comparator(): Comparator<K> {
1455
+ return this.#core.comparator;
1456
+ }
1457
+
1458
+ // ━━━ clear ━━━
1459
+
1460
+ /**
1461
+ * Remove all elements from the multiset.
1462
+ * @remarks Time O(1), Space O(1)
1463
+
1464
+
1465
+
1466
+
1467
+
1468
+
1469
+
1470
+
1471
+
1472
+
1473
+
1474
+
1475
+
1476
+
1477
+
1478
+
1479
+
1480
+
1481
+
1482
+
1483
+
1484
+
1485
+
1486
+
1487
+
1488
+
1489
+
1490
+
1491
+
1492
+
1493
+
1494
+
1495
+
1496
+
1497
+
1498
+
1499
+
1500
+
1501
+
1502
+
1503
+
1504
+
1505
+
1506
+
1507
+
1508
+
1509
+
1510
+
1511
+
1512
+
1513
+
1514
+
1515
+
1516
+
1517
+
1518
+
1519
+
1520
+
1521
+
1522
+
1523
+
1524
+
1525
+
1526
+
1527
+
1528
+
1529
+
1530
+
1531
+
1532
+
1533
+
1534
+
1535
+
1536
+
1537
+
1538
+
1539
+
1540
+
1541
+
1542
+
1543
+
1544
+
1545
+
1546
+
1547
+
1548
+
1549
+
1550
+
1551
+
1552
+
1553
+
1554
+
1555
+
1556
+
1557
+
1558
+
1559
+
1560
+
1561
+
1562
+
1563
+
1564
+
1565
+
1566
+
1567
+
1568
+
1569
+
1570
+
1571
+
1572
+
1573
+
1574
+
1575
+
1576
+
1577
+
1578
+
1579
+
1580
+
1581
+
1582
+
1583
+
1584
+
1585
+
1586
+
1587
+
1588
+
1589
+
1590
+
1591
+
1592
+
1593
+
1594
+
1595
+
1596
+
1597
+
1598
+
1599
+
1600
+
1601
+
1602
+
1603
+
1604
+
1605
+
1606
+
1607
+
1608
+
1609
+
1610
+
1611
+
1612
+
1613
+
1614
+
1615
+
1616
+
1617
+
1618
+
1619
+
1620
+
1621
+
1622
+ * @example
1623
+ * // Remove all
1624
+ * const ms = new TreeMultiSet<number>();
1625
+ * ms.add(1);
1626
+ * ms.clear();
1627
+ * console.log(ms.isEmpty()); // true;
1628
+ */
1629
+ clear(): void {
1630
+ this.#core.clear();
1631
+ this._size = 0;
1632
+ }
1633
+
1634
+ // ━━━ Navigable methods ━━━
1635
+
1636
+ /**
1637
+ * Returns the smallest key, or undefined if empty.
1638
+ * @remarks Time O(log n), Space O(1)
1639
+
1640
+
1641
+
1642
+
1643
+
1644
+
1645
+
1646
+
1647
+
1648
+
1649
+
1650
+
1651
+
1652
+
1653
+
1654
+
1655
+
1656
+
1657
+
1658
+
1659
+
1660
+
1661
+
1662
+
1663
+
1664
+
1665
+
1666
+ * @example
1667
+ * // Smallest element
1668
+ * const ms = new TreeMultiSet<number>();
1669
+ * ms.add(3);
1670
+ * ms.add(1);
1671
+ * console.log(ms.first()); // 1;
1672
+ */
1673
+ first(): K | undefined {
1674
+ return this.#core.getLeftMost();
1675
+ }
1676
+
1677
+ /**
1678
+ * Returns the largest key, or undefined if empty.
1679
+ * @remarks Time O(log n), Space O(1)
1680
+
1681
+
1682
+
1683
+
1684
+
1685
+
1686
+
1687
+
1688
+
1689
+
1690
+
1691
+
1692
+
1693
+
1694
+
1695
+
1696
+
1697
+
1698
+
1699
+
1700
+
1701
+
1702
+
1703
+
1704
+
1705
+
1706
+
1707
+ * @example
1708
+ * // Largest element
1709
+ * const ms = new TreeMultiSet<number>();
1710
+ * ms.add(1);
1711
+ * ms.add(3);
1712
+ * console.log(ms.last()); // 3;
1713
+ */
1714
+ last(): K | undefined {
1715
+ return this.#core.getRightMost();
1716
+ }
1717
+
1718
+ /**
1719
+ * Removes all occurrences of the smallest key and returns it.
1720
+ * @remarks Time O(log n), Space O(1)
1721
+
1722
+
1723
+
1724
+
1725
+
1726
+
1727
+
1728
+
1729
+
1730
+
1731
+
1732
+
1733
+
1734
+
1735
+
1736
+
1737
+
1738
+
1739
+
1740
+
1741
+
1742
+
1743
+
1744
+
1745
+
1746
+
1747
+
1748
+ * @example
1749
+ * // Remove and return smallest
1750
+ * const ms = new TreeMultiSet<number>();
1751
+ * ms.add(2);
1752
+ * ms.add(1);
1753
+ * console.log(ms.pollFirst()); // 1;
1754
+ * console.log(ms.has(1)); // false;
1755
+ */
1756
+ pollFirst(): K | undefined {
1757
+ const key = this.first();
1758
+ if (key === undefined) return undefined;
1759
+ this.deleteAll(key);
1760
+ return key;
1761
+ }
1762
+
1763
+ /**
1764
+ * Removes all occurrences of the largest key and returns it.
1765
+ * @remarks Time O(log n), Space O(1)
1766
+
1767
+
1768
+
1769
+
1770
+
1771
+
1772
+
1773
+
1774
+
1775
+
1776
+
1777
+
1778
+
1779
+
1780
+
1781
+
1782
+
1783
+
1784
+
1785
+
1786
+
1787
+
1788
+
1789
+
1790
+
1791
+
1792
+
1793
+ * @example
1794
+ * // Remove and return largest
1795
+ * const ms = new TreeMultiSet<number>();
1796
+ * ms.add(1);
1797
+ * ms.add(3);
1798
+ * console.log(ms.pollLast()); // 3;
1799
+ */
1800
+ pollLast(): K | undefined {
1801
+ const key = this.last();
1802
+ if (key === undefined) return undefined;
1803
+ this.deleteAll(key);
1804
+ return key;
1805
+ }
1806
+
1807
+ /**
1808
+ * Returns the smallest key >= given key, or undefined.
1809
+ * @remarks Time O(log n), Space O(1)
1810
+
1811
+
1812
+
1813
+
1814
+
1815
+
1816
+
1817
+
1818
+
1819
+
1820
+
1821
+
1822
+
1823
+
1824
+
1825
+
1826
+
1827
+
1828
+
1829
+
1830
+
1831
+
1832
+
1833
+
1834
+
1835
+
1836
+
1837
+
1838
+
1839
+
1840
+
1841
+
1842
+
1843
+
1844
+
1845
+
1846
+
1847
+
1848
+
1849
+
1850
+
1851
+
1852
+
1853
+
1854
+
1855
+
1856
+
1857
+
1858
+
1859
+
1860
+
1861
+
1862
+
1863
+
1864
+
1865
+
1866
+
1867
+
1868
+
1869
+
1870
+
1871
+
1872
+
1873
+
1874
+
1875
+
1876
+
1877
+
1878
+
1879
+
1880
+
1881
+
1882
+
1883
+
1884
+
1885
+
1886
+
1887
+
1888
+
1889
+
1890
+
1891
+
1892
+
1893
+
1894
+
1895
+
1896
+
1897
+
1898
+
1899
+
1900
+
1901
+
1902
+
1903
+
1904
+
1905
+
1906
+
1907
+
1908
+
1909
+
1910
+
1911
+
1912
+
1913
+
1914
+
1915
+
1916
+
1917
+
1918
+
1919
+
1920
+
1921
+
1922
+
1923
+
1924
+
1925
+
1926
+
1927
+
1928
+
1929
+
1930
+
1931
+
1932
+
1933
+
1934
+
1935
+
1936
+ * @example
1937
+ * // Least key ≥ target
1938
+ * const ms = new TreeMultiSet<number>();
1939
+ * ms.add(10);
1940
+ * ms.add(20);
1941
+ * ms.add(30);
1942
+ * console.log(ms.ceiling(15)); // 20;
1943
+ */
1944
+ ceiling(key: K): K | undefined {
1945
+ this._validateKey(key);
1946
+ return this.#core.ceiling(key);
1947
+ }
1948
+
1949
+ /**
1950
+ * Returns the largest key <= given key, or undefined.
1951
+ * @remarks Time O(log n), Space O(1)
1952
+
1953
+
1954
+
1955
+
1956
+
1957
+
1958
+
1959
+
1960
+
1961
+
1962
+
1963
+
1964
+
1965
+
1966
+
1967
+
1968
+
1969
+
1970
+
1971
+
1972
+
1973
+
1974
+
1975
+
1976
+
1977
+
1978
+
1979
+
1980
+
1981
+
1982
+
1983
+
1984
+
1985
+
1986
+
1987
+
1988
+
1989
+
1990
+
1991
+
1992
+
1993
+
1994
+
1995
+
1996
+
1997
+
1998
+
1999
+
2000
+
2001
+
2002
+
2003
+
2004
+
2005
+
2006
+
2007
+
2008
+
2009
+
2010
+
2011
+
2012
+
2013
+
2014
+
2015
+
2016
+
2017
+
2018
+
2019
+
2020
+
2021
+
2022
+
2023
+
2024
+
2025
+
2026
+
2027
+
2028
+
2029
+
2030
+
2031
+
2032
+
2033
+
2034
+
2035
+
2036
+
2037
+
2038
+
2039
+
2040
+
2041
+
2042
+
2043
+
2044
+
2045
+
2046
+
2047
+
2048
+
2049
+
2050
+
2051
+
2052
+
2053
+
2054
+
2055
+
2056
+
2057
+
2058
+
2059
+
2060
+
2061
+
2062
+
2063
+
2064
+
2065
+
2066
+
2067
+
2068
+
2069
+
2070
+
2071
+
2072
+
2073
+
2074
+
2075
+
2076
+
2077
+
2078
+ * @example
2079
+ * // Greatest key ≤ target
2080
+ * const ms = new TreeMultiSet<number>();
2081
+ * ms.add(10);
2082
+ * ms.add(20);
2083
+ * ms.add(30);
2084
+ * console.log(ms.floor(25)); // 20;
2085
+ */
2086
+ floor(key: K): K | undefined {
2087
+ this._validateKey(key);
2088
+ return this.#core.floor(key);
2089
+ }
2090
+
2091
+ /**
2092
+ * Returns the smallest key > given key, or undefined.
2093
+ * @remarks Time O(log n), Space O(1)
2094
+
2095
+
2096
+
2097
+
2098
+
2099
+
2100
+
2101
+
2102
+
2103
+
2104
+
2105
+
2106
+
2107
+
2108
+
2109
+
2110
+
2111
+
2112
+
2113
+
2114
+
2115
+
2116
+
2117
+
2118
+
2119
+
2120
+
2121
+
2122
+
2123
+
2124
+
2125
+
2126
+
2127
+
2128
+
2129
+
2130
+
2131
+
2132
+
2133
+
2134
+
2135
+
2136
+
2137
+
2138
+
2139
+
2140
+
2141
+
2142
+
2143
+
2144
+
2145
+
2146
+
2147
+
2148
+
2149
+
2150
+
2151
+
2152
+
2153
+
2154
+
2155
+
2156
+
2157
+
2158
+
2159
+
2160
+
2161
+
2162
+
2163
+
2164
+
2165
+
2166
+
2167
+
2168
+
2169
+
2170
+
2171
+
2172
+
2173
+
2174
+
2175
+
2176
+
2177
+
2178
+
2179
+
2180
+
2181
+
2182
+
2183
+
2184
+
2185
+
2186
+
2187
+
2188
+
2189
+
2190
+
2191
+
2192
+
2193
+
2194
+
2195
+
2196
+
2197
+
2198
+
2199
+
2200
+
2201
+
2202
+
2203
+
2204
+
2205
+
2206
+
2207
+
2208
+
2209
+
2210
+
2211
+
2212
+
2213
+
2214
+
2215
+
2216
+
2217
+
2218
+
2219
+
2220
+ * @example
2221
+ * // Least key > target
2222
+ * const ms = new TreeMultiSet<number>();
2223
+ * ms.add(10);
2224
+ * ms.add(20);
2225
+ * console.log(ms.higher(10)); // 20;
2226
+ */
2227
+ higher(key: K): K | undefined {
2228
+ this._validateKey(key);
2229
+ return this.#core.higher(key);
2230
+ }
2231
+
2232
+ /**
2233
+ * Returns the largest key < given key, or undefined.
2234
+ * @remarks Time O(log n), Space O(1)
2235
+
2236
+
2237
+
2238
+
2239
+
2240
+
2241
+
2242
+
2243
+
2244
+
2245
+
2246
+
2247
+
2248
+
2249
+
2250
+
2251
+
2252
+
2253
+
2254
+
2255
+
2256
+
2257
+
2258
+
2259
+
2260
+
2261
+
2262
+
2263
+
2264
+
2265
+
2266
+
2267
+
2268
+
2269
+
2270
+
2271
+
2272
+
2273
+
2274
+
2275
+
2276
+
2277
+
2278
+
2279
+
2280
+
2281
+
2282
+
2283
+
2284
+
2285
+
2286
+
2287
+
2288
+
2289
+
2290
+
2291
+
2292
+
2293
+
2294
+
2295
+
2296
+
2297
+
2298
+
2299
+
2300
+
2301
+
2302
+
2303
+
2304
+
2305
+
2306
+
2307
+
2308
+
2309
+
2310
+
2311
+
2312
+
2313
+
2314
+
2315
+
2316
+
2317
+
2318
+
2319
+
2320
+
2321
+
2322
+
2323
+
2324
+
2325
+
2326
+
2327
+
2328
+
2329
+
2330
+
2331
+
2332
+
2333
+
2334
+
2335
+
2336
+
2337
+
2338
+
2339
+
2340
+
2341
+
2342
+
2343
+
2344
+
2345
+
2346
+
2347
+
2348
+
2349
+
2350
+
2351
+
2352
+
2353
+
2354
+
2355
+
2356
+
2357
+
2358
+
2359
+
2360
+
2361
+ * @example
2362
+ * // Greatest key < target
2363
+ * const ms = new TreeMultiSet<number>();
2364
+ * ms.add(10);
2365
+ * ms.add(20);
2366
+ * console.log(ms.lower(20)); // 10;
2367
+ */
2368
+ lower(key: K): K | undefined {
2369
+ this._validateKey(key);
2370
+ return this.#core.lower(key);
2371
+ }
2372
+
2373
+ // ━━━ Functional methods ━━━
2374
+
2375
+ /**
2376
+ * Iterates over distinct keys with their counts.
2377
+ * @remarks Time O(n), Space O(1)
2378
+
2379
+
2380
+
2381
+
2382
+
2383
+
2384
+
2385
+
2386
+
2387
+
2388
+
2389
+
2390
+
2391
+
2392
+
2393
+
2394
+
2395
+
2396
+
2397
+
2398
+
2399
+
2400
+
2401
+
2402
+
2403
+
2404
+
2405
+
2406
+
2407
+
2408
+
2409
+
2410
+
2411
+
2412
+
2413
+
2414
+
2415
+
2416
+
2417
+
2418
+
2419
+
2420
+
2421
+
2422
+
2423
+
2424
+
2425
+
2426
+
2427
+
2428
+
2429
+
2430
+
2431
+
2432
+
2433
+
2434
+
2435
+
2436
+
2437
+
2438
+
2439
+
2440
+
2441
+
2442
+
2443
+
2444
+
2445
+
2446
+
2447
+
2448
+
2449
+
2450
+
2451
+
2452
+
2453
+
2454
+
2455
+
2456
+
2457
+
2458
+
2459
+
2460
+
2461
+
2462
+
2463
+
2464
+
2465
+
2466
+
2467
+
2468
+
2469
+
2470
+
2471
+
2472
+
2473
+
2474
+
2475
+
2476
+
2477
+
2478
+
2479
+
2480
+
2481
+
2482
+
2483
+
2484
+
2485
+
2486
+
2487
+
2488
+
2489
+
2490
+
2491
+
2492
+
2493
+
2494
+
2495
+
2496
+
2497
+
2498
+
2499
+
2500
+
2501
+
2502
+
2503
+
2504
+
2505
+
2506
+
2507
+
2508
+
2509
+
2510
+
2511
+
2512
+
2513
+
2514
+
2515
+
2516
+
2517
+
2518
+
2519
+
2520
+
2521
+
2522
+
2523
+
2524
+
2525
+
2526
+
2527
+
2528
+
2529
+
2530
+
2531
+
2532
+
2533
+
2534
+
2535
+
2536
+
2537
+ * @example
2538
+ * // Iterate
2539
+ * const ms = new TreeMultiSet<number>();
2540
+ * ms.add(1, 2);
2541
+ * ms.add(2);
2542
+ * const pairs: [number, number][] = [];
2543
+ * ms.forEach((k, c) => pairs.push([k, c]));
2544
+ * console.log(pairs); // [[1, 2], [2, 1]];
2545
+ */
2546
+ forEach(callback: (key: K, count: number) => void): void {
2547
+ for (const [k, c] of this.entries()) {
2548
+ callback(k, c);
2549
+ }
2550
+ }
2551
+
2552
+ /**
2553
+ * Creates a new TreeMultiSet with entries that match the predicate.
2554
+ * @remarks Time O(n log n), Space O(n)
2555
+
2556
+
2557
+
2558
+
2559
+
2560
+
2561
+
2562
+
2563
+
2564
+
2565
+
2566
+
2567
+
2568
+
2569
+
2570
+
2571
+
2572
+
2573
+
2574
+
2575
+
2576
+
2577
+
2578
+
2579
+
2580
+
2581
+
2582
+
2583
+
2584
+
2585
+
2586
+
2587
+
2588
+
2589
+
2590
+
2591
+
2592
+
2593
+
2594
+
2595
+
2596
+
2597
+
2598
+
2599
+
2600
+
2601
+
2602
+
2603
+
2604
+
2605
+
2606
+
2607
+
2608
+
2609
+
2610
+
2611
+
2612
+
2613
+
2614
+
2615
+
2616
+
2617
+
2618
+
2619
+
2620
+
2621
+
2622
+
2623
+
2624
+
2625
+
2626
+
2627
+
2628
+
2629
+
2630
+
2631
+
2632
+
2633
+
2634
+
2635
+
2636
+
2637
+
2638
+
2639
+
2640
+
2641
+
2642
+
2643
+
2644
+
2645
+
2646
+
2647
+
2648
+
2649
+
2650
+
2651
+
2652
+
2653
+
2654
+
2655
+
2656
+
2657
+
2658
+
2659
+
2660
+
2661
+
2662
+
2663
+
2664
+
2665
+
2666
+
2667
+
2668
+
2669
+
2670
+
2671
+
2672
+
2673
+
2674
+
2675
+
2676
+
2677
+
2678
+
2679
+
2680
+
2681
+
2682
+
2683
+
2684
+
2685
+
2686
+
2687
+
2688
+
2689
+
2690
+
2691
+
2692
+
2693
+
2694
+
2695
+
2696
+
2697
+
2698
+
2699
+
2700
+
2701
+
2702
+
2703
+
2704
+
2705
+
2706
+
2707
+
2708
+
2709
+
2710
+
2711
+
2712
+
2713
+
2714
+ * @example
2715
+ * // Filter
2716
+ * const ms = new TreeMultiSet<number>();
2717
+ * ms.add(1, 3);
2718
+ * ms.add(2, 1);
2719
+ * ms.add(3, 2);
2720
+ * const filtered = ms.filter((k, c) => c > 1);
2721
+ * console.log([...filtered.keysDistinct()]); // [1, 3];
2722
+ */
2723
+ filter(predicate: (key: K, count: number) => boolean): TreeMultiSet<K> {
2724
+ const result = new TreeMultiSet<K>([], {
2725
+ comparator: this.#isDefaultComparator ? undefined : this.comparator,
2726
+ isMapMode: this.#core.isMapMode
2727
+ });
2728
+ for (const [k, c] of this.entries()) {
2729
+ if (predicate(k, c)) {
2730
+ result.add(k, c);
2731
+ }
2732
+ }
2733
+ return result;
2734
+ }
2735
+
2736
+ /**
2737
+ * Reduces the multiset to a single value.
2738
+ * @remarks Time O(n), Space O(1)
2739
+
2740
+
2741
+
2742
+
2743
+
2744
+
2745
+
2746
+
2747
+
2748
+
2749
+
2750
+
2751
+
2752
+
2753
+
2754
+
2755
+
2756
+
2757
+
2758
+
2759
+
2760
+
2761
+
2762
+
2763
+
2764
+
2765
+
2766
+
2767
+
2768
+
2769
+
2770
+
2771
+
2772
+
2773
+
2774
+
2775
+
2776
+
2777
+
2778
+
2779
+
2780
+
2781
+
2782
+
2783
+
2784
+
2785
+
2786
+
2787
+
2788
+
2789
+
2790
+
2791
+
2792
+
2793
+
2794
+
2795
+
2796
+
2797
+
2798
+
2799
+
2800
+
2801
+
2802
+
2803
+
2804
+
2805
+
2806
+
2807
+
2808
+
2809
+
2810
+
2811
+
2812
+
2813
+
2814
+
2815
+
2816
+
2817
+
2818
+
2819
+
2820
+
2821
+
2822
+
2823
+
2824
+
2825
+
2826
+
2827
+
2828
+
2829
+
2830
+
2831
+
2832
+
2833
+
2834
+
2835
+
2836
+
2837
+
2838
+
2839
+
2840
+
2841
+
2842
+
2843
+
2844
+
2845
+
2846
+
2847
+
2848
+
2849
+
2850
+
2851
+
2852
+
2853
+
2854
+
2855
+
2856
+
2857
+
2858
+
2859
+
2860
+
2861
+
2862
+
2863
+
2864
+
2865
+
2866
+
2867
+
2868
+
2869
+
2870
+
2871
+
2872
+
2873
+
2874
+
2875
+
2876
+
2877
+
2878
+
2879
+
2880
+
2881
+
2882
+
2883
+
2884
+
2885
+
2886
+
2887
+
2888
+
2889
+
2890
+
2891
+
2892
+
2893
+
2894
+
2895
+
2896
+
2897
+
2898
+ * @example
2899
+ * // Aggregate
2900
+ * const ms = new TreeMultiSet<number>();
2901
+ * ms.add(1, 2);
2902
+ * ms.add(2, 3);
2903
+ * const sum = ms.reduce((acc, k, c) => acc + k * c, 0);
2904
+ * console.log(sum); // 8;
2905
+ */
2906
+ reduce<U>(callback: (accumulator: U, key: K, count: number) => U, initialValue: U): U {
2907
+ let acc = initialValue;
2908
+ for (const [k, c] of this.entries()) {
2909
+ acc = callback(acc, k, c);
2910
+ }
2911
+ return acc;
2912
+ }
2913
+
2914
+ /**
2915
+ * Maps keys and counts to a new TreeMultiSet.
2916
+ * When multiple keys map to the same new key, counts are merged (added).
2917
+ * @remarks Time O(n log n), Space O(n)
2918
+
2919
+
2920
+
2921
+
2922
+
2923
+
2924
+
2925
+
2926
+
2927
+
2928
+
2929
+
2930
+
2931
+
2932
+
2933
+
2934
+
2935
+
2936
+
2937
+
2938
+
2939
+
2940
+
2941
+
2942
+
2943
+
2944
+
2945
+
2946
+
2947
+
2948
+
2949
+
2950
+
2951
+
2952
+
2953
+
2954
+
2955
+
2956
+
2957
+
2958
+
2959
+
2960
+
2961
+
2962
+
2963
+
2964
+
2965
+
2966
+
2967
+
2968
+
2969
+
2970
+
2971
+
2972
+
2973
+
2974
+
2975
+
2976
+
2977
+
2978
+
2979
+
2980
+
2981
+
2982
+
2983
+
2984
+
2985
+
2986
+
2987
+
2988
+
2989
+
2990
+
2991
+
2992
+
2993
+
2994
+
2995
+
2996
+
2997
+
2998
+
2999
+
3000
+
3001
+
3002
+
3003
+
3004
+
3005
+
3006
+
3007
+
3008
+
3009
+
3010
+
3011
+
3012
+
3013
+
3014
+
3015
+
3016
+
3017
+
3018
+
3019
+
3020
+
3021
+
3022
+
3023
+
3024
+
3025
+
3026
+
3027
+
3028
+
3029
+
3030
+
3031
+
3032
+
3033
+
3034
+
3035
+
3036
+
3037
+
3038
+
3039
+
3040
+
3041
+
3042
+
3043
+
3044
+
3045
+
3046
+
3047
+
3048
+
3049
+
3050
+
3051
+
3052
+
3053
+
3054
+
3055
+
3056
+
3057
+
3058
+
3059
+
3060
+
3061
+
3062
+
3063
+
3064
+
3065
+
3066
+
3067
+
3068
+
3069
+
3070
+
3071
+
3072
+
3073
+
3074
+
3075
+
3076
+
3077
+ * @example
3078
+ * // Transform
3079
+ * const ms = new TreeMultiSet<number>();
3080
+ * ms.add(1, 2);
3081
+ * ms.add(2, 3);
3082
+ * const doubled = ms.map((k, c) => [k * 10, c] as [number, number]);
3083
+ * console.log([...doubled.keysDistinct()]); // [10, 20];
3084
+ */
3085
+ map<K2>(
3086
+ mapper: (key: K, count: number) => [K2, number],
3087
+ options?: { comparator?: Comparator<K2> }
3088
+ ): TreeMultiSet<K2> {
3089
+ const result = new TreeMultiSet<K2>([], {
3090
+ comparator: options?.comparator,
3091
+ isMapMode: this.#core.isMapMode
3092
+ });
3093
+ for (const [k, c] of this.entries()) {
3094
+ const [newKey, newCount] = mapper(k, c);
3095
+ result.add(newKey, newCount);
3096
+ }
3097
+ return result;
3098
+ }
3099
+
3100
+ /**
3101
+ * Creates an independent copy of this multiset.
3102
+ * @remarks Time O(n log n), Space O(n)
3103
+
3104
+
3105
+
3106
+
3107
+
3108
+
3109
+
3110
+
3111
+
3112
+
3113
+
3114
+
3115
+
3116
+
3117
+
3118
+
3119
+
3120
+
3121
+
3122
+
3123
+
3124
+
3125
+
3126
+
3127
+
3128
+
3129
+
3130
+
3131
+
3132
+
3133
+
3134
+
3135
+
3136
+
3137
+
3138
+
3139
+
3140
+
3141
+
3142
+
3143
+
3144
+
3145
+
3146
+
3147
+
3148
+
3149
+
3150
+
3151
+
3152
+
3153
+
3154
+
3155
+
3156
+
3157
+
3158
+
3159
+
3160
+
3161
+
3162
+
3163
+
3164
+
3165
+
3166
+
3167
+
3168
+
3169
+
3170
+
3171
+
3172
+
3173
+
3174
+
3175
+
3176
+
3177
+
3178
+
3179
+
3180
+
3181
+
3182
+
3183
+
3184
+
3185
+
3186
+
3187
+
3188
+
3189
+
3190
+
3191
+
3192
+
3193
+
3194
+
3195
+
3196
+
3197
+
3198
+
3199
+
3200
+
3201
+
3202
+
3203
+
3204
+
3205
+
3206
+
3207
+
3208
+
3209
+
3210
+
3211
+
3212
+
3213
+
3214
+
3215
+
3216
+
3217
+
3218
+
3219
+
3220
+
3221
+
3222
+
3223
+
3224
+
3225
+
3226
+
3227
+
3228
+
3229
+
3230
+
844
3231
 
845
3232
 
846
3233
 
@@ -871,22 +3258,87 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
871
3258
 
872
3259
 
873
3260
  * @example
874
- * // Greatest key < target
3261
+ * // Order-statistic on BST
3262
+ * const tree = new TreeMultiSet<number>([30, 10, 50, 20, 40], { enableOrderStatistic: true });
3263
+ * console.log(tree.getByRank(0)); // 10;
3264
+ * console.log(tree.getByRank(4)); // 50;
3265
+ * console.log(tree.getRank(30)); // 2;
3266
+ */
3267
+ // ─── Order-Statistic Methods ───────────────────────────
3268
+
3269
+ getByRank(k: number): K | undefined {
3270
+ return this.#core.getByRank(k);
3271
+ }
3272
+
3273
+ /**
3274
+ * Get the rank of a key in sorted order
3275
+ * @example
3276
+ * // Get the rank of a key in sorted order
3277
+ * const tree = new TreeMultiSet<number>(
3278
+ * [10, 20, 30, 40, 50],
3279
+ * { enableOrderStatistic: true }
3280
+ * );
3281
+ * console.log(tree.getRank(10)); // 0; // smallest → rank 0
3282
+ * console.log(tree.getRank(30)); // 2; // 2 elements before 30 in tree order
3283
+ * console.log(tree.getRank(50)); // 4; // largest → rank 4
3284
+ * console.log(tree.getRank(25)); // 2;
3285
+ */
3286
+ getRank(key: K): number {
3287
+ return this.#core.getRank(key);
3288
+ }
3289
+
3290
+ /**
3291
+ * Get elements by rank range
3292
+
3293
+ * @example
3294
+ * // Pagination with rangeByRank
3295
+ * const tree = new TreeMultiSet<number>(
3296
+ * [10, 20, 30, 40, 50, 60, 70, 80, 90],
3297
+ * { enableOrderStatistic: true }
3298
+ * );
3299
+ * const pageSize = 3;
3300
+ *
3301
+ * // Page 1
3302
+ * console.log(tree.rangeByRank(0, pageSize - 1)); // [10, 20, 30];
3303
+ * // Page 2
3304
+ * console.log(tree.rangeByRank(pageSize, 2 * pageSize - 1)); // [40, 50, 60];
3305
+ * // Page 3
3306
+ * console.log(tree.rangeByRank(2 * pageSize, 3 * pageSize - 1)); // [70, 80, 90];
3307
+ */
3308
+ rangeByRank(start: number, end: number): K[] {
3309
+ return this.#core.rangeByRank(start, end).filter((k): k is K => k !== undefined);
3310
+ }
3311
+
3312
+ /**
3313
+ * Deep copy
3314
+
3315
+
3316
+
3317
+
3318
+ * @example
3319
+ * // Deep clone
875
3320
  * const ms = new TreeMultiSet<number>();
876
- * ms.add(10);
877
- * ms.add(20);
878
- * console.log(ms.lower(20)); // 10;
3321
+ * ms.add(1, 3);
3322
+ * const copy = ms.clone();
3323
+ * copy.deleteAll(1);
3324
+ * console.log(ms.has(1)); // true;
879
3325
  */
880
- lower(key: K): K | undefined {
881
- this._validateKey(key);
882
- return this.#core.lower(key);
3326
+ clone(): TreeMultiSet<K> {
3327
+ const result = new TreeMultiSet<K>([], {
3328
+ comparator: this.#isDefaultComparator ? undefined : this.comparator,
3329
+ isMapMode: this.#core.isMapMode
3330
+ });
3331
+ for (const [k, c] of this.entries()) {
3332
+ result.add(k, c);
3333
+ }
3334
+ return result;
883
3335
  }
884
3336
 
885
- // ━━━ Functional methods ━━━
3337
+ // ━━━ Tree utilities ━━━
886
3338
 
887
3339
  /**
888
- * Iterates over distinct keys with their counts.
889
- * @remarks Time O(n), Space O(1)
3340
+ * Returns keys within the given range.
3341
+ * @remarks Time O(log n + k), Space O(k) where k is result size
890
3342
 
891
3343
 
892
3344
 
@@ -926,25 +3378,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
926
3378
 
927
3379
 
928
3380
 
929
- * @example
930
- * // Iterate
931
- * const ms = new TreeMultiSet<number>();
932
- * ms.add(1, 2);
933
- * ms.add(2);
934
- * const pairs: [number, number][] = [];
935
- * ms.forEach((k, c) => pairs.push([k, c]));
936
- * console.log(pairs); // [[1, 2], [2, 1]];
937
- */
938
- forEach(callback: (key: K, count: number) => void): void {
939
- for (const [k, c] of this.entries()) {
940
- callback(k, c);
941
- }
942
- }
943
-
944
- /**
945
- * Creates a new TreeMultiSet with entries that match the predicate.
946
- * @remarks Time O(n log n), Space O(n)
947
-
948
3381
 
949
3382
 
950
3383
 
@@ -983,32 +3416,17 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
983
3416
 
984
3417
 
985
3418
 
986
- * @example
987
- * // Filter
988
- * const ms = new TreeMultiSet<number>();
989
- * ms.add(1, 3);
990
- * ms.add(2, 1);
991
- * ms.add(3, 2);
992
- * const filtered = ms.filter((k, c) => c > 1);
993
- * console.log([...filtered.keysDistinct()]); // [1, 3];
994
- */
995
- filter(predicate: (key: K, count: number) => boolean): TreeMultiSet<K> {
996
- const result = new TreeMultiSet<K>([], {
997
- comparator: this.#isDefaultComparator ? undefined : this.comparator,
998
- isMapMode: this.#core.isMapMode
999
- });
1000
- for (const [k, c] of this.entries()) {
1001
- if (predicate(k, c)) {
1002
- result.add(k, c);
1003
- }
1004
- }
1005
- return result;
1006
- }
1007
-
1008
- /**
1009
- * Reduces the multiset to a single value.
1010
- * @remarks Time O(n), Space O(1)
1011
-
3419
+
3420
+
3421
+
3422
+
3423
+
3424
+
3425
+
3426
+
3427
+
3428
+
3429
+
1012
3430
 
1013
3431
 
1014
3432
 
@@ -1048,25 +3466,25 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
1048
3466
 
1049
3467
 
1050
3468
  * @example
1051
- * // Aggregate
3469
+ * // Find in range
1052
3470
  * const ms = new TreeMultiSet<number>();
1053
- * ms.add(1, 2);
1054
- * ms.add(2, 3);
1055
- * const sum = ms.reduce((acc, k, c) => acc + k * c, 0);
1056
- * console.log(sum); // 8;
3471
+ * ms.add(10);
3472
+ * ms.add(20);
3473
+ * ms.add(30);
3474
+ * const result = ms.rangeSearch([15, 25]);
3475
+ * console.log(result.length); // 1;
1057
3476
  */
1058
- reduce<U>(callback: (accumulator: U, key: K, count: number) => U, initialValue: U): U {
1059
- let acc = initialValue;
1060
- for (const [k, c] of this.entries()) {
1061
- acc = callback(acc, k, c);
1062
- }
1063
- return acc;
3477
+ rangeSearch<C extends (key: K) => any>(
3478
+ range: [K, K],
3479
+ callback?: C
3480
+ ): (C extends undefined ? K : ReturnType<C>)[] {
3481
+ const cb = callback ?? ((k: K) => k);
3482
+ return this.#core.rangeSearch(range, node => cb(node.key));
1064
3483
  }
1065
3484
 
1066
3485
  /**
1067
- * Maps keys and counts to a new TreeMultiSet.
1068
- * When multiple keys map to the same new key, counts are merged (added).
1069
- * @remarks Time O(n log n), Space O(n)
3486
+ * Prints the internal tree structure (for debugging).
3487
+ * @remarks Time O(n), Space O(n)
1070
3488
 
1071
3489
 
1072
3490
 
@@ -1106,33 +3524,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
1106
3524
 
1107
3525
 
1108
3526
 
1109
- * @example
1110
- * // Transform
1111
- * const ms = new TreeMultiSet<number>();
1112
- * ms.add(1, 2);
1113
- * ms.add(2, 3);
1114
- * const doubled = ms.map((k, c) => [k * 10, c] as [number, number]);
1115
- * console.log([...doubled.keysDistinct()]); // [10, 20];
1116
- */
1117
- map<K2>(
1118
- mapper: (key: K, count: number) => [K2, number],
1119
- options?: { comparator?: Comparator<K2> }
1120
- ): TreeMultiSet<K2> {
1121
- const result = new TreeMultiSet<K2>([], {
1122
- comparator: options?.comparator,
1123
- isMapMode: this.#core.isMapMode
1124
- });
1125
- for (const [k, c] of this.entries()) {
1126
- const [newKey, newCount] = mapper(k, c);
1127
- result.add(newKey, newCount);
1128
- }
1129
- return result;
1130
- }
1131
-
1132
- /**
1133
- * Creates an independent copy of this multiset.
1134
- * @remarks Time O(n log n), Space O(n)
1135
-
1136
3527
 
1137
3528
 
1138
3529
 
@@ -1171,31 +3562,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
1171
3562
 
1172
3563
 
1173
3564
 
1174
- * @example
1175
- * // Deep clone
1176
- * const ms = new TreeMultiSet<number>();
1177
- * ms.add(1, 3);
1178
- * const copy = ms.clone();
1179
- * copy.deleteAll(1);
1180
- * console.log(ms.has(1)); // true;
1181
- */
1182
- clone(): TreeMultiSet<K> {
1183
- const result = new TreeMultiSet<K>([], {
1184
- comparator: this.#isDefaultComparator ? undefined : this.comparator,
1185
- isMapMode: this.#core.isMapMode
1186
- });
1187
- for (const [k, c] of this.entries()) {
1188
- result.add(k, c);
1189
- }
1190
- return result;
1191
- }
1192
-
1193
- // ━━━ Tree utilities ━━━
1194
-
1195
- /**
1196
- * Returns keys within the given range.
1197
- * @remarks Time O(log n + k), Space O(k) where k is result size
1198
-
1199
3565
 
1200
3566
 
1201
3567
 
@@ -1225,27 +3591,21 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
1225
3591
 
1226
3592
 
1227
3593
 
1228
- * @example
1229
- * // Find in range
1230
- * const ms = new TreeMultiSet<number>();
1231
- * ms.add(10);
1232
- * ms.add(20);
1233
- * ms.add(30);
1234
- * const result = ms.rangeSearch([15, 25]);
1235
- * console.log(result.length); // 1;
1236
- */
1237
- rangeSearch<C extends (key: K) => any>(
1238
- range: [K, K],
1239
- callback?: C
1240
- ): (C extends undefined ? K : ReturnType<C>)[] {
1241
- const cb = callback ?? ((k: K) => k);
1242
- return this.#core.rangeSearch(range, node => cb(node.key));
1243
- }
1244
-
1245
- /**
1246
- * Prints the internal tree structure (for debugging).
1247
- * @remarks Time O(n), Space O(n)
1248
-
3594
+
3595
+
3596
+
3597
+
3598
+
3599
+
3600
+
3601
+
3602
+
3603
+
3604
+
3605
+
3606
+
3607
+
3608
+
1249
3609
 
1250
3610
 
1251
3611