binary-tree-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 (85) hide show
  1. package/README.md +0 -84
  2. package/dist/cjs/index.cjs +965 -420
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/cjs-legacy/index.cjs +962 -417
  5. package/dist/cjs-legacy/index.cjs.map +1 -1
  6. package/dist/esm/index.mjs +965 -421
  7. package/dist/esm/index.mjs.map +1 -1
  8. package/dist/esm-legacy/index.mjs +962 -418
  9. package/dist/esm-legacy/index.mjs.map +1 -1
  10. package/dist/types/common/error.d.ts +23 -0
  11. package/dist/types/common/index.d.ts +1 -0
  12. package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
  13. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
  14. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
  15. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +439 -78
  16. package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
  17. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +217 -31
  18. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
  19. package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
  20. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
  21. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
  22. package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
  23. package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
  24. package/dist/types/data-structures/graph/directed-graph.d.ts +220 -47
  25. package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
  26. package/dist/types/data-structures/graph/undirected-graph.d.ts +218 -59
  27. package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
  28. package/dist/types/data-structures/heap/heap.d.ts +287 -99
  29. package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
  30. package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
  31. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
  32. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
  33. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
  34. package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
  35. package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
  36. package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
  37. package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
  38. package/dist/types/data-structures/queue/deque.d.ts +313 -66
  39. package/dist/types/data-structures/queue/queue.d.ts +211 -42
  40. package/dist/types/data-structures/stack/stack.d.ts +174 -32
  41. package/dist/types/data-structures/trie/trie.d.ts +213 -43
  42. package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
  43. package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
  44. package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
  45. package/dist/umd/binary-tree-typed.js +959 -414
  46. package/dist/umd/binary-tree-typed.js.map +1 -1
  47. package/dist/umd/binary-tree-typed.min.js +3 -3
  48. package/dist/umd/binary-tree-typed.min.js.map +1 -1
  49. package/package.json +2 -2
  50. package/src/common/error.ts +60 -0
  51. package/src/common/index.ts +2 -0
  52. package/src/data-structures/base/iterable-element-base.ts +2 -2
  53. package/src/data-structures/binary-tree/avl-tree.ts +134 -51
  54. package/src/data-structures/binary-tree/binary-indexed-tree.ts +303 -247
  55. package/src/data-structures/binary-tree/binary-tree.ts +542 -121
  56. package/src/data-structures/binary-tree/bst.ts +346 -37
  57. package/src/data-structures/binary-tree/red-black-tree.ts +309 -96
  58. package/src/data-structures/binary-tree/segment-tree.ts +372 -248
  59. package/src/data-structures/binary-tree/tree-map.ts +1292 -13
  60. package/src/data-structures/binary-tree/tree-multi-map.ts +1098 -215
  61. package/src/data-structures/binary-tree/tree-multi-set.ts +863 -69
  62. package/src/data-structures/binary-tree/tree-set.ts +1143 -15
  63. package/src/data-structures/graph/abstract-graph.ts +106 -1
  64. package/src/data-structures/graph/directed-graph.ts +223 -47
  65. package/src/data-structures/graph/map-graph.ts +59 -1
  66. package/src/data-structures/graph/undirected-graph.ts +299 -59
  67. package/src/data-structures/hash/hash-map.ts +243 -79
  68. package/src/data-structures/heap/heap.ts +291 -102
  69. package/src/data-structures/heap/max-heap.ts +48 -3
  70. package/src/data-structures/heap/min-heap.ts +59 -0
  71. package/src/data-structures/linked-list/doubly-linked-list.ts +286 -44
  72. package/src/data-structures/linked-list/singly-linked-list.ts +278 -65
  73. package/src/data-structures/linked-list/skip-linked-list.ts +689 -90
  74. package/src/data-structures/matrix/matrix.ts +425 -22
  75. package/src/data-structures/priority-queue/max-priority-queue.ts +59 -3
  76. package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
  77. package/src/data-structures/priority-queue/priority-queue.ts +60 -0
  78. package/src/data-structures/queue/deque.ts +343 -68
  79. package/src/data-structures/queue/queue.ts +211 -42
  80. package/src/data-structures/stack/stack.ts +174 -32
  81. package/src/data-structures/trie/trie.ts +215 -44
  82. package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
  83. package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
  84. package/src/types/data-structures/queue/deque.ts +7 -0
  85. 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,47 @@ 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
