data-structure-typed 2.4.4 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/CHANGELOG.md +22 -1
  2. package/README.md +34 -1
  3. package/dist/cjs/index.cjs +10639 -2151
  4. package/dist/cjs-legacy/index.cjs +10694 -2195
  5. package/dist/esm/index.mjs +10639 -2150
  6. package/dist/esm-legacy/index.mjs +10694 -2194
  7. package/dist/types/common/error.d.ts +23 -0
  8. package/dist/types/common/index.d.ts +1 -0
  9. package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
  10. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
  11. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
  12. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +439 -78
  13. package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
  14. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +217 -31
  15. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
  16. package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
  17. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
  18. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
  19. package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
  20. package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
  21. package/dist/types/data-structures/graph/directed-graph.d.ts +220 -47
  22. package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
  23. package/dist/types/data-structures/graph/undirected-graph.d.ts +218 -59
  24. package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
  25. package/dist/types/data-structures/heap/heap.d.ts +287 -99
  26. package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
  27. package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
  28. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
  29. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
  30. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
  31. package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
  32. package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
  33. package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
  34. package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
  35. package/dist/types/data-structures/queue/deque.d.ts +313 -66
  36. package/dist/types/data-structures/queue/queue.d.ts +211 -42
  37. package/dist/types/data-structures/stack/stack.d.ts +174 -32
  38. package/dist/types/data-structures/trie/trie.d.ts +213 -43
  39. package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
  40. package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
  41. package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
  42. package/dist/umd/data-structure-typed.js +10725 -2221
  43. package/dist/umd/data-structure-typed.min.js +4 -2
  44. package/package.json +5 -4
  45. package/src/common/error.ts +60 -0
  46. package/src/common/index.ts +2 -0
  47. package/src/data-structures/base/iterable-element-base.ts +2 -2
  48. package/src/data-structures/binary-tree/avl-tree.ts +146 -51
  49. package/src/data-structures/binary-tree/binary-indexed-tree.ts +317 -247
  50. package/src/data-structures/binary-tree/binary-tree.ts +567 -121
  51. package/src/data-structures/binary-tree/bst.ts +370 -37
  52. package/src/data-structures/binary-tree/red-black-tree.ts +328 -96
  53. package/src/data-structures/binary-tree/segment-tree.ts +378 -248
  54. package/src/data-structures/binary-tree/tree-map.ts +1411 -13
  55. package/src/data-structures/binary-tree/tree-multi-map.ts +1218 -215
  56. package/src/data-structures/binary-tree/tree-multi-set.ts +959 -69
  57. package/src/data-structures/binary-tree/tree-set.ts +1257 -15
  58. package/src/data-structures/graph/abstract-graph.ts +106 -1
  59. package/src/data-structures/graph/directed-graph.ts +233 -47
  60. package/src/data-structures/graph/map-graph.ts +59 -1
  61. package/src/data-structures/graph/undirected-graph.ts +308 -59
  62. package/src/data-structures/hash/hash-map.ts +254 -79
  63. package/src/data-structures/heap/heap.ts +305 -102
  64. package/src/data-structures/heap/max-heap.ts +48 -3
  65. package/src/data-structures/heap/min-heap.ts +59 -0
  66. package/src/data-structures/linked-list/doubly-linked-list.ts +303 -44
  67. package/src/data-structures/linked-list/singly-linked-list.ts +293 -65
  68. package/src/data-structures/linked-list/skip-linked-list.ts +707 -90
  69. package/src/data-structures/matrix/matrix.ts +433 -22
  70. package/src/data-structures/priority-queue/max-priority-queue.ts +59 -3
  71. package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
  72. package/src/data-structures/priority-queue/priority-queue.ts +60 -0
  73. package/src/data-structures/queue/deque.ts +358 -68
  74. package/src/data-structures/queue/queue.ts +223 -42
  75. package/src/data-structures/stack/stack.ts +184 -32
  76. package/src/data-structures/trie/trie.ts +227 -44
  77. package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
  78. package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
  79. package/src/types/data-structures/queue/deque.ts +7 -0
  80. package/src/utils/utils.ts +4 -2
@@ -9,6 +9,7 @@
9
9
 
10
10
  import type { Comparator } from '../../types';
