binary-tree-typed 2.5.0 → 2.5.1

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 (75) hide show
  1. package/dist/cjs/index.cjs +609 -0
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs-legacy/index.cjs +609 -0
  4. package/dist/cjs-legacy/index.cjs.map +1 -1
  5. package/dist/esm/index.mjs +609 -0
  6. package/dist/esm/index.mjs.map +1 -1
  7. package/dist/esm-legacy/index.mjs +609 -0
  8. package/dist/esm-legacy/index.mjs.map +1 -1
  9. package/dist/types/data-structures/base/index.d.ts +1 -0
  10. package/dist/types/data-structures/base/iterable-entry-base.d.ts +8 -8
  11. package/dist/types/data-structures/base/linear-base.d.ts +3 -3
  12. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +252 -0
  13. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +294 -0
  14. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +527 -2
  15. package/dist/types/data-structures/binary-tree/bst.d.ts +505 -1
  16. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +399 -0
  17. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +126 -1
  18. package/dist/types/data-structures/binary-tree/tree-map.d.ts +2881 -382
  19. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +2867 -347
  20. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +2328 -312
  21. package/dist/types/data-structures/binary-tree/tree-set.d.ts +2671 -277
  22. package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -4
  23. package/dist/types/data-structures/graph/directed-graph.d.ts +210 -0
  24. package/dist/types/data-structures/graph/undirected-graph.d.ts +189 -0
  25. package/dist/types/data-structures/hash/hash-map.d.ts +241 -10
  26. package/dist/types/data-structures/heap/heap.d.ts +294 -0
  27. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +360 -3
  28. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +318 -3
  29. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +380 -2
  30. package/dist/types/data-structures/matrix/matrix.d.ts +168 -0
  31. package/dist/types/data-structures/queue/deque.d.ts +319 -4
  32. package/dist/types/data-structures/queue/queue.d.ts +252 -0
  33. package/dist/types/data-structures/stack/stack.d.ts +210 -0
  34. package/dist/types/data-structures/trie/trie.d.ts +256 -4
  35. package/dist/types/interfaces/graph.d.ts +1 -1
  36. package/dist/types/types/common.d.ts +2 -2
  37. package/dist/types/types/data-structures/heap/heap.d.ts +1 -0
  38. package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +1 -0
  39. package/dist/types/types/utils/validate-type.d.ts +4 -4
  40. package/dist/umd/binary-tree-typed.js +609 -0
  41. package/dist/umd/binary-tree-typed.js.map +1 -1
  42. package/dist/umd/binary-tree-typed.min.js +5 -5
  43. package/dist/umd/binary-tree-typed.min.js.map +1 -1
  44. package/package.json +2 -2
  45. package/src/data-structures/base/index.ts +1 -0
  46. package/src/data-structures/base/iterable-entry-base.ts +8 -8
  47. package/src/data-structures/base/linear-base.ts +3 -3
  48. package/src/data-structures/binary-tree/avl-tree.ts +252 -0
  49. package/src/data-structures/binary-tree/binary-indexed-tree.ts +295 -1
  50. package/src/data-structures/binary-tree/binary-tree.ts +527 -2
  51. package/src/data-structures/binary-tree/bst.ts +505 -1
  52. package/src/data-structures/binary-tree/red-black-tree.ts +399 -0
  53. package/src/data-structures/binary-tree/segment-tree.ts +127 -2
  54. package/src/data-structures/binary-tree/tree-map.ts +2958 -459
  55. package/src/data-structures/binary-tree/tree-multi-map.ts +3069 -549
  56. package/src/data-structures/binary-tree/tree-multi-set.ts +2476 -460
  57. package/src/data-structures/binary-tree/tree-set.ts +2816 -422
  58. package/src/data-structures/graph/abstract-graph.ts +4 -4
  59. package/src/data-structures/graph/directed-graph.ts +210 -0
  60. package/src/data-structures/graph/undirected-graph.ts +189 -0
  61. package/src/data-structures/hash/hash-map.ts +246 -15
  62. package/src/data-structures/heap/heap.ts +294 -0
  63. package/src/data-structures/linked-list/doubly-linked-list.ts +360 -3
  64. package/src/data-structures/linked-list/singly-linked-list.ts +318 -3
  65. package/src/data-structures/linked-list/skip-linked-list.ts +380 -2
  66. package/src/data-structures/matrix/matrix.ts +169 -1
  67. package/src/data-structures/queue/deque.ts +320 -5
  68. package/src/data-structures/queue/queue.ts +252 -0
  69. package/src/data-structures/stack/stack.ts +210 -0
  70. package/src/data-structures/trie/trie.ts +257 -5
  71. package/src/interfaces/graph.ts +1 -1
  72. package/src/types/common.ts +2 -2
  73. package/src/types/data-structures/heap/heap.ts +1 -0
  74. package/src/types/data-structures/priority-queue/priority-queue.ts +1 -0
  75. package/src/types/utils/validate-type.ts +4 -4