+ * @example
146
+ * // Check empty
147
+ * console.log(new TreeSet().isEmpty()); // true;
102
148
  */
103
149
  isEmpty(): boolean {
104
150
  return this.size === 0;
@@ -108,24 +154,76 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
108
154
  if (!this.#isDefaultComparator) return;
109
155
 
110
156
  if (typeof key === 'number') {
111
- if (Number.isNaN(key)) throw new TypeError('TreeSet: NaN is not a valid key');
157
+ if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN('TreeSet'));
112
158
  return;
113
159
  }
114
160
 
115
161
  if (typeof key === 'string') return;
116
162
 
117
163
  if (key instanceof Date) {
118
- if (Number.isNaN(key.getTime())) throw new TypeError('TreeSet: invalid Date key');
164
+ if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate('TreeSet'));
119
165
  return;
120
166
  }
121
167
 
122
168
  // 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');
169
+ throw new TypeError(ERR.comparatorRequired('TreeSet'));
124
170
  }
125
171
 
126
172
  /**
127
173
  * Add a key to the set (no-op if already present).
128
174
  * @remarks Expected time O(log n)
175
+
176
+
177
+
178
+
179
+
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
+ * @example
217
+ * // Unique tags with sorted order
218
+ * const tags = new TreeSet<string>(['javascript', 'typescript', 'react', 'typescript', 'node']);
219
+ *
220
+ * // Duplicates removed, sorted alphabetically
221
+ * console.log([...tags]); // ['javascript', 'node', 'react', 'typescript'];
222
+ * console.log(tags.size); // 4;
223
+ *
224
+ * tags.add('angular');
225
+ * console.log(tags.first()); // 'angular';
226
+ * console.log(tags.last()); // 'typescript';
129
227
  */