11
11
  import type { TreeSetElementCallback, TreeSetOptions, TreeSetRangeOptions, TreeSetReduceCallback } from '../../types';
12
+ import { ERR } from '../../common';
12
13
  import { RedBlackTree } from './red-black-tree';
13
14
 
14
15
  /**
@@ -16,6 +17,11 @@ import { RedBlackTree } from './red-black-tree';
16
17
  *
17
18
  * - Iteration order is ascending by key.
18
19
  * - No node exposure: all APIs use keys only.
20
+ * @example
21
+ * // Set multiple key-value pairs
22
+ * const ts = new TreeSet<number, string>();
23
+ * ts.setMany([[1, 'a'], [2, 'b'], [3, 'c']]);
24
+ * console.log(ts.size); // 3;
19
25
  */
20
26
  export class TreeSet<K = any, R = K> implements Iterable<K> {
21
27
  readonly #core: RedBlackTree<K, undefined>;
@@ -66,27 +72,26 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
66
72
  return (a: K, b: K): number => {
67
73
  // numbers
68
74
  if (typeof a === 'number' && typeof b === 'number') {
69
- if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError('TreeSet: NaN is not a valid key');
70
- // treat -0 and 0 as equal
75
+ /* istanbul ignore next -- _validateKey prevents NaN from entering the tree */
76
+ if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError(ERR.invalidNaN('TreeSet'));
71
77
  const aa = Object.is(a, -0) ? 0 : a;
72
78
  const bb = Object.is(b, -0) ? 0 : b;
73
79
  return aa > bb ? 1 : aa < bb ? -1 : 0;
74
80
  }
75
81
 
76
- // strings
77
82
  if (typeof a === 'string' && typeof b === 'string') {
78
83
  return a > b ? 1 : a < b ? -1 : 0;
79
84
  }
80
85
 
81
- // Date
82
86
  if (a instanceof Date && b instanceof Date) {
83
87
  const ta = a.getTime();
84
88
  const tb = b.getTime();
85
- if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError('TreeSet: invalid Date key');
89
+ /* istanbul ignore next -- _validateKey prevents invalid Date from entering the tree */
90
+ if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate('TreeSet'));
86
91
  return ta > tb ? 1 : ta < tb ? -1 : 0;
87
92
  }
88
93
 
89
- throw new TypeError('TreeSet: comparator is required for non-number/non-string/non-Date keys');
94
+ throw new TypeError(ERR.comparatorRequired('TreeSet'));
90
95
  };
91
96
  }
92
97
 
@@ -99,6 +104,52 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
99
104
 
100
105
  /**
101
106
  * Whether the set is empty.
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+
124
+
125
+
126
+
127
+
128
+
129
+
130
+
131
+
132
+
133
+
134
+
135
+
136
+
137
+
138
+
139
+
140
+
141
+
142
+
143
+
144
+
145
+
146
+
147
+
148
+
149
+
150
+ * @example
151
+ * // Check empty
152
+ * console.log(new TreeSet().isEmpty()); // true;
102
153
  */
103
154
  isEmpty(): boolean {
104
155
  return this.size === 0;
@@ -108,24 +159,81 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
108
159
  if (!this.#isDefaultComparator) return;
109
160
 
110
161
  if (typeof key === 'number') {
111
- if (Number.isNaN(key)) throw new TypeError('TreeSet: NaN is not a valid key');
162
+ if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN('TreeSet'));
112
163
  return;
113
164
  }
114
165
 
115
166
  if (typeof key === 'string') return;
116
167
 
117
168
  if (key instanceof Date) {
118
- if (Number.isNaN(key.getTime())) throw new TypeError('TreeSet: invalid Date key');
169
+ if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate('TreeSet'));
119
170
  return;
120
171
  }
121
172
 
122
173
  // Other key types should have provided a comparator, so reaching here means misuse.
123
- throw new TypeError('TreeSet: comparator is required for non-number/non-string/non-Date keys');
174
+ throw new TypeError(ERR.comparatorRequired('TreeSet'));
124
175
  }
125
176
 