@@ -86,6 +86,27 @@ 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
+
89
110
  * @example
90
111
  * // Unique key count
91
112
  * const ms = new TreeMultiSet<number>();
@@ -138,17 +159,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
138
159
 
139
160
 
140
161
 
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
162
 
153
163
 
154
164
 
@@ -190,38 +200,8 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
190
200
 
191
201
 
192
202
 
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
203
 
209
204
 
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
205
 
226
206
 
227
207
 
@@ -254,59 +234,46 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
254
234
 
255
235
 
256
236
 
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)
237
+
238
+
239
+
240
+
241
+
242
+
243
+
244
+
245
+
246
+
247
+
248
+
249
+
250
+
251
+
252
+
253
+
254
+
255
+
256
+
257
+
258
+
259
+
260
+
261
+
262
+
263
+
264
+
282
265
 
283
266
 
284
267
  * @example
285
- * // Set occurrence count
286
- * const ms = new TreeMultiSet<number>();
287
- * ms.setCount(1, 3);
288
- * console.log(ms.count(1)); // 3;
268
+ * // Check empty
269
+ * console.log(new TreeMultiSet().isEmpty()); // true;
289
270
  */
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;
271
+ isEmpty(): boolean {
272
+ return this.size === 0;
305
273
  }
306
274
 
307
275
  /**
308
- * Delete `n` occurrences of `key` (default 1).
309
- * @returns True if any occurrence was removed.
276
+ * Whether the multiset contains the given key.
310
277
  * @remarks Time O(log n), Space O(1)
311
278
 
312
279
 
@@ -349,72 +316,10 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
349
316
 
350
317
 
351
318
 
352
- * @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;
358
- */
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;
375
- }
376
-
377
- /**
378
- * Delete all occurrences of the given key.
379
- * @returns True if any occurrence was removed.
380
- * @remarks Time O(log n), Space O(1)
381
319
 
382
320
 
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
321
 
403
322
 
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
323
 
419
324
 
420
325
 
@@ -453,31 +358,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
453
358
 
454
359
 
455
360
 
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
361
 
482
362
 
483
363
 
@@ -516,63 +396,183 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
516
396
 
517
397
 
518
398
 
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
399
 
534
400
 
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)
401
+
402
+
403
+
404
+
405
+
406
+
407
+
408
+
409
+
410
+
411
+
412
+
413
+
414
+
415
+
416
+
417
+
418
+
419
+
420
+
421
+
549
422
 
550
423
 
551
424
  * @example
552
- * // Key-count pairs
425
+ * // Check existence
553
426
  * const ms = new TreeMultiSet<number>();
554
- * ms.add(1, 2);
555
- * ms.add(3);
556
- * console.log(ms.toEntries()); // [[1, 2], [3, 1]];
427
+ * ms.add(1);
428
+ * console.log(ms.has(1)); // true;
429
+ * console.log(ms.has(2)); // false;
557
430
  */