130
228
  add(key: K): this {
131
229
  this._validateKey(key);
@@ -137,6 +235,61 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
137
235
  /**
138
236
  * Test whether a key exists.
139
237
  * @remarks Expected time O(log n)
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
+
265
+
266
+
267
+
268
+
269
+
270
+
271
+
272
+
273
+
274
+
275
+
276
+
277
+
278
+
279
+
280
+
281
+
282
+
283
+
284
+
285
+
286
+
287
+ * @example
288
+ * // Checking membership in a sorted collection
289
+ * const allowed = new TreeSet<string>(['admin', 'editor', 'viewer']);
290
+ *
291
+ * console.log(allowed.has('admin')); // true;
292
+ * console.log(allowed.has('guest')); // false;
140
293
  */
141
294
  has(key: K): boolean {
142
295
  this._validateKey(key);
@@ -147,6 +300,62 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
147
300
  * Delete a key.
148
301
  * @returns `true` if the key existed; otherwise `false`.
149
302
  * @remarks Expected time O(log n)
303
+
304
+
305
+
306
+
307
+
308
+
309
+
310
+
311
+
312
+
313
+
314
+
315
+
316
+
317
+
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
+ * @example
353
+ * // Removing elements while maintaining order
354
+ * const nums = new TreeSet<number>([1, 3, 5, 7, 9]);
355
+ *
356
+ * console.log(nums.delete(5)); // true;
357
+ * console.log(nums.delete(5)); // false; // already gone
358
+ * console.log([...nums]); // [1, 3, 7, 9];
150
359
  */
151
360
  delete(key: K): boolean {
152
361
  this._validateKey(key);
@@ -156,6 +365,49 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
156
365
 
157
366
  /**
158
367
  * Remove all keys.
368
+
369
+
370
+
371
+
372
+
373
+
374
+
375
+
376
+
377
+
378
+
379
+
380
+
381
+
382
+
383
+
384
+
385
+
386
+
387
+
388
+
389
+
390
+
391
+
392
+
393
+
394
+
395
+
396
+
397
+
398
+
399
+
400
+
401
+
402
+
403
+
404
+
405
+
406
+ * @example
407
+ * // Remove all
408
+ * const ts = new TreeSet<number>([1, 2]);
409
+ * ts.clear();
410
+ * console.log(ts.isEmpty()); // true;
159
411
  */
160
412
  clear(): void {
161
413
  this.#core.clear();
@@ -163,6 +415,48 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
163
415
 
164
416
  /**
165
417
  * Iterate over keys in ascending order.
418
+
419
+
420
+
421
+
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
+
455
+
456
+ * @example
457
+ * // Get sorted keys
458
+ * const ts = new TreeSet<number>([30, 10, 20]);
459
+ * console.log([...ts.keys()]); // [10, 20, 30];
166
460
  */
167
461
  keys(): IterableIterator<K> {
168
462
  return this.#core.keys();
@@ -172,6 +466,48 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
172
466
  * Iterate over values in ascending order.
173
467
  *
174
468
  * Note: for Set-like containers, `values()` is the same as `keys()`.
469
+
470
+
471
+
472
+
473
+
474
+
475
+
476
+
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
+ * @example
508
+ * // Get values (same as keys for Set)
509
+ * const ts = new TreeSet<number>([2, 1, 3]);
510
+ * console.log([...ts.values()]); // [1, 2, 3];
175
511
  */
176
512
  values(): IterableIterator<K> {
177
513
  return this.keys();
@@ -181,6 +517,48 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
181
517
  * Iterate over `[value, value]` pairs (native Set convention).
182
518
  *
183
519
  * Note: TreeSet stores only keys internally; `[k, k]` is created on-the-fly during iteration.
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
+ * @example
559
+ * // Iterate entries
560
+ * const ts = new TreeSet<number>([3, 1, 2]);
561
+ * console.log([...ts.entries()].map(([k]) => k)); // [1, 2, 3];
184
562
  */
185
563
  *entries(): IterableIterator<[K, K]> {
186
564
  for (const k of this.keys()) yield [k, k];
@@ -194,6 +572,50 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
194
572
  * Visit each value in ascending order.
195
573
  *
196
574
  * Callback follows native Set convention: `(value, value2, set)`.
575
+
576
+
577
+
578
+
579
+
580
+
581
+
582
+
583
+
584
+
585
+
586
+
587
+
588
+
589
+
590
+
591
+
592
+
593
+
594
+
595
+
596
+
597
+
598
+
599
+
600
+
601
+
602
+
603
+
604
+
605
+
606
+
607
+
608
+
609
+
610
+
611
+
612
+
613
+ * @example
614
+ * // Execute for each
615
+ * const ts = new TreeSet<number>([3, 1, 2]);
616
+ * const keys: number[] = [];
617
+ * ts.forEach(k => keys.push(k));
618
+ * console.log(keys); // [1, 2, 3];
197
619
  */
198
620
  forEach(cb: (value: K, value2: K, set: TreeSet<K>) => void, thisArg?: any): void {
199
621
  for (const k of this) cb.call(thisArg, k, k, this);
@@ -204,6 +626,49 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
204
626
  *
205
627
  * This mirrors `RedBlackTree.map`: mapping produces a new ordered container.
206
628
  * @remarks Time O(n log n) expected, Space O(n)
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
+
666
+
667
+ * @example
668
+ * // Transform
669
+ * const ts = new TreeSet<number>([1, 2, 3]);
670
+ * const doubled = ts.map(k => k * 2);
671
+ * console.log([...doubled]); // [2, 4, 6];
207
672
  */
208
673
  map<MK>(
209
674
  callbackfn: TreeSetElementCallback<K, MK, TreeSet<K>>,
@@ -224,6 +689,49 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
224
689
  /**
225
690
  * Create a new TreeSet containing only values that satisfy the predicate.
226
691
  * @remarks Time O(n log n) expected, Space O(n)
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
+ * @example
731
+ * // Filter
732
+ * const ts = new TreeSet<number>([1, 2, 3, 4, 5]);
733
+ * const evens = ts.filter(k => k % 2 === 0);
734
+ * console.log([...evens]); // [2, 4];
227
735
  */
228
736
  filter(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): TreeSet<K> {
229
737
  const out = new TreeSet<K>([], { comparator: this.#userComparator });
@@ -240,6 +748,49 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
240
748
  /**
241
749
  * Reduce values into a single accumulator.
242
750
  * @remarks Time O(n), Space O(1)
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
+ * @example
790
+ * // Aggregate
791
+ * const ts = new TreeSet<number>([1, 2, 3]);
792
+ * const sum = ts.reduce((acc, k) => acc + k, 0);
793
+ * console.log(sum); // 6;
243
794
  */
244
795
  reduce<A>(callbackfn: TreeSetReduceCallback<K, A, TreeSet<K>>, initialValue: A): A {
245
796
  let acc = initialValue;
@@ -251,6 +802,46 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
251
802
  /**
252
803
  * Test whether all values satisfy a predicate.
253
804
  * @remarks Time O(n), Space O(1)
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
+ * @example
842
+ * // Test all
843
+ * const ts = new TreeSet<number>([2, 4, 6]);
844
+ * console.log(ts.every(k => k > 0)); // true;
254
845
  */
255
846
  every(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): boolean {
256
847
  let index = 0;
@@ -266,6 +857,46 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
266
857
  /**
267
858
  * Test whether any value satisfies a predicate.
268
859
  * @remarks Time O(n), Space O(1)
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
+ * @example
897
+ * // Test any
898
+ * const ts = new TreeSet<number>([1, 3, 5]);
899
+ * console.log(ts.some(k => k === 3)); // true;
269
900
  */
270
901
  some(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): boolean {
271
902
  let index = 0;
@@ -281,6 +912,47 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
281
912
  /**
282
913
  * Find the first value that satisfies a predicate.
283
914
  * @remarks Time O(n), Space O(1)
915
+
916
+
917
+
918
+
919
+
920
+
921
+
922
+
923
+
924
+
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
+ * @example
952
+ * // Find entry
953
+ * const ts = new TreeSet<number>([1, 2, 3]);
954
+ * const found = ts.find(k => k === 2);
955
+ * console.log(found); // 2;
284
956
  */
285
957
  find(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): K | undefined {
286
958
  let index = 0;
@@ -296,6 +968,48 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
296
968
  /**
297
969
  * Materialize the set into an array of keys.
298
970
  * @remarks Time O(n), Space O(n)
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
+ * @example
1010
+ * // Convert to array
1011
+ * const ts = new TreeSet<number>([3, 1, 2]);
1012
+ * console.log(ts.toArray()); // [1, 2, 3];
299
1013
  */
300
1014
  toArray(): K[] {
301
1015
  return [...this];
@@ -304,6 +1018,48 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
304
1018
  /**
305
1019
  * Print a human-friendly representation.
306
1020
  * @remarks Time O(n), Space O(n)
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
+ * @example
1060
+ * // Display tree
1061
+ * const ts = new TreeSet<number>([1, 2, 3]);
1062
+ * expect(() => ts.print()).not.toThrow();
307
1063
  */
308
1064
  print(): void {
309
1065
  // Delegate to the underlying tree's visualization.
@@ -314,6 +1070,44 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
314
1070
 
315
1071
  /**
316
1072
  * Smallest key in the set.
1073
+
1074
+
1075
+
1076
+
1077
+
1078
+
1079
+
1080
+
1081
+
1082
+
1083
+
1084
+ * @example
1085
+ * // Student grade ranking with custom comparator
1086
+ * interface Student {
1087
+ * name: string;
1088
+ * gpa: number;
1089
+ * }
1090
+ *
1091
+ * const ranking = new TreeSet<Student>(
1092
+ * [
1093
+ * { name: 'Alice', gpa: 3.8 },
1094
+ * { name: 'Bob', gpa: 3.5 },
1095
+ * { name: 'Charlie', gpa: 3.9 },
1096
+ * { name: 'Diana', gpa: 3.5 }
1097
+ * ],
1098
+ * { comparator: (a, b) => b.gpa - a.gpa || a.name.localeCompare(b.name) }
1099
+ * );
1100
+ *
1101
+ * // Sorted by GPA descending, then name ascending
1102
+ * const names = [...ranking].map(s => s.name);
1103
+ * console.log(names); // ['Charlie', 'Alice', 'Bob', 'Diana'];
1104
+ *
1105
+ * // Top student
1106
+ * console.log(ranking.first()?.name); // 'Charlie';
1107
+ *
1108
+ * // Filter students with GPA >= 3.8
1109
+ * const honors = ranking.filter(s => s.gpa >= 3.8);
1110
+ * console.log(honors.toArray().map(s => s.name)); // ['Charlie', 'Alice'];
317
1111
  */
318
1112
  first(): K | undefined {
319
1113
  return this.#core.getLeftMost();
@@ -321,6 +1115,22 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
321
1115
 
322
1116
  /**
323
1117
  * Largest key in the set.
1118
+
1119
+
1120
+
1121
+
1122
+
1123
+
1124
+
1125
+
1126
+
1127
+
1128
+
1129
+ * @example
1130
+ * // Get the maximum element
1131
+ * const temps = new TreeSet<number>([18, 22, 15, 30, 25]);
1132
+ * console.log(temps.last()); // 30;
1133
+ * console.log(temps.first()); // 15;
324
1134
  */
325
1135
  last(): K | undefined {
326
1136
  return this.#core.getRightMost();
@@ -328,6 +1138,24 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
328
1138
 
329
1139
  /**
330
1140
  * Remove and return the smallest key.
1141
+
1142
+
1143
+
1144
+
1145
+
1146
+
1147
+
1148
+
1149
+
1150
+
1151
+
1152
+ * @example
1153
+ * // Remove and return minimum
1154
+ * const queue = new TreeSet<number>([5, 1, 8, 3]);
1155
+ *
1156
+ * console.log(queue.pollFirst()); // 1;
1157
+ * console.log(queue.pollFirst()); // 3;
1158
+ * console.log(queue.size); // 2;
331
1159
  */
332
1160
  pollFirst(): K | undefined {
333
1161
  const k = this.first();
@@ -338,6 +1166,23 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
338
1166
 
339
1167
  /**
340
1168
  * Remove and return the largest key.
1169
+
1170
+
1171
+
1172
+
1173
+
1174
+
1175
+
1176
+
1177
+
1178
+
1179
+
1180
+ * @example
1181
+ * // Remove and return maximum
1182
+ * const stack = new TreeSet<number>([10, 20, 30]);
1183
+ *
1184
+ * console.log(stack.pollLast()); // 30;
1185
+ * console.log(stack.size); // 2;
341
1186
  */
342
1187
  pollLast(): K | undefined {
343
1188
  const k = this.last();
@@ -348,6 +1193,60 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
348
1193
 
349
1194
  /**
350
1195
  * Smallest key that is >= the given key.
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
+ * @example
1235
+ * // Finding nearest available time slot
1236
+ * // Available appointment times (minutes from midnight)
1237
+ * const slots = new TreeSet<number>([540, 600, 660, 720, 840, 900]);
1238
+ *
1239
+ * // Customer wants something around 10:30 (630 min)
1240
+ * const nearest = slots.ceiling(630);
1241
+ * console.log(nearest); // 660; // 11:00 AM
1242
+ *
1243
+ * // What's the latest slot before 2:00 PM (840)?
1244
+ * const before2pm = slots.lower(840);
1245
+ * console.log(before2pm); // 720; // 12:00 PM
1246
+ *
1247
+ * // Book the 11:00 slot
1248
+ * slots.delete(660);
1249
+ * console.log(slots.ceiling(630)); // 720;
351
1250
  */
352
1251
  ceiling(key: K): K | undefined {
353
1252
  this._validateKey(key);
@@ -356,6 +1255,52 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
356
1255
 
357
1256
  /**
358
1257
  * Largest key that is <= the given key.
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
+ * @example
1297
+ * // Largest element ≤ target
1298
+ * const breakpoints = new TreeSet<number>([320, 768, 1024, 1280, 1920]);
1299
+ *
1300
+ * // Current width is 800 → which breakpoint applies?
1301
+ * console.log(breakpoints.floor(800)); // 768;
1302
+ * console.log(breakpoints.floor(1024)); // 1024; // exact match
1303
+ * console.log(breakpoints.floor(100)); // undefined;
359
1304
  */
360
1305
  floor(key: K): K | undefined {
361
1306
  this._validateKey(key);
@@ -364,6 +1309,50 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
364
1309
 
365
1310
  /**
366
1311
  * Smallest key that is > the given key.
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
+ * @example
1351
+ * // Smallest element strictly > target
1352
+ * const levels = new TreeSet<number>([1, 5, 10, 25, 50, 100]);
1353
+ *
1354
+ * console.log(levels.higher(10)); // 25;
1355
+ * console.log(levels.higher(100)); // undefined;
367
1356
  */
368
1357
  higher(key: K): K | undefined {
369
1358
  this._validateKey(key);
@@ -372,6 +1361,50 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
372
1361
 
373
1362
  /**
374
1363
  * Largest key that is < the given key.
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
+ * @example
1403
+ * // Largest element strictly < target
1404
+ * const tiers = new TreeSet<number>([100, 200, 500, 1000]);
1405
+ *
1406
+ * console.log(tiers.lower(500)); // 200;
1407
+ * console.log(tiers.lower(100)); // undefined;
375
1408
  */
376
1409
  lower(key: K): K | undefined {
377
1410
  this._validateKey(key);
@@ -383,6 +1416,61 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
383
1416
  *
384
1417
  * @param range `[low, high]`
385
1418
  * @param options Inclusive/exclusive bounds (defaults to inclusive).
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
+ * @example
1458
+ * // IP address blocklist with range checking
1459
+ * // Simplified: use numeric IP representation
1460
+ * const blocklist = new TreeSet<number>([
1461
+ * 167772160, // 10.0.0.0
1462
+ * 167772416, // 10.0.1.0
1463
+ * 167772672, // 10.0.2.0
1464
+ * 167773184 // 10.0.4.0
1465
+ * ]);
1466
+ *
1467
+ * // Check if any blocked IP is in range 10.0.1.0 - 10.0.3.0
1468
+ * const inRange = blocklist.rangeSearch([167772416, 167772928]);
1469
+ * console.log(inRange); // [167772416, 167772672];
1470
+ *
1471
+ * // Quick membership check
1472
+ * console.log(blocklist.has(167772416)); // true;
1473
+ * console.log(blocklist.has(167772800)); // false;
386
1474
  */
387
1475
  rangeSearch(range: [K, K], options: TreeSetRangeOptions = {}): K[] {
388
1476
  const { lowInclusive = true, highInclusive = true } = options;
@@ -396,7 +1484,7 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
396
1484
  const cmp = this.#core.comparator;
397
1485
 
398
1486
  for (const k of keys) {
399
- if (k === undefined) continue;
1487
+ /* istanbul ignore next -- defensive: tree keys are never undefined */ if (k === undefined) continue;
400
1488
  if (!lowInclusive && cmp(k, low) === 0) continue;
401
1489
  if (!highInclusive && cmp(k, high) === 0) continue;
402
1490
  out.push(k);
@@ -408,11 +1496,51 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
408
1496
  /**
409
1497
  * Creates a shallow clone of this set.
410
1498
  * @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)
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
+ * @example
1539
+ * // Deep clone
1540
+ * const ts = new TreeSet<number>([1, 2, 3]);
1541
+ * const copy = ts.clone();
1542
+ * copy.delete(1);
1543
+ * console.log(ts.has(1)); // true;
416
1544
  */
417
1545
  clone(): TreeSet<K> {
418
1546
  return new TreeSet<K>(this, {