max-priority-queue-typed 2.4.5 → 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.
- package/README.md +63 -0
- package/dist/cjs/index.cjs +400 -119
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +399 -118
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +400 -119
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +399 -118
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +429 -78
- package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +212 -32
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
- package/dist/types/data-structures/graph/directed-graph.d.ts +219 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +204 -59
- package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
- package/dist/types/data-structures/heap/heap.d.ts +287 -99
- package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
- package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
- package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
- package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
- package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
- package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
- package/dist/types/data-structures/queue/deque.d.ts +272 -65
- package/dist/types/data-structures/queue/queue.d.ts +211 -42
- package/dist/types/data-structures/stack/stack.d.ts +174 -32
- package/dist/types/data-structures/trie/trie.d.ts +213 -43
- package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
- package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
- package/dist/umd/max-priority-queue-typed.js +397 -116
- package/dist/umd/max-priority-queue-typed.js.map +1 -1
- package/dist/umd/max-priority-queue-typed.min.js +1 -1
- package/dist/umd/max-priority-queue-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/data-structures/base/iterable-element-base.ts +4 -5
- package/src/data-structures/binary-tree/avl-tree.ts +134 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +302 -247
- package/src/data-structures/binary-tree/binary-tree.ts +429 -79
- package/src/data-structures/binary-tree/bst.ts +335 -34
- package/src/data-structures/binary-tree/red-black-tree.ts +290 -97
- package/src/data-structures/binary-tree/segment-tree.ts +372 -248
- package/src/data-structures/binary-tree/tree-map.ts +1284 -6
- package/src/data-structures/binary-tree/tree-multi-map.ts +1094 -211
- package/src/data-structures/binary-tree/tree-multi-set.ts +858 -65
- package/src/data-structures/binary-tree/tree-set.ts +1136 -9
- package/src/data-structures/graph/directed-graph.ts +219 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +204 -59
- package/src/data-structures/hash/hash-map.ts +230 -77
- package/src/data-structures/heap/heap.ts +287 -99
- package/src/data-structures/heap/max-heap.ts +46 -0
- package/src/data-structures/heap/min-heap.ts +59 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +286 -44
- package/src/data-structures/linked-list/singly-linked-list.ts +278 -65
- package/src/data-structures/linked-list/skip-linked-list.ts +689 -90
- package/src/data-structures/matrix/matrix.ts +416 -12
- package/src/data-structures/priority-queue/max-priority-queue.ts +57 -0
- package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
- package/src/data-structures/priority-queue/priority-queue.ts +60 -0
- package/src/data-structures/queue/deque.ts +272 -65
- package/src/data-structures/queue/queue.ts +211 -42
- package/src/data-structures/stack/stack.ts +174 -32
- package/src/data-structures/trie/trie.ts +213 -43
- package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
- package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
|
@@ -17,6 +17,11 @@ import { RedBlackTree } from './red-black-tree';
|
|
|
17
17
|
*
|
|
18
18
|
* - Iteration order is ascending by key.
|
|
19
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;
|
|
20
25
|
*/
|
|
21
26
|
export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
22
27
|
readonly #core: RedBlackTree<K, undefined>;
|
|
@@ -67,22 +72,21 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
67
72
|
return (a: K, b: K): number => {
|
|
68
73
|
// numbers
|
|
69
74
|
if (typeof a === 'number' && typeof b === 'number') {
|
|
75
|
+
/* istanbul ignore next -- _validateKey prevents NaN from entering the tree */
|
|
70
76
|
if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError(ERR.invalidNaN('TreeSet'));
|
|
71
|
-
// treat -0 and 0 as equal
|
|
72
77
|
const aa = Object.is(a, -0) ? 0 : a;
|
|
73
78
|
const bb = Object.is(b, -0) ? 0 : b;
|
|
74
79
|
return aa > bb ? 1 : aa < bb ? -1 : 0;
|
|
75
80
|
}
|
|
76
81
|
|
|
77
|
-
// strings
|
|
78
82
|
if (typeof a === 'string' && typeof b === 'string') {
|
|
79
83
|
return a > b ? 1 : a < b ? -1 : 0;
|
|
80
84
|
}
|
|
81
85
|
|
|
82
|
-
// Date
|
|
83
86
|
if (a instanceof Date && b instanceof Date) {
|
|
84
87
|
const ta = a.getTime();
|
|
85
88
|
const tb = b.getTime();
|
|
89
|
+
/* istanbul ignore next -- _validateKey prevents invalid Date from entering the tree */
|
|
86
90
|
if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate('TreeSet'));
|
|
87
91
|
return ta > tb ? 1 : ta < tb ? -1 : 0;
|
|
88
92
|
}
|
|
@@ -100,6 +104,47 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
100
104
|
|
|
101
105
|
/**
|
|
102
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;
|
|
103
148
|
*/
|
|
104
149
|
isEmpty(): boolean {
|
|
105
150
|
return this.size === 0;
|
|
@@ -127,6 +172,58 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
127
172
|
/**
|
|
128
173
|
* Add a key to the set (no-op if already present).
|
|
129
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';
|
|
130
227
|
*/
|
|
131
228
|
add(key: K): this {
|
|
132
229
|
this._validateKey(key);
|
|
@@ -138,6 +235,61 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
138
235
|
/**
|
|
139
236
|
* Test whether a key exists.
|
|
140
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;
|
|
141
293
|
*/
|
|
142
294
|
has(key: K): boolean {
|
|
143
295
|
this._validateKey(key);
|
|
@@ -148,6 +300,62 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
148
300
|
* Delete a key.
|
|
149
301
|
* @returns `true` if the key existed; otherwise `false`.
|
|
150
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];
|
|
151
359
|
*/
|
|
152
360
|
delete(key: K): boolean {
|
|
153
361
|
this._validateKey(key);
|
|
@@ -157,6 +365,49 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
157
365
|
|
|
158
366
|
/**
|
|
159
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;
|
|
160
411
|
*/
|
|
161
412
|
clear(): void {
|
|
162
413
|
this.#core.clear();
|
|
@@ -164,6 +415,48 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
164
415
|
|
|
165
416
|
/**
|
|
166
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];
|
|
167
460
|
*/
|
|
168
461
|
keys(): IterableIterator<K> {
|
|
169
462
|
return this.#core.keys();
|
|
@@ -173,6 +466,48 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
173
466
|
* Iterate over values in ascending order.
|
|
174
467
|
*
|
|
175
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];
|
|
176
511
|
*/
|
|
177
512
|
values(): IterableIterator<K> {
|
|
178
513
|
return this.keys();
|
|
@@ -182,6 +517,48 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
182
517
|
* Iterate over `[value, value]` pairs (native Set convention).
|
|
183
518
|
*
|
|
184
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];
|
|
185
562
|
*/
|
|
186
563
|
*entries(): IterableIterator<[K, K]> {
|
|
187
564
|
for (const k of this.keys()) yield [k, k];
|
|
@@ -195,6 +572,50 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
195
572
|
* Visit each value in ascending order.
|
|
196
573
|
*
|
|
197
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];
|
|
198
619
|
*/
|
|
199
620
|
forEach(cb: (value: K, value2: K, set: TreeSet<K>) => void, thisArg?: any): void {
|
|
200
621
|
for (const k of this) cb.call(thisArg, k, k, this);
|
|
@@ -205,6 +626,49 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
205
626
|
*
|
|
206
627
|
* This mirrors `RedBlackTree.map`: mapping produces a new ordered container.
|
|
207
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];
|
|
208
672
|
*/
|
|
209
673
|
map<MK>(
|
|
210
674
|
callbackfn: TreeSetElementCallback<K, MK, TreeSet<K>>,
|
|
@@ -225,6 +689,49 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
225
689
|
/**
|
|
226
690
|
* Create a new TreeSet containing only values that satisfy the predicate.
|
|
227
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];
|
|
228
735
|
*/
|
|
229
736
|
filter(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): TreeSet<K> {
|
|
230
737
|
const out = new TreeSet<K>([], { comparator: this.#userComparator });
|
|
@@ -241,6 +748,49 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
241
748
|
/**
|
|
242
749
|
* Reduce values into a single accumulator.
|
|
243
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;
|
|
244
794
|
*/
|
|
245
795
|
reduce<A>(callbackfn: TreeSetReduceCallback<K, A, TreeSet<K>>, initialValue: A): A {
|
|
246
796
|
let acc = initialValue;
|
|
@@ -252,6 +802,46 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
252
802
|
/**
|
|
253
803
|
* Test whether all values satisfy a predicate.
|
|
254
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;
|
|
255
845
|
*/
|
|
256
846
|
every(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): boolean {
|
|
257
847
|
let index = 0;
|
|
@@ -267,6 +857,46 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
267
857
|
/**
|
|
268
858
|
* Test whether any value satisfies a predicate.
|
|
269
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;
|
|
270
900
|
*/
|
|
271
901
|
some(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): boolean {
|
|
272
902
|
let index = 0;
|
|
@@ -282,6 +912,47 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
282
912
|
/**
|
|
283
913
|
* Find the first value that satisfies a predicate.
|
|
284
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;
|
|
285
956
|
*/
|
|
286
957
|
find(callbackfn: TreeSetElementCallback<K, boolean, TreeSet<K>>, thisArg?: unknown): K | undefined {
|
|
287
958
|
let index = 0;
|
|
@@ -297,6 +968,48 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
297
968
|
/**
|
|
298
969
|
* Materialize the set into an array of keys.
|
|
299
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];
|
|
300
1013
|
*/
|
|
301
1014
|
toArray(): K[] {
|
|
302
1015
|
return [...this];
|
|
@@ -305,6 +1018,48 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
305
1018
|
/**
|
|
306
1019
|
* Print a human-friendly representation.
|
|
307
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();
|
|
308
1063
|
*/
|
|
309
1064
|
print(): void {
|
|
310
1065
|
// Delegate to the underlying tree's visualization.
|
|
@@ -315,6 +1070,44 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
315
1070
|
|
|
316
1071
|
/**
|
|
317
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'];
|
|
318
1111
|
*/
|
|
319
1112
|
first(): K | undefined {
|
|
320
1113
|
return this.#core.getLeftMost();
|
|
@@ -322,6 +1115,22 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
322
1115
|
|
|
323
1116
|
/**
|
|
324
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;
|
|
325
1134
|
*/
|
|
326
1135
|
last(): K | undefined {
|
|
327
1136
|
return this.#core.getRightMost();
|
|
@@ -329,6 +1138,24 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
329
1138
|
|
|
330
1139
|
/**
|
|
331
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;
|
|
332
1159
|
*/
|
|
333
1160
|
pollFirst(): K | undefined {
|
|
334
1161
|
const k = this.first();
|
|
@@ -339,6 +1166,23 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
339
1166
|
|
|
340
1167
|
/**
|
|
341
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;
|
|
342
1186
|
*/
|
|
343
1187
|
pollLast(): K | undefined {
|
|
344
1188
|
const k = this.last();
|
|
@@ -349,6 +1193,60 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
349
1193
|
|
|
350
1194
|
/**
|
|
351
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;
|
|
352
1250
|
*/
|
|
353
1251
|
ceiling(key: K): K | undefined {
|
|
354
1252
|
this._validateKey(key);
|
|
@@ -357,6 +1255,52 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
357
1255
|
|
|
358
1256
|
/**
|
|
359
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;
|
|
360
1304
|
*/
|
|
361
1305
|
floor(key: K): K | undefined {
|
|
362
1306
|
this._validateKey(key);
|
|
@@ -365,6 +1309,50 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
365
1309
|
|
|
366
1310
|
/**
|
|
367
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;
|
|
368
1356
|
*/
|
|
369
1357
|
higher(key: K): K | undefined {
|
|
370
1358
|
this._validateKey(key);
|
|
@@ -373,6 +1361,50 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
373
1361
|
|
|
374
1362
|
/**
|
|
375
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;
|
|
376
1408
|
*/
|
|
377
1409
|
lower(key: K): K | undefined {
|
|
378
1410
|
this._validateKey(key);
|
|
@@ -384,6 +1416,61 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
384
1416
|
*
|
|
385
1417
|
* @param range `[low, high]`
|
|
386
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;
|
|
387
1474
|
*/
|
|
388
1475
|
rangeSearch(range: [K, K], options: TreeSetRangeOptions = {}): K[] {
|
|
389
1476
|
const { lowInclusive = true, highInclusive = true } = options;
|
|
@@ -397,7 +1484,7 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
397
1484
|
const cmp = this.#core.comparator;
|
|
398
1485
|
|
|
399
1486
|
for (const k of keys) {
|
|
400
|
-
if (k === undefined) continue;
|
|
1487
|
+
/* istanbul ignore next -- defensive: tree keys are never undefined */ if (k === undefined) continue;
|
|
401
1488
|
if (!lowInclusive && cmp(k, low) === 0) continue;
|
|
402
1489
|
if (!highInclusive && cmp(k, high) === 0) continue;
|
|
403
1490
|
out.push(k);
|
|
@@ -409,11 +1496,51 @@ export class TreeSet<K = any, R = K> implements Iterable<K> {
|
|
|
409
1496
|
/**
|
|
410
1497
|
* Creates a shallow clone of this set.
|
|
411
1498
|
* @remarks Time O(n log n), Space O(n)
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
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;
|
|
417
1544
|
*/
|
|
418
1545
|
clone(): TreeSet<K> {
|
|
419
1546
|
return new TreeSet<K>(this, {
|