558
- toEntries(): Array<[K, number]> {
559
- return [...this.entries()];
431
+ has(key: K): boolean {
432
+ this._validateKey(key);
433
+ return this.count(key) > 0;
560
434
  }
561
435
 
562
436
  /**
563
- * Expose comparator for advanced usage/testing (read-only).
564
- * @remarks Time O(1), Space O(1)
437
+ * Returns the count of occurrences for the given key.
438
+ * @remarks Time O(log n), Space O(1)
439
+
440
+
441
+
442
+
443
+
444
+
445
+
446
+
447
+
448
+
449
+
450
+
451
+
452
+
453
+
454
+
455
+
456
+
457
+
458
+
459
+
460
+
461
+
462
+ * @example
463
+ * // Get occurrence count
464
+ * const ms = new TreeMultiSet<number>();
465
+ * ms.add(1, 5);
466
+ * console.log(ms.count(1)); // 5;
565
467
  */
566
- get comparator(): Comparator<K> {
567
- return this.#core.comparator;
468
+ count(key: K): number {
469
+ this._validateKey(key);
470
+ return this.#core.get(key) ?? 0;
568
471
  }
569
472
 
570
- // ━━━ clear ━━━
571
-
572
473
  /**
573
- * Remove all elements from the multiset.
574
- * @remarks Time O(1), Space O(1)
575
-
474
+ * Add `n` occurrences of `key`.
475
+ * @returns True if the multiset changed.
476
+ * @remarks Time O(log n), Space O(1)
477
+
478
+
479
+
480
+
481
+
482
+
483
+
484
+
485
+
486
+
487
+
488
+
489
+
490
+
491
+
492
+
493
+
494
+
495
+
496
+
497
+
498
+
499
+
500
+
501
+
502
+
503
+
504
+
505
+
506
+
507
+
508
+
509
+
510
+
511
+
512
+
513
+
514
+
515
+
516
+
517
+
518
+
519
+
520
+
521
+
522
+
523
+
524
+
525
+
526
+
527
+
528
+
529
+
530
+
531
+
532
+
533
+
534
+
535
+
536
+
537
+
538
+
539
+
540
+
541
+
542
+
543
+
544
+
545
+
546
+
547
+
548
+
549
+
550
+
551
+
552
+
553
+
554
+
555
+
556
+
557
+
558
+
559
+
560
+
561
+
562
+
563
+
564
+
565
+
566
+
567
+
568
+
569
+
570
+
571
+
572
+
573
+
574
+
575
+
576
576
 
577
577
 
578
578
 
@@ -612,97 +612,2248 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
612
612
 
613
613
 
614
614
  * @example
615
- * // Remove all
615
+ * // Add elements
616
616
  * const ms = new TreeMultiSet<number>();
617
617
  * ms.add(1);
618
- * ms.clear();
619
- * console.log(ms.isEmpty()); // true;
618
+ * ms.add(1);
619
+ * ms.add(2);
620
+ * console.log(ms.count(1)); // 2;
621
+ * console.log(ms.size); // 3;
620
622
  */
621
- clear(): void {
622
- this.#core.clear();
623
- this._size = 0;
624
- }
623
+ add(key: K, n = 1): boolean {
624
+ this._validateKey(key);
625
+ this._validateCount(n);
626
+ if (n === 0) return false;
625
627
 
626
- // ━━━ Navigable methods ━━━
628
+ const old = this.#core.get(key) ?? 0;
629
+ const next = old + n;
630
+ this.#core.set(key, next);
631
+ this._size += n;
632
+ return true;
633
+ }
627
634
 
628
635
  /**
629
- * Returns the smallest key, or undefined if empty.
636
+ * Set count for `key` to exactly `n`.
637
+ * @returns True if changed.
630
638
  * @remarks Time O(log n), Space O(1)
631
-
639
+
640
+
641
+
642
+
643
+
644
+
645
+
646
+
647
+
648
+
649
+
650
+
651
+
652
+
653
+
654
+
655
+
656
+
657
+
658
+
659
+
632
660
 
633
661
 
634
662
  * @example
635
- * // Smallest element
663
+ * // Set occurrence count
636
664
  * const ms = new TreeMultiSet<number>();
637
- * ms.add(3);
638
- * ms.add(1);
639
- * console.log(ms.first()); // 1;
665
+ * ms.setCount(1, 3);
666
+ * console.log(ms.count(1)); // 3;
640
667
  */
641
- first(): K | undefined {
642
- return this.#core.getLeftMost();
668
+ setCount(key: K, n: number): boolean {
669
+ this._validateKey(key);
670
+ this._validateCount(n);
671
+
672
+ const old = this.#core.get(key) ?? 0;
673
+ if (old === n) return false;
674
+
675
+ if (n === 0) {
676
+ if (old !== 0) this.#core.delete(key);
677
+ } else {
678
+ this.#core.set(key, n);
679
+ }
680
+
681
+ this._size += n - old;
682
+ return true;
643
683
  }
644
684
 
645
685
  /**
646
- * Returns the largest key, or undefined if empty.
686
+ * Delete `n` occurrences of `key` (default 1).
687
+ * @returns True if any occurrence was removed.
647
688
  * @remarks Time O(log n), Space O(1)
648
-
649
689
 
650
690
 
651
- * @example
652
- * // Largest element
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
+
717
+
718
+
719
+
720
+
721
+
722
+
723
+
724
+
725
+
726
+
727
+
728
+
729
+
730
+
731
+
732
+
733
+
734
+
735
+
736
+
737
+
738
+
739
+
740
+
741
+
742
+
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
+ * @example
836
+ * // Remove one occurrence
653
837
  * const ms = new TreeMultiSet<number>();
654
- * ms.add(1);
655
- * ms.add(3);
656
- * console.log(ms.last()); // 3;
838
+ * ms.add(1, 3);
839
+ * ms.delete(1);
840
+ * console.log(ms.count(1)); // 2;
657
841
  */
658
- last(): K | undefined {
659
- return this.#core.getRightMost();
842
+ delete(key: K, n = 1): boolean {
843
+ this._validateKey(key);
844
+ this._validateCount(n);
845
+ if (n === 0) return false;
846
+
847
+ const old = this.#core.get(key) ?? 0;
848
+ if (old === 0) return false;
849
+
850
+ const removed = Math.min(old, n);
851
+ const next = old - removed;
852
+
853
+ if (next === 0) this.#core.delete(key);
854
+ else this.#core.set(key, next);
855
+
856
+ this._size -= removed;
857
+ return true;
660
858
  }
661
859
 
662
860
  /**
663
- * Removes all occurrences of the smallest key and returns it.
861
+ * Delete all occurrences of the given key.
862
+ * @returns True if any occurrence was removed.
664
863
  * @remarks Time O(log n), Space O(1)
665
-
864
+
865
+
866
+
867
+
868
+
869
+
870
+
871
+
872
+
873
+
874
+
875
+
876
+
877
+
878
+
879
+
880
+
881
+
882
+
883
+
884
+
666
885
 
667
886
 
668
887
  * @example
669
- * // Remove and return smallest
888
+ * // Remove all occurrences
670
889
  * const ms = new TreeMultiSet<number>();
671
- * ms.add(2);
672
- * ms.add(1);
673
- * console.log(ms.pollFirst()); // 1;
890
+ * ms.add(1, 3);
891
+ * ms.deleteAll(1);
674
892
  * console.log(ms.has(1)); // false;
675
893
  */
676
- pollFirst(): K | undefined {
677
- const key = this.first();
678
- if (key === undefined) return undefined;
679
- this.deleteAll(key);
680
- return key;
894
+ deleteAll(key: K): boolean {
895
+ this._validateKey(key);
896
+ const old = this.#core.get(key) ?? 0;
897
+ if (old === 0) return false;
898
+ this.#core.delete(key);
899
+ this._size -= old;
900
+ return true;
681
901
  }
682
902
 
683
903
  /**
684
- * Removes all occurrences of the largest key and returns it.
685
- * @remarks Time O(log n), Space O(1)
686
-
904
+ * Iterates over distinct keys (each key yielded once).
905
+ * @remarks Time O(n), Space O(1)
906
+
907
+
908
+
909
+
910
+
911
+
912
+
913
+
914
+
915
+
916
+
917
+
918
+
919
+
920
+
921
+
922
+
923
+
924
+
925
+
926
+
687
927
 
688
928
 
689
929
  * @example
690
- * // Remove and return largest
930
+ * // Iterate unique keys
691
931
  * const ms = new TreeMultiSet<number>();
692
- * ms.add(1);
693
- * ms.add(3);
694
- * console.log(ms.pollLast()); // 3;
932
+ * ms.add(1, 2);
933
+ * ms.add(2);
934
+ * console.log([...ms.keysDistinct()]); // [1, 2];
695
935
  */
696
- pollLast(): K | undefined {
697
- const key = this.last();
698
- if (key === undefined) return undefined;
699
- this.deleteAll(key);
700
- return key;
936
+ *keysDistinct(): IterableIterator<K> {
937
+ yield* this.#core.keys();
938
+ }
939
+
940
+ /**
941
+ * Iterates over entries as [key, count] pairs.
942
+ * @remarks Time O(n), Space O(1)
943
+
944
+
945
+
946
+
947
+
948
+
949
+
950
+
951
+
952
+
953
+
954
+
955
+
956
+
957
+
958
+
959
+
960
+
961
+
962
+
963
+
964
+
965
+
966
+
967
+
968
+
969
+
970
+
971
+
972
+
973
+
974
+
975
+
976
+
977
+
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
+
1005
+
1006
+
1007
+
1008
+
1009
+
1010
+
1011
+
1012
+
1013
+
1014
+
1015
+
1016
+
1017
+
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
+ * @example
1087
+ * // Iterate entries
1088
+ * const ms = new TreeMultiSet<number>();
1089
+ * ms.add(1, 2);
1090
+ * console.log([...ms.entries()].length); // > 0;
1091
+ */
1092
+ *entries(): IterableIterator<[K, number]> {
1093
+ for (const [k, v] of this.#core) {
1094
+ yield [k, v ?? 0];
1095
+ }
1096
+ }
1097
+
1098
+ /**
1099
+ * Expanded iteration (default). Each key is yielded `count(key)` times.
1100
+ * @remarks Time O(size), Space O(1) where size is total occurrences
1101
+ */
1102
+ *[Symbol.iterator](): Iterator<K> {
1103
+ for (const [k, c] of this.entries()) {
1104
+ for (let i = 0; i < c; i++) yield k;
1105
+ }
1106
+ }
1107
+
1108
+ /**
1109
+ * Returns an array with all elements (expanded).
1110
+ * @remarks Time O(size), Space O(size)
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
+
1177
+
1178
+
1179
+
1180
+
1181
+
1182
+
1183
+
1184
+
1185
+
1186
+
1187
+
1188
+
1189
+
1190
+
1191
+
1192
+
1193
+
1194
+
1195
+
1196
+
1197
+
1198
+
1199
+
1200
+
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
+ * @example
1255
+ * // All elements (with duplicates)
1256
+ * const ms = new TreeMultiSet<number>();
1257
+ * ms.add(1, 2);
1258
+ * ms.add(2);
1259
+ * console.log(ms.toArray()); // [1, 1, 2];
1260
+ */
1261
+ toArray(): K[] {
1262
+ return [...this];
1263
+ }
1264
+
1265
+ /**
1266
+ * Returns an array with distinct keys only.
1267
+ * @remarks Time O(n), Space O(n)
1268
+
1269
+
1270
+
1271
+
1272
+
1273
+
1274
+
1275
+
1276
+
1277
+
1278
+
1279
+
1280
+
1281
+
1282
+
1283
+
1284
+
1285
+
1286
+
1287
+
1288
+
1289
+
1290
+
1291
+ * @example
1292
+ * // Unique keys only
1293
+ * const ms = new TreeMultiSet<number>();
1294
+ * ms.add(1, 3);
1295
+ * ms.add(2);
1296
+ * console.log(ms.toDistinctArray()); // [1, 2];
1297
+ */
1298
+ toDistinctArray(): K[] {
1299
+ return [...this.keysDistinct()];
1300
+ }
1301
+
1302
+ /**
1303
+ * Returns an array of [key, count] entries.
1304
+ * @remarks Time O(n), Space O(n)
1305
+
1306
+
1307
+
1308
+
1309
+
1310
+
1311
+
1312
+
1313
+
1314
+
1315
+
1316
+
1317
+
1318
+
1319
+
1320
+
1321
+
1322
+
1323
+
1324
+
1325
+
1326
+
1327
+
1328
+ * @example
1329
+ * // Key-count pairs
1330
+ * const ms = new TreeMultiSet<number>();
1331
+ * ms.add(1, 2);
1332
+ * ms.add(3);
1333
+ * console.log(ms.toEntries()); // [[1, 2], [3, 1]];
1334
+ */
1335
+ toEntries(): Array<[K, number]> {
1336
+ return [...this.entries()];
1337
+ }
1338
+
1339
+ /**
1340
+ * Expose comparator for advanced usage/testing (read-only).
1341
+ * @remarks Time O(1), Space O(1)
1342
+ */
1343
+ get comparator(): Comparator<K> {
1344
+ return this.#core.comparator;
1345
+ }
1346
+
1347
+ // ━━━ clear ━━━
1348
+
1349
+ /**
1350
+ * Remove all elements from the multiset.
1351
+ * @remarks Time O(1), Space O(1)
1352
+
1353
+
1354
+
1355
+
1356
+
1357
+
1358
+
1359
+
1360
+
1361
+
1362
+
1363
+
1364
+
1365
+
1366
+
1367
+
1368
+
1369
+
1370
+
1371
+
1372
+
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
+
1400
+
1401
+
1402
+
1403
+
1404
+
1405
+
1406
+
1407
+
1408
+
1409
+
1410
+
1411
+
1412
+
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
+
1440
+
1441
+
1442
+
1443
+
1444
+
1445
+
1446
+
1447
+
1448
+
1449
+
1450
+
1451
+
1452
+
1453
+
1454
+
1455
+
1456
+
1457
+
1458
+
1459
+
1460
+
1461
+
1462
+
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
+ * @example
1497
+ * // Remove all
1498
+ * const ms = new TreeMultiSet<number>();
1499
+ * ms.add(1);
1500
+ * ms.clear();
1501
+ * console.log(ms.isEmpty()); // true;
1502
+ */
1503
+ clear(): void {
1504
+ this.#core.clear();
1505
+ this._size = 0;
1506
+ }
1507
+
1508
+ // ━━━ Navigable methods ━━━
1509
+
1510
+ /**
1511
+ * Returns the smallest key, or undefined if empty.
1512
+ * @remarks Time O(log n), Space O(1)
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
+ * @example
1538
+ * // Smallest element
1539
+ * const ms = new TreeMultiSet<number>();
1540
+ * ms.add(3);
1541
+ * ms.add(1);
1542
+ * console.log(ms.first()); // 1;
1543
+ */
1544
+ first(): K | undefined {
1545
+ return this.#core.getLeftMost();
1546
+ }
1547
+
1548
+ /**
1549
+ * Returns the largest key, or undefined if empty.
1550
+ * @remarks Time O(log n), Space O(1)
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
+ * @example
1576
+ * // Largest element
1577
+ * const ms = new TreeMultiSet<number>();
1578
+ * ms.add(1);
1579
+ * ms.add(3);
1580
+ * console.log(ms.last()); // 3;
1581
+ */
1582
+ last(): K | undefined {
1583
+ return this.#core.getRightMost();
1584
+ }
1585
+
1586
+ /**
1587
+ * Removes all occurrences of the smallest key and returns it.
1588
+ * @remarks Time O(log n), Space O(1)
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
+ * @example
1614
+ * // Remove and return smallest
1615
+ * const ms = new TreeMultiSet<number>();
1616
+ * ms.add(2);
1617
+ * ms.add(1);
1618
+ * console.log(ms.pollFirst()); // 1;
1619
+ * console.log(ms.has(1)); // false;
1620
+ */
1621
+ pollFirst(): K | undefined {
1622
+ const key = this.first();
1623
+ if (key === undefined) return undefined;
1624
+ this.deleteAll(key);
1625
+ return key;
1626
+ }
1627
+
1628
+ /**
1629
+ * Removes all occurrences of the largest key and returns it.
1630
+ * @remarks Time O(log n), Space O(1)
1631
+
1632
+
1633
+
1634
+
1635
+
1636
+
1637
+
1638
+
1639
+
1640
+
1641
+
1642
+
1643
+
1644
+
1645
+
1646
+
1647
+
1648
+
1649
+
1650
+
1651
+
1652
+
1653
+
1654
+
1655
+ * @example
1656
+ * // Remove and return largest
1657
+ * const ms = new TreeMultiSet<number>();
1658
+ * ms.add(1);
1659
+ * ms.add(3);
1660
+ * console.log(ms.pollLast()); // 3;
1661
+ */
1662
+ pollLast(): K | undefined {
1663
+ const key = this.last();
1664
+ if (key === undefined) return undefined;
1665
+ this.deleteAll(key);
1666
+ return key;
1667
+ }
1668
+
1669
+ /**
1670
+ * Returns the smallest key >= given key, or undefined.
1671
+ * @remarks Time O(log n), Space O(1)
1672
+
1673
+
1674
+
1675
+
1676
+
1677
+
1678
+
1679
+
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
+
1708
+
1709
+
1710
+
1711
+
1712
+
1713
+
1714
+
1715
+
1716
+
1717
+
1718
+
1719
+
1720
+
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
+
1749
+
1750
+
1751
+
1752
+
1753
+
1754
+
1755
+
1756
+
1757
+
1758
+
1759
+
1760
+
1761
+
1762
+
1763
+
1764
+
1765
+
1766
+
1767
+
1768
+
1769
+
1770
+
1771
+
1772
+
1773
+
1774
+
1775
+
1776
+
1777
+
1778
+
1779
+
1780
+
1781
+
1782
+
1783
+
1784
+
1785
+
1786
+ * @example
1787
+ * // Least key ≥ target
1788
+ * const ms = new TreeMultiSet<number>();
1789
+ * ms.add(10);
1790
+ * ms.add(20);
1791
+ * ms.add(30);
1792
+ * console.log(ms.ceiling(15)); // 20;
1793
+ */
1794
+ ceiling(key: K): K | undefined {
1795
+ this._validateKey(key);
1796
+ return this.#core.ceiling(key);
1797
+ }
1798
+
1799
+ /**
1800
+ * Returns the largest key <= given key, or undefined.
1801
+ * @remarks Time O(log n), Space O(1)
1802
+
1803
+
1804
+
1805
+
1806
+
1807
+
1808
+
1809
+
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
+ * @example
1917
+ * // Greatest key ≤ target
1918
+ * const ms = new TreeMultiSet<number>();
1919
+ * ms.add(10);
1920
+ * ms.add(20);
1921
+ * ms.add(30);
1922
+ * console.log(ms.floor(25)); // 20;
1923
+ */
1924
+ floor(key: K): K | undefined {
1925
+ this._validateKey(key);
1926
+ return this.#core.floor(key);
1927
+ }
1928
+
1929
+ /**
1930
+ * Returns the smallest key > given key, or undefined.
1931
+ * @remarks Time O(log n), Space O(1)
1932
+
1933
+
1934
+
1935
+
1936
+
1937
+
1938
+
1939
+
1940
+
1941
+
1942
+
1943
+
1944
+
1945
+
1946
+
1947
+
1948
+
1949
+
1950
+
1951
+
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
+ * @example
2047
+ * // Least key > target
2048
+ * const ms = new TreeMultiSet<number>();
2049
+ * ms.add(10);
2050
+ * ms.add(20);
2051
+ * console.log(ms.higher(10)); // 20;
2052
+ */
2053
+ higher(key: K): K | undefined {
2054
+ this._validateKey(key);
2055
+ return this.#core.higher(key);
2056
+ }
2057
+
2058
+ /**
2059
+ * Returns the largest key < given key, or undefined.
2060
+ * @remarks Time O(log n), Space O(1)
2061
+
2062
+
2063
+
2064
+
2065
+
2066
+
2067
+
2068
+
2069
+
2070
+
2071
+
2072
+
2073
+
2074
+
2075
+
2076
+
2077
+
2078
+
2079
+
2080
+
2081
+
2082
+
2083
+
2084
+
2085
+
2086
+
2087
+
2088
+
2089
+
2090
+
2091
+
2092
+
2093
+
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
+ * @example
2176
+ * // Greatest key < target
2177
+ * const ms = new TreeMultiSet<number>();
2178
+ * ms.add(10);
2179
+ * ms.add(20);
2180
+ * console.log(ms.lower(20)); // 10;
2181
+ */
2182
+ lower(key: K): K | undefined {
2183
+ this._validateKey(key);
2184
+ return this.#core.lower(key);
2185
+ }
2186
+
2187
+ // ━━━ Functional methods ━━━
2188
+
2189
+ /**
2190
+ * Iterates over distinct keys with their counts.
2191
+ * @remarks Time O(n), Space O(1)
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
+
2221
+
2222
+
2223
+
2224
+
2225
+
2226
+
2227
+
2228
+
2229
+
2230
+
2231
+
2232
+
2233
+
2234
+
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
+ * @example
2337
+ * // Iterate
2338
+ * const ms = new TreeMultiSet<number>();
2339
+ * ms.add(1, 2);
2340
+ * ms.add(2);
2341
+ * const pairs: [number, number][] = [];
2342
+ * ms.forEach((k, c) => pairs.push([k, c]));
2343
+ * console.log(pairs); // [[1, 2], [2, 1]];
2344
+ */
2345
+ forEach(callback: (key: K, count: number) => void): void {
2346
+ for (const [k, c] of this.entries()) {
2347
+ callback(k, c);
2348
+ }
2349
+ }
2350
+
2351
+ /**
2352
+ * Creates a new TreeMultiSet with entries that match the predicate.
2353
+ * @remarks Time O(n log n), Space O(n)
2354
+
2355
+
2356
+
2357
+
2358
+
2359
+
2360
+
2361
+
2362
+
2363
+
2364
+
2365
+
2366
+
2367
+
2368
+
2369
+
2370
+
2371
+
2372
+
2373
+
2374
+
2375
+
2376
+
2377
+
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
+ * @example
2499
+ * // Filter
2500
+ * const ms = new TreeMultiSet<number>();
2501
+ * ms.add(1, 3);
2502
+ * ms.add(2, 1);
2503
+ * ms.add(3, 2);
2504
+ * const filtered = ms.filter((k, c) => c > 1);
2505
+ * console.log([...filtered.keysDistinct()]); // [1, 3];
2506
+ */
2507
+ filter(predicate: (key: K, count: number) => boolean): TreeMultiSet<K> {
2508
+ const result = new TreeMultiSet<K>([], {
2509
+ comparator: this.#isDefaultComparator ? undefined : this.comparator,
2510
+ isMapMode: this.#core.isMapMode
2511
+ });
2512
+ for (const [k, c] of this.entries()) {
2513
+ if (predicate(k, c)) {
2514
+ result.add(k, c);
2515
+ }
2516
+ }
2517
+ return result;
2518
+ }
2519
+
2520
+ /**
2521
+ * Reduces the multiset to a single value.
2522
+ * @remarks Time O(n), Space O(1)
2523
+
2524
+
2525
+
2526
+
2527
+
2528
+
2529
+
2530
+
2531
+
2532
+
2533
+
2534
+
2535
+
2536
+
2537
+
2538
+
2539
+
2540
+
2541
+
2542
+
2543
+
2544
+
2545
+
2546
+
2547
+
2548
+
2549
+
2550
+
2551
+
2552
+
2553
+
2554
+
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
+ * @example
2668
+ * // Aggregate
2669
+ * const ms = new TreeMultiSet<number>();
2670
+ * ms.add(1, 2);
2671
+ * ms.add(2, 3);
2672
+ * const sum = ms.reduce((acc, k, c) => acc + k * c, 0);
2673
+ * console.log(sum); // 8;
2674
+ */
2675
+ reduce<U>(callback: (accumulator: U, key: K, count: number) => U, initialValue: U): U {
2676
+ let acc = initialValue;
2677
+ for (const [k, c] of this.entries()) {
2678
+ acc = callback(acc, k, c);
2679
+ }
2680
+ return acc;
2681
+ }
2682
+
2683
+ /**
2684
+ * Maps keys and counts to a new TreeMultiSet.
2685
+ * When multiple keys map to the same new key, counts are merged (added).
2686
+ * @remarks Time O(n log n), Space O(n)
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
+
2715
+
2716
+
2717
+
2718
+
2719
+
2720
+
2721
+
2722
+
2723
+
2724
+
2725
+
2726
+
2727
+
2728
+
2729
+
2730
+
2731
+
2732
+
2733
+
2734
+
2735
+
2736
+
2737
+
2738
+
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
+ * @example
2832
+ * // Transform
2833
+ * const ms = new TreeMultiSet<number>();
2834
+ * ms.add(1, 2);
2835
+ * ms.add(2, 3);
2836
+ * const doubled = ms.map((k, c) => [k * 10, c] as [number, number]);
2837
+ * console.log([...doubled.keysDistinct()]); // [10, 20];
2838
+ */
2839
+ map<K2>(
2840
+ mapper: (key: K, count: number) => [K2, number],
2841
+ options?: { comparator?: Comparator<K2> }
2842
+ ): TreeMultiSet<K2> {
2843
+ const result = new TreeMultiSet<K2>([], {
2844
+ comparator: options?.comparator,
2845
+ isMapMode: this.#core.isMapMode
2846
+ });
2847
+ for (const [k, c] of this.entries()) {
2848
+ const [newKey, newCount] = mapper(k, c);
2849
+ result.add(newKey, newCount);
2850
+ }
2851
+ return result;
701
2852
  }
702
2853
 
703
2854
  /**
704
- * Returns the smallest key >= given key, or undefined.
705
- * @remarks Time O(log n), Space O(1)
2855
+ * Creates an independent copy of this multiset.
2856
+ * @remarks Time O(n log n), Space O(n)
706
2857
 
707
2858
 
708
2859
 
@@ -733,23 +2884,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
733
2884
 
734
2885
 
735
2886
 
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
2887
 
754
2888
 
755
2889
 
@@ -779,23 +2913,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
779
2913
 
780
2914
 
781
2915
 
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
2916
 
800
2917
 
801
2918
 
@@ -825,22 +2942,33 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
825
2942
 
826
2943
 
827
2944
 
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
-
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
+
844
2972
 
845
2973
 
846
2974
 
@@ -871,22 +2999,29 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
871
2999
 
872
3000
 
873
3001
  * @example
874
- * // Greatest key < target
3002
+ * // Deep clone
875
3003
  * const ms = new TreeMultiSet<number>();
876
- * ms.add(10);
877
- * ms.add(20);
878
- * console.log(ms.lower(20)); // 10;
3004
+ * ms.add(1, 3);
3005
+ * const copy = ms.clone();
3006
+ * copy.deleteAll(1);
3007
+ * console.log(ms.has(1)); // true;
879
3008
  */
880
- lower(key: K): K | undefined {
881
- this._validateKey(key);
882
- return this.#core.lower(key);
3009
+ clone(): TreeMultiSet<K> {
3010
+ const result = new TreeMultiSet<K>([], {
3011
+ comparator: this.#isDefaultComparator ? undefined : this.comparator,
3012
+ isMapMode: this.#core.isMapMode
3013
+ });
3014
+ for (const [k, c] of this.entries()) {
3015
+ result.add(k, c);
3016
+ }
3017
+ return result;
883
3018
  }
884
3019
 
885
- // ━━━ Functional methods ━━━
3020
+ // ━━━ Tree utilities ━━━
886
3021
 
887
3022
  /**
888
- * Iterates over distinct keys with their counts.
889
- * @remarks Time O(n), Space O(1)
3023
+ * Returns keys within the given range.
3024
+ * @remarks Time O(log n + k), Space O(k) where k is result size
890
3025
 
891
3026
 
892
3027
 
@@ -926,26 +3061,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
926
3061
 
927
3062
 
928
3063
 
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
-
949
3064
 
950
3065
 
951
3066
 
@@ -983,32 +3098,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
983
3098
 
984
3099
 
985
3100
 
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
-
1012
3101
 
1013
3102
 
1014
3103
 
@@ -1048,25 +3137,25 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
1048
3137
 
1049
3138
 
1050
3139
  * @example
1051
- * // Aggregate
3140
+ * // Find in range
1052
3141
  * 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;
3142
+ * ms.add(10);
3143
+ * ms.add(20);
3144
+ * ms.add(30);
3145
+ * const result = ms.rangeSearch([15, 25]);
3146
+ * console.log(result.length); // 1;
1057
3147
  */
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;
3148
+ rangeSearch<C extends (key: K) => any>(
3149
+ range: [K, K],
3150
+ callback?: C
3151
+ ): (C extends undefined ? K : ReturnType<C>)[] {
3152
+ const cb = callback ?? ((k: K) => k);
3153
+ return this.#core.rangeSearch(range, node => cb(node.key));
1064
3154
  }
1065
3155
 
1066
3156
  /**
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)
3157
+ * Prints the internal tree structure (for debugging).
3158
+ * @remarks Time O(n), Space O(n)
1070
3159
 
1071
3160
 
1072
3161
 
@@ -1106,33 +3195,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
1106
3195
 
1107
3196
 
1108
3197
 
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
3198
 
1137
3199
 
1138
3200
 
@@ -1171,31 +3233,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
1171
3233
 
1172
3234
 
1173
3235
 
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
3236
 
1200
3237
 
1201
3238
 
@@ -1225,27 +3262,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
1225
3262
 
1226
3263
 
1227
3264
 
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
-
1249
3265
 
1250
3266
 
1251
3267