126
177
  /**
127
178
  * Add a key to the set (no-op if already present).
128
179
  * @remarks Expected time O(log n)
180
+
181
+
182
+
183
+
184
+
185
+
186
+
187
+
188
+
189
+
190
+
191
+
192
+
193
+
194
+
195
+
196
+
197
+
198
+
199
+
200
+
201
+
202
+
203
+
204
+
205
+
206
+
207
+
208
+
209
+
210
+
211
+
212
+
213
+
214
+
215
+
216
+
217
+
218
+
219
+
220
+
221
+
222
+
223
+
224
+
225
+
226
+ * @example
227
+ * // Unique tags with sorted order
228
+ * const tags = new TreeSet<string>(['javascript', 'typescript', 'react', 'typescript', 'node']);
229
+ *
230
+ * // Duplicates removed, sorted alphabetically
231
+ * console.log([...tags]); // ['javascript', 'node', 'react', 'typescript'];
232
+ * console.log(tags.size); // 4;
233
+ *
234
+ * tags.add('angular');
235
+ * console.log(tags.first()); // 'angular';
236
+ * console.log(tags.last()); // 'typescript';
129
237
  */
130
238
  add(key: K): this {
131
239
  this._validateKey(key);
@@ -137,6 +245,66 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
137
245
  /**
138
246
  * Test whether a key exists.
139
247
  * @remarks Expected time O(log n)
248
+
249
+
250
+
251
+
252
+
253
+
254
+
255
+
256
+
257
+
258
+
259
+
260
+
261
+
262
+
263
+
264
+
265
+
266
+
267
+
268
+
269
+
270
+
271
+
272
+
273
+
274
+
275
+
276
+
277
+
278
+
279
+
280
+
281
+
282
+
283
+
284
+
285
+
286
+
287
+
288
+
289
+
290
+
291
+
292
+
293
+
294
+
295
+
296
+
297
+
298
+
299
+
300
+
301
+
302
+ * @example
303
+ * // Checking membership in a sorted collection
304
+ * const allowed = new TreeSet<string>(['admin', 'editor', 'viewer']);
305
+ *
306
+ * console.log(allowed.has('admin')); // true;
307
+ * console.log(allowed.has('guest')); // false;
140
308
  */
141
309
  has(key: K): boolean {
142
310
  this._validateKey(key);
@@ -147,6 +315,67 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
147
315
  * Delete a key.
148
316
  * @returns `true` if the key existed; otherwise `false`.
149
317
  * @remarks Expected time O(log n)
318
+
319
+
320
+
321
+
322
+
323
+
324
+
325
+
326
+
327
+
328
+
329
+
330
+
331
+
332
+
333
+
334
+
335
+
336
+
337
+
338
+
339
+
340
+
341
+
342
+
343
+
344
+
345
+
346
+
347
+
348
+
349
+
350
+
351
+
352
+
353
+
354
+
355
+
356
+
357
+
358
+
359
+
360
+
361
+
362
+
363
+
364
+
365
+
366
+
367
+
368
+
369
+
370
+
371
+
372
+ * @example
373
+ * // Removing elements while maintaining order
374
+ * const nums = new TreeSet<number>([1, 3, 5, 7, 9]);
375
+ *
376
+ * console.log(nums.delete(5)); // true;
377
+ * console.log(nums.delete(5)); // false; // already gone
378
+ * console.log([...nums]); // [1, 3, 7, 9];
150
379
  */
151
380
  delete(key: K): boolean {
152
381
  this._validateKey(key);
@@ -156,6 +385,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
156
385
 
157
386
  /**
158
387
  * Remove all keys.
388
+
389
+
390
+
391
+
392
+
393
+
394
+
395
+
396
+
397
+
398
+
399
+
400
+
401
+
402
+
403
+
404
+
405
+
406
+
407
+
408
+
409
+
410
+
411
+
412
+
413
+
414
+
415
+
416
+
417
+
418
+
419
+
420
+
421
+
422
+
423
+
424
+
425
+
426
+
427
+
428
+
429
+
430
+
431
+ * @example
432
+ * // Remove all
433
+ * const ts = new TreeSet<number>([1, 2]);
434
+ * ts.clear();
435
+ * console.log(ts.isEmpty()); // true;
159
436
  */
160
437
  clear(): void {
161
438
  this.#core.clear();
@@ -163,6 +440,53 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
163
440
 
164
441
  /**
165
442
  * Iterate over keys in ascending order.
443
+
444
+
445
+
446
+
447
+
448
+
449
+
450
+
451
+
452
+
453
+
454
+
455
+
456
+
457
+
458
+
459
+
460
+
461
+
462
+
463
+
464
+
465
+
466
+
467
+
468
+
469
+
470
+
471
+
472
+
473
+
474
+
475
+
476
+
477
+
478
+
479
+
480
+
481
+
482
+
483
+
484
+
485
+
486
+ * @example
487
+ * // Get sorted keys
488
+ * const ts = new TreeSet<number>([30, 10, 20]);
489
+ * console.log([...ts.keys()]); // [10, 20, 30];
166
490
  */
167
491
  keys(): IterableIterator<K> {
168
492
  return this.#core.keys();
@@ -172,6 +496,53 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
172
496
  * Iterate over values in ascending order.
173
497
  *
174
498
  * Note: for Set-like containers, `values()` is the same as `keys()`.
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
+ * @example
543
+ * // Get values (same as keys for Set)
544
+ * const ts = new TreeSet<number>([2, 1, 3]);
545
+ * console.log([...ts.values()]); // [1, 2, 3];
175
546
  */
176
547
  values(): IterableIterator<K> {
177
548
  return this.keys();
@@ -181,6 +552,53 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
181
552
  * Iterate over `[value, value]` pairs (native Set convention).
182
553
  *
183
554
  * Note: TreeSet stores only keys internally; `[k, k]` is created on-the-fly during iteration.
555
+
556
+
557
+
558
+
559
+
560
+
561
+
562
+
563
+
564
+
565
+
566
+
567
+
568
+
569
+
570
+
571
+
572
+
573
+
574
+
575
+
576
+
577
+
578
+
579
+
580
+
581
+
582
+
583
+
584
+
585
+
586
+
587
+
588
+
589
+
590
+
591
+
592
+
593
+
594
+
595
+
596
+
597
+
598
+ * @example
599
+ * // Iterate entries
600
+ * const ts = new TreeSet<number>([3, 1, 2]);
601
+ * console.log([...ts.entries()].map(([k]) => k)); // [1, 2, 3];
184
602
  */
185
603
  *entries(): IterableIterator<[K, K]> {
186
604
  for (const k of this.keys()) yield [k, k];
@@ -194,6 +612,55 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
194
612
  * Visit each value in ascending order.
195
613
  *
196
614
  * Callback follows native Set convention: `(value, value2, set)`.
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
+ * @example
659
+ * // Execute for each
660
+ * const ts = new TreeSet<number>([3, 1, 2]);
661
+ * const keys: number[] = [];
662
+ * ts.forEach(k => keys.push(k));
663
+ * console.log(keys); // [1, 2, 3];
197
664
  */
198
665
  forEach(cb: (value: K, value2: K, set: TreeSet<K>) => void, thisArg?: any): void {
199
666
  for (const k of this) cb.call(thisArg, k, k, this);
@@ -204,6 +671,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
204
671
  *
205
672
  * This mirrors `RedBlackTree.map`: mapping produces a new ordered container.
206
673
  * @remarks Time O(n log n) expected, Space O(n)
674
+
675
+
676
+
677
+
678
+
679
+
680
+
681
+
682
+
683
+
684
+
685
+
686
+
687
+
688
+
689
+
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
+
717
+ * @example
718
+ * // Transform
719
+ * const ts = new TreeSet<number>([1, 2, 3]);
720
+ * const doubled = ts.map(k => k * 2);
721
+ * console.log([...doubled]); // [2, 4, 6];
207
722
  */
208
723
  map<MK>(
209
724
  callbackfn: TreeSetElementCallback<K, MK, TreeSet<K>>,
@@ -224,6 +739,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
224
739
  /**
225
740
  * Create a new TreeSet containing only values that satisfy the predicate.
226
741
  * @remarks Time O(n log n) expected, Space O(n)
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
+ * @example
786
+ * // Filter
787
+ * const ts = new TreeSet<number>([1, 2, 3, 4, 5]);
788
+ * const evens = ts.filter(k => k % 2 === 0);
789
+ * console.log([...evens]); // [2, 4];
227
790
  */
228
791
  filter(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): TreeSet<K> {
229
792
  const out = new TreeSet<K>([], { comparator: this.#userComparator });
@@ -240,6 +803,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
240
803
  /**
241
804
  * Reduce values into a single accumulator.
242
805
  * @remarks Time O(n), Space O(1)
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
+ * @example
850
+ * // Aggregate
851
+ * const ts = new TreeSet<number>([1, 2, 3]);
852
+ * const sum = ts.reduce((acc, k) => acc + k, 0);
853
+ * console.log(sum); // 6;
243
854
  */
244
855
  reduce<A>(callbackfn: TreeSetReduceCallback<K, A, TreeSet<K>>, initialValue: A): A {
245
856
  let acc = initialValue;
@@ -251,6 +862,51 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
251
862
  /**
252
863
  * Test whether all values satisfy a predicate.
253
864
  * @remarks Time O(n), Space O(1)
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
+
905
+
906
+ * @example
907
+ * // Test all
908
+ * const ts = new TreeSet<number>([2, 4, 6]);
909
+ * console.log(ts.every(k => k > 0)); // true;
254
910
  */
255
911
  every(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): boolean {
256
912
  let index = 0;
@@ -266,6 +922,51 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
266
922
  /**
267
923
  * Test whether any value satisfies a predicate.
268
924
  * @remarks Time O(n), Space O(1)
925
+
926
+
927
+
928
+
929
+
930
+
931
+
932
+
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
+
960
+
961
+
962
+
963
+
964
+
965
+
966
+ * @example
967
+ * // Test any
968
+ * const ts = new TreeSet<number>([1, 3, 5]);
969
+ * console.log(ts.some(k => k === 3)); // true;
269
970
  */
270
971
  some(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): boolean {
271
972
  let index = 0;
@@ -281,6 +982,52 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
281
982
  /**
282
983
  * Find the first value that satisfies a predicate.
283
984
  * @remarks Time O(n), Space O(1)
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
+ * @example
1027
+ * // Find entry
1028
+ * const ts = new TreeSet<number>([1, 2, 3]);
1029
+ * const found = ts.find(k => k === 2);
1030
+ * console.log(found); // 2;
284
1031
  */
285
1032
  find(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): K | undefined {
286
1033
  let index = 0;
@@ -296,6 +1043,53 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
296
1043
  /**
297
1044
  * Materialize the set into an array of keys.
298
1045
  * @remarks Time O(n), Space O(n)
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
+ * @example
1090
+ * // Convert to array
1091
+ * const ts = new TreeSet<number>([3, 1, 2]);
1092
+ * console.log(ts.toArray()); // [1, 2, 3];
299
1093
  */
300
1094
  toArray(): K[] {
301
1095
  return [...this];
@@ -304,6 +1098,53 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
304
1098
  /**
305
1099
  * Print a human-friendly representation.
306
1100
  * @remarks Time O(n), Space O(n)
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
+ * @example
1145
+ * // Display tree
1146
+ * const ts = new TreeSet<number>([1, 2, 3]);
1147
+ * expect(() => ts.print()).not.toThrow();
307
1148
  */
308
1149
  print(): void {
309
1150
  // Delegate to the underlying tree's visualization.
@@ -314,6 +1155,45 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
314
1155
 
315
1156
  /**
316
1157
  * Smallest key in the set.
1158
+
1159
+
1160
+
1161
+
1162
+
1163
+
1164
+
1165
+
1166
+
1167
+
1168
+
1169
+
1170
+ * @example
1171
+ * // Student grade ranking with custom comparator
1172
+ * interface Student {
1173
+ * name: string;
1174
+ * gpa: number;
1175
+ * }
1176
+ *
1177
+ * const ranking = new TreeSet<Student>(
1178
+ * [
1179
+ * { name: 'Alice', gpa: 3.8 },
1180
+ * { name: 'Bob', gpa: 3.5 },
1181
+ * { name: 'Charlie', gpa: 3.9 },
1182
+ * { name: 'Diana', gpa: 3.5 }
1183
+ * ],
1184
+ * { comparator: (a, b) => b.gpa - a.gpa || a.name.localeCompare(b.name) }
1185
+ * );
1186
+ *
1187
+ * // Sorted by GPA descending, then name ascending
1188
+ * const names = [...ranking].map(s => s.name);
1189
+ * console.log(names); // ['Charlie', 'Alice', 'Bob', 'Diana'];
1190
+ *
1191
+ * // Top student
1192
+ * console.log(ranking.first()?.name); // 'Charlie';
1193
+ *
1194
+ * // Filter students with GPA >= 3.8
1195
+ * const honors = ranking.filter(s => s.gpa >= 3.8);
1196
+ * console.log(honors.toArray().map(s => s.name)); // ['Charlie', 'Alice'];
317
1197
  */
318
1198
  first(): K | undefined {
319
1199
  return this.#core.getLeftMost();
@@ -321,6 +1201,23 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
321
1201
 
322
1202
  /**
323
1203
  * Largest key in the set.
1204
+
1205
+
1206
+
1207
+
1208
+
1209
+
1210
+
1211
+
1212
+
1213
+
1214
+
1215
+
1216
+ * @example
1217
+ * // Get the maximum element
1218
+ * const temps = new TreeSet<number>([18, 22, 15, 30, 25]);
1219
+ * console.log(temps.last()); // 30;
1220
+ * console.log(temps.first()); // 15;
324
1221
  */
325
1222
  last(): K | undefined {
326
1223
  return this.#core.getRightMost();
@@ -328,6 +1225,25 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
328
1225
 
329
1226
  /**
330
1227
  * Remove and return the smallest key.
1228
+
1229
+
1230
+
1231
+
1232
+
1233
+
1234
+
1235
+
1236
+
1237
+
1238
+
1239
+
1240
+ * @example
1241
+ * // Remove and return minimum
1242
+ * const queue = new TreeSet<number>([5, 1, 8, 3]);
1243
+ *
1244
+ * console.log(queue.pollFirst()); // 1;
1245
+ * console.log(queue.pollFirst()); // 3;
1246
+ * console.log(queue.size); // 2;
331
1247
  */
332
1248
  pollFirst(): K | undefined {
333
1249
  const k = this.first();
@@ -338,6 +1254,24 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
338
1254
 
339
1255
  /**
340
1256
  * Remove and return the largest key.
1257
+
1258
+
1259
+
1260
+
1261
+
1262
+
1263
+
1264
+
1265
+
1266
+
1267
+
1268
+
1269
+ * @example
1270
+ * // Remove and return maximum
1271
+ * const stack = new TreeSet<number>([10, 20, 30]);
1272
+ *
1273
+ * console.log(stack.pollLast()); // 30;
1274
+ * console.log(stack.size); // 2;
341
1275
  */
342
1276
  pollLast(): K | undefined {
343
1277
  const k = this.last();
@@ -348,6 +1282,64 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
348
1282
 
349
1283
  /**
350
1284
  * Smallest key that is >= the given key.
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
+ * @example
1328
+ * // Finding nearest available time slot
1329
+ * // Available appointment times (minutes from midnight)
1330
+ * const slots = new TreeSet<number>([540, 600, 660, 720, 840, 900]);
1331
+ *
1332
+ * // Customer wants something around 10:30 (630 min)
1333
+ * const nearest = slots.ceiling(630);
1334
+ * console.log(nearest); // 660; // 11:00 AM
1335
+ *
1336
+ * // What's the latest slot before 2:00 PM (840)?
1337
+ * const before2pm = slots.lower(840);
1338
+ * console.log(before2pm); // 720; // 12:00 PM
1339
+ *
1340
+ * // Book the 11:00 slot
1341
+ * slots.delete(660);
1342
+ * console.log(slots.ceiling(630)); // 720;
351
1343
  */
352
1344
  ceiling(key: K): K | undefined {
353
1345
  this._validateKey(key);
@@ -356,6 +1348,56 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
356
1348
 
357
1349
  /**
358
1350
  * Largest key that is <= the given key.
1351
+
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
+ * @example
1394
+ * // Largest element ≤ target
1395
+ * const breakpoints = new TreeSet<number>([320, 768, 1024, 1280, 1920]);
1396
+ *
1397
+ * // Current width is 800 → which breakpoint applies?
1398
+ * console.log(breakpoints.floor(800)); // 768;
1399
+ * console.log(breakpoints.floor(1024)); // 1024; // exact match
1400
+ * console.log(breakpoints.floor(100)); // undefined;
359
1401
  */
360
1402
  floor(key: K): K | undefined {
361
1403
  this._validateKey(key);
@@ -364,6 +1406,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
364
1406
 
365
1407
  /**
366
1408
  * Smallest key that is > the given key.
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
+ * @example
1452
+ * // Smallest element strictly > target
1453
+ * const levels = new TreeSet<number>([1, 5, 10, 25, 50, 100]);
1454
+ *
1455
+ * console.log(levels.higher(10)); // 25;
1456
+ * console.log(levels.higher(100)); // undefined;
367
1457
  */
368
1458
  higher(key: K): K | undefined {
369
1459
  this._validateKey(key);
@@ -372,6 +1462,54 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
372
1462
 
373
1463
  /**
374
1464
  * Largest key that is < the given key.
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
+ * @example
1508
+ * // Largest element strictly < target
1509
+ * const tiers = new TreeSet<number>([100, 200, 500, 1000]);
1510
+ *
1511
+ * console.log(tiers.lower(500)); // 200;
1512
+ * console.log(tiers.lower(100)); // undefined;
375
1513
  */
376
1514
  lower(key: K): K | undefined {
377
1515
  this._validateKey(key);
@@ -383,6 +1521,65 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
383
1521
  *
384
1522
  * @param range `[low, high]`
385
1523
  * @param options Inclusive/exclusive bounds (defaults to inclusive).
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
+ * @example
1567
+ * // IP address blocklist with range checking
1568
+ * // Simplified: use numeric IP representation
1569
+ * const blocklist = new TreeSet<number>([
1570
+ * 167772160, // 10.0.0.0
1571
+ * 167772416, // 10.0.1.0
1572
+ * 167772672, // 10.0.2.0
1573
+ * 167773184 // 10.0.4.0
1574
+ * ]);
1575
+ *
1576
+ * // Check if any blocked IP is in range 10.0.1.0 - 10.0.3.0
1577
+ * const inRange = blocklist.rangeSearch([167772416, 167772928]);
1578
+ * console.log(inRange); // [167772416, 167772672];
1579
+ *
1580
+ * // Quick membership check
1581
+ * console.log(blocklist.has(167772416)); // true;
1582
+ * console.log(blocklist.has(167772800)); // false;
386
1583
  */
387
1584
  rangeSearch(range: [K, K], options: TreeSetRangeOptions = {}): K[] {
388
1585
  const { lowInclusive = true, highInclusive = true } = options;
@@ -396,7 +1593,7 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
396
1593
  const cmp = this.#core.comparator;
397
1594
 
398
1595
  for (const k of keys) {
399
- if (k === undefined) continue;
1596
+ /* istanbul ignore next -- defensive: tree keys are never undefined */ if (k === undefined) continue;
400
1597
  if (!lowInclusive && cmp(k, low) === 0) continue;
401
1598
  if (!highInclusive && cmp(k, high) === 0) continue;
402
1599
  out.push(k);
@@ -408,11 +1605,56 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
408
1605
  /**
409
1606
  * Creates a shallow clone of this set.
410
1607
  * @remarks Time O(n log n), Space O(n)
411
- * @example
412
- * const original = new TreeSet([1, 2, 3]);
413
- * const copy = original.clone();
414
- * copy.add(4);
415
- * original.has(4); // false (original unchanged)
1608
+
1609
+
1610
+
1611
+
1612
+
1613
+
1614
+
1615
+
1616
+
1617
+
1618
+
1619
+
1620
+
1621
+
1622
+
1623
+
1624
+
1625
+
1626
+
1627
+
1628
+
1629
+
1630
+
1631
+
1632
+
1633
+
1634
+
1635
+
1636
+
1637
+
1638
+
1639
+
1640
+
1641
+
1642
+
1643
+
1644
+
1645
+
1646
+
1647
+
1648
+
1649
+
1650
+
1651
+
1652
+ * @example
1653
+ * // Deep clone
1654
+ * const ts = new TreeSet<number>([1, 2, 3]);
1655
+ * const copy = ts.clone();
1656
+ * copy.delete(1);
1657
+ * console.log(ts.has(1)); // true;
416
1658
  */
417
1659
  clone(): TreeSet<K> {
418
1660
  return new TreeSet<K>(this, {