data-structure-typed 2.6.0 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/.github/workflows/ci.yml +7 -2
  2. package/.github/workflows/release-package.yml +9 -2
  3. package/docs-site-docusaurus/docs/api/classes/AVLTree.md +108 -108
  4. package/docs-site-docusaurus/docs/api/classes/BST.md +101 -101
  5. package/docs-site-docusaurus/docs/api/classes/BinaryIndexedTree.md +13 -13
  6. package/docs-site-docusaurus/docs/api/classes/BinaryTree.md +66 -66
  7. package/docs-site-docusaurus/docs/api/classes/Deque.md +235 -51
  8. package/docs-site-docusaurus/docs/api/classes/DirectedGraph.md +21 -21
  9. package/docs-site-docusaurus/docs/api/classes/DoublyLinkedList.md +231 -67
  10. package/docs-site-docusaurus/docs/api/classes/FibonacciHeap.md +9 -9
  11. package/docs-site-docusaurus/docs/api/classes/FibonacciHeapNode.md +1 -1
  12. package/docs-site-docusaurus/docs/api/classes/HashMap.md +14 -14
  13. package/docs-site-docusaurus/docs/api/classes/Heap.md +117 -34
  14. package/docs-site-docusaurus/docs/api/classes/IterableElementBase.md +83 -13
  15. package/docs-site-docusaurus/docs/api/classes/LinearBase.md +124 -20
  16. package/docs-site-docusaurus/docs/api/classes/LinearLinkedBase.md +140 -32
  17. package/docs-site-docusaurus/docs/api/classes/LinkedHashMap.md +23 -23
  18. package/docs-site-docusaurus/docs/api/classes/LinkedListQueue.md +159 -51
  19. package/docs-site-docusaurus/docs/api/classes/MapGraph.md +20 -20
  20. package/docs-site-docusaurus/docs/api/classes/Matrix.md +23 -23
  21. package/docs-site-docusaurus/docs/api/classes/MaxHeap.md +117 -34
  22. package/docs-site-docusaurus/docs/api/classes/MaxPriorityQueue.md +117 -34
  23. package/docs-site-docusaurus/docs/api/classes/MinHeap.md +117 -34
  24. package/docs-site-docusaurus/docs/api/classes/MinPriorityQueue.md +117 -34
  25. package/docs-site-docusaurus/docs/api/classes/PriorityQueue.md +117 -34
  26. package/docs-site-docusaurus/docs/api/classes/Queue.md +142 -34
  27. package/docs-site-docusaurus/docs/api/classes/RedBlackTree.md +117 -117
  28. package/docs-site-docusaurus/docs/api/classes/SegmentTree.md +8 -8
  29. package/docs-site-docusaurus/docs/api/classes/SinglyLinkedList.md +158 -50
  30. package/docs-site-docusaurus/docs/api/classes/SkipList.md +21 -21
  31. package/docs-site-docusaurus/docs/api/classes/Stack.md +108 -26
  32. package/docs-site-docusaurus/docs/api/classes/TreeMap.md +33 -33
  33. package/docs-site-docusaurus/docs/api/classes/TreeMultiMap.md +75 -39
  34. package/docs-site-docusaurus/docs/api/classes/TreeSet.md +301 -39
  35. package/docs-site-docusaurus/docs/api/classes/Trie.md +110 -28
  36. package/docs-site-docusaurus/docs/api/classes/UndirectedGraph.md +20 -20
  37. package/package.json +45 -46
  38. package/src/common/error.ts +15 -32
  39. package/src/common/index.ts +0 -3
  40. package/src/data-structures/base/iterable-element-base.ts +0 -3
  41. package/src/data-structures/base/linear-base.ts +2 -36
  42. package/src/data-structures/binary-tree/avl-tree.ts +31 -529
  43. package/src/data-structures/binary-tree/binary-indexed-tree.ts +47 -572
  44. package/src/data-structures/binary-tree/binary-tree.ts +326 -1311
  45. package/src/data-structures/binary-tree/bst.ts +158 -1082
  46. package/src/data-structures/binary-tree/red-black-tree.ts +451 -1290
  47. package/src/data-structures/binary-tree/segment-tree.ts +73 -351
  48. package/src/data-structures/binary-tree/tree-map.ts +462 -5124
  49. package/src/data-structures/binary-tree/tree-multi-map.ts +302 -4914
  50. package/src/data-structures/binary-tree/tree-multi-set.ts +284 -3972
  51. package/src/data-structures/binary-tree/tree-set.ts +338 -4836
  52. package/src/data-structures/graph/abstract-graph.ts +98 -167
  53. package/src/data-structures/graph/directed-graph.ts +137 -562
  54. package/src/data-structures/graph/map-graph.ts +0 -3
  55. package/src/data-structures/graph/undirected-graph.ts +132 -511
  56. package/src/data-structures/hash/hash-map.ts +154 -582
  57. package/src/data-structures/heap/heap.ts +200 -795
  58. package/src/data-structures/linked-list/doubly-linked-list.ts +121 -865
  59. package/src/data-structures/linked-list/singly-linked-list.ts +122 -794
  60. package/src/data-structures/linked-list/skip-linked-list.ts +211 -918
  61. package/src/data-structures/matrix/matrix.ts +179 -518
  62. package/src/data-structures/matrix/navigator.ts +0 -1
  63. package/src/data-structures/priority-queue/max-priority-queue.ts +1 -6
  64. package/src/data-structures/priority-queue/min-priority-queue.ts +6 -11
  65. package/src/data-structures/priority-queue/priority-queue.ts +1 -2
  66. package/src/data-structures/queue/deque.ts +214 -882
  67. package/src/data-structures/queue/queue.ts +102 -625
  68. package/src/data-structures/stack/stack.ts +76 -505
  69. package/src/data-structures/trie/trie.ts +98 -628
  70. package/src/types/common.ts +0 -10
  71. package/src/types/data-structures/binary-tree/bst.ts +0 -7
  72. package/src/types/data-structures/binary-tree/red-black-tree.ts +0 -1
  73. package/src/types/data-structures/graph/abstract-graph.ts +0 -2
  74. package/src/types/data-structures/hash/hash-map.ts +0 -3
  75. package/src/types/data-structures/hash/index.ts +0 -1
  76. package/src/types/data-structures/matrix/navigator.ts +0 -2
  77. package/src/types/utils/utils.ts +0 -7
  78. package/src/types/utils/validate-type.ts +0 -7
  79. package/src/utils/number.ts +0 -2
  80. package/src/utils/utils.ts +0 -5
@@ -5,7 +5,6 @@
5
5
  * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
6
6
  * @license MIT License
7
7
  */
8
-
9
8
  import type {
10
9
  DequeOptions,
11
10
  ElementCallback,
@@ -83,7 +82,11 @@ import { LinearBase } from '../base/linear-base';
83
82
  * console.log(dq.toArray()); // [10, 20, 30];
84
83
  */
85
84
  export class Deque<E = any, R = any> extends LinearBase<E, R> {
86
- protected _equals: (a: E, b: E) => boolean = (a, b) => Object.is(a, b);
85
+ /**
86
+ * Counter for shift/pop operations since last compaction check.
87
+ * Only checks ratio every `_bucketSize` operations to minimize overhead.
88
+ */
89
+ protected _compactCounter = 0;
87
90
 
88
91
  /**
89
92
  * Create a Deque and optionally bulk-insert elements.
@@ -92,25 +95,26 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
92
95
  * @param [options] - Options such as bucketSize, toElementFn, and maxLen.
93
96
  * @returns New Deque instance.
94
97
  */
95
-
96
98
  constructor(elements?: IterableWithSizeOrLength<E>, options?: DequeOptions<E, R>);
97
- constructor(elements: IterableWithSizeOrLength<R>, options: DequeOptions<E, R> & { toElementFn: (rawElement: R) => E });
99
+ constructor(
100
+ elements: IterableWithSizeOrLength<R>,
101
+ options: DequeOptions<E, R> & {
102
+ toElementFn: (rawElement: R) => E;
103
+ }
104
+ );
98
105
  constructor(elements: IterableWithSizeOrLength<E> | IterableWithSizeOrLength<R> = [], options?: DequeOptions<E, R>) {
99
106
  super(options);
100
-
101
107
  if (options) {
102
108
  const { bucketSize, autoCompactRatio } = options;
103
109
  if (typeof bucketSize === 'number') this._bucketSize = bucketSize;
104
110
  if (typeof autoCompactRatio === 'number') this._autoCompactRatio = autoCompactRatio;
105
111
  }
106
-
107
112
  let _size: number;
108
113
  if ('length' in elements) {
109
114
  _size = typeof elements.length === 'function' ? elements.length() : elements.length;
110
115
  } else {
111
116
  _size = typeof elements.size === 'function' ? elements.size() : elements.size;
112
117
  }
113
-
114
118
  this._bucketCount = calcMinUnitsRequired(_size, this._bucketSize) || 1;
115
119
  for (let i = 0; i < this._bucketCount; ++i) {
116
120
  this._buckets.push(new Array(this._bucketSize));
@@ -128,7 +132,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
128
132
  * @remarks Time O(1), Space O(1)
129
133
  * @returns Bucket capacity per bucket.
130
134
  */
131
-
132
135
  get bucketSize() {
133
136
  return this._bucketSize;
134
137
  }
@@ -155,12 +158,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
155
158
  this._autoCompactRatio = value;
156
159
  }
157
160
 
158
- /**
159
- * Counter for shift/pop operations since last compaction check.
160
- * Only checks ratio every `_bucketSize` operations to minimize overhead.
161
- */
162
- protected _compactCounter = 0;
163
-
164
161
  protected _bucketFirst = 0;
165
162
 
166
163
  /**
@@ -168,7 +165,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
168
165
  * @remarks Time O(1), Space O(1)
169
166
  * @returns Zero-based bucket index.
170
167
  */
171
-
172
168
  get bucketFirst(): number {
173
169
  return this._bucketFirst;
174
170
  }
@@ -180,7 +176,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
180
176
  * @remarks Time O(1), Space O(1)
181
177
  * @returns Zero-based index within the first bucket.
182
178
  */
183
-
184
179
  get firstInBucket(): number {
185
180
  return this._firstInBucket;
186
181
  }
@@ -192,7 +187,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
192
187
  * @remarks Time O(1), Space O(1)
193
188
  * @returns Zero-based bucket index.
194
189
  */
195
-
196
190
  get bucketLast(): number {
197
191
  return this._bucketLast;
198
192
  }
@@ -204,7 +198,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
204
198
  * @remarks Time O(1), Space O(1)
205
199
  * @returns Zero-based index within the last bucket.
206
200
  */
207
-
208
201
  get lastInBucket(): number {
209
202
  return this._lastInBucket;
210
203
  }
@@ -216,7 +209,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
216
209
  * @remarks Time O(1), Space O(1)
217
210
  * @returns Bucket count.
218
211
  */
219
-
220
212
  get bucketCount(): number {
221
213
  return this._bucketCount;
222
214
  }
@@ -228,7 +220,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
228
220
  * @remarks Time O(1), Space O(1)
229
221
  * @returns Array of buckets storing values.
230
222
  */
231
-
232
223
  get buckets() {
233
224
  return this._buckets;
234
225
  }
@@ -240,97 +231,26 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
240
231
  * @remarks Time O(1), Space O(1)
241
232
  * @returns Current length.
242
233
  */
243
-
244
234
  get length() {
245
235
  return this._length;
246
236
  }
247
237
 
248
238
  /**
249
- * Get the first element without removing it.
250
- * @remarks Time O(1), Space O(1)
251
- * @returns First element or undefined.
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
- * @example
291
- * // Deque peek at both ends
292
- * const deque = new Deque<number>([10, 20, 30, 40, 50]);
293
- *
294
- * // Get first element without removing
295
- * const first = deque.at(0);
296
- * console.log(first); // 10;
297
- *
298
- * // Get last element without removing
299
- * const last = deque.at(deque.length - 1);
300
- * console.log(last); // 50;
301
- *
302
- * // Length unchanged
303
- * console.log(deque.length); // 5;
304
- */
305
-
306
- /**
307
- * Peek at the front element without removing it (alias for `first`).
308
- * @remarks Time O(1), Space O(1)
309
- * @returns Front element or undefined.
310
- */
311
- peek(): E | undefined {
312
- return this.first;
313
- }
314
-
315
- /**
316
239
  * Deque peek at both ends
317
-
318
-
319
-
320
- * @example
321
- * // Deque peek at both ends
322
- * const deque = new Deque<number>([10, 20, 30, 40, 50]);
323
- *
324
- * // Get first element without removing
325
- * const first = deque.at(0);
326
- * console.log(first); // 10;
327
- *
328
- * // Get last element without removing
329
- * const last = deque.at(deque.length - 1);
330
- * console.log(last); // 50;
331
- *
332
- * // Length unchanged
333
- * console.log(deque.length); // 5;
240
+ * @example
241
+ * // Deque peek at both ends
242
+ * const deque = new Deque<number>([10, 20, 30, 40, 50]);
243
+ *
244
+ * // Get first element without removing
245
+ * const first = deque.at(0);
246
+ * console.log(first); // 10;
247
+ *
248
+ * // Get last element without removing
249
+ * const last = deque.at(deque.length - 1);
250
+ * console.log(last); // 50;
251
+ *
252
+ * // Length unchanged
253
+ * console.log(deque.length); // 5;
334
254
  */
335
255
  get first(): E | undefined {
336
256
  if (this._length === 0) return;
@@ -341,55 +261,12 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
341
261
  * Get the last element without removing it.
342
262
  * @remarks Time O(1), Space O(1)
343
263
  * @returns Last element or undefined.
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
-
373
-
374
-
375
-
376
-
377
-
378
-
379
-
380
-
381
-
382
-
383
-
384
-
385
-
386
- * @example
387
- * // Peek at the back element
388
- * const dq = new Deque<string>(['a', 'b', 'c']);
389
- * console.log(dq.last); // 'c';
390
- * console.log(dq.first); // 'a';
264
+ * @example
265
+ * // Peek at the back element
266
+ * const dq = new Deque<string>(['a', 'b', 'c']);
267
+ * console.log(dq.last); // 'c';
268
+ * console.log(dq.first); // 'a';
391
269
  */
392
-
393
270
  get last(): E | undefined {
394
271
  if (this._length === 0) return;
395
272
  return this._buckets[this._bucketLast][this._lastInBucket];
@@ -405,7 +282,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
405
282
  * @param [options] - Options forwarded to the constructor.
406
283
  * @returns A new Deque populated from the array.
407
284
  */
408
-
409
285
  static fromArray<E, R = any>(
410
286
  this: new (
411
287
  elements?: IterableWithSizeOrLength<E> | IterableWithSizeOrLength<R>,
@@ -417,73 +293,58 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
417
293
  return new this(data, options);
418
294
  }
419
295
 
296
+ /**
297
+ * Get the first element without removing it.
298
+ * @remarks Time O(1), Space O(1)
299
+ * @returns First element or undefined.
300
+ * @example
301
+ * // Deque peek at both ends
302
+ * const deque = new Deque<number>([10, 20, 30, 40, 50]);
303
+ *
304
+ * // Get first element without removing
305
+ * const first = deque.at(0);
306
+ * console.log(first); // 10;
307
+ *
308
+ * // Get last element without removing
309
+ * const last = deque.at(deque.length - 1);
310
+ * console.log(last); // 50;
311
+ *
312
+ * // Length unchanged
313
+ * console.log(deque.length); // 5;
314
+ */
315
+ /**
316
+ * Peek at the front element without removing it (alias for `first`).
317
+ * @remarks Time O(1), Space O(1)
318
+ * @returns Front element or undefined.
319
+ */
320
+ peek(): E | undefined {
321
+ return this.first;
322
+ }
323
+
420
324
  /**
421
325
  * Append one element at the back.
422
326
  * @remarks Time O(1) amortized, Space O(1)
423
327
  * @param element - Element to append.
424
328
  * @returns True when appended.
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
-
457
-
458
-
459
-
460
-
461
-
462
-
463
-
464
-
465
-
466
-
467
- * @example
468
- * // basic Deque creation and push/pop operations
469
- * // Create a simple Deque with initial values
470
- * const deque = new Deque([1, 2, 3, 4, 5]);
471
- *
472
- * // Verify the deque maintains insertion order
473
- * console.log([...deque]); // [1, 2, 3, 4, 5];
474
- *
475
- * // Check length
476
- * console.log(deque.length); // 5;
477
- *
478
- * // Push to the end
479
- * deque.push(6);
480
- * console.log(deque.length); // 6;
481
- *
482
- * // Pop from the end
483
- * const last = deque.pop();
484
- * console.log(last); // 6;
329
+ * @example
330
+ * // basic Deque creation and push/pop operations
331
+ * // Create a simple Deque with initial values
332
+ * const deque = new Deque([1, 2, 3, 4, 5]);
333
+ *
334
+ * // Verify the deque maintains insertion order
335
+ * console.log([...deque]); // [1, 2, 3, 4, 5];
336
+ *
337
+ * // Check length
338
+ * console.log(deque.length); // 5;
339
+ *
340
+ * // Push to the end
341
+ * deque.push(6);
342
+ * console.log(deque.length); // 6;
343
+ *
344
+ * // Pop from the end
345
+ * const last = deque.pop();
346
+ * console.log(last); // 6;
485
347
  */
486
-
487
348
  push(element: E): boolean {
488
349
  if (this._length) {
489
350
  if (this._lastInBucket < this._bucketSize - 1) {
@@ -507,55 +368,12 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
507
368
  * Remove and return the last element.
508
369
  * @remarks Time O(1), Space O(1)
509
370
  * @returns Removed element or undefined.
510
-
511
-
512
-
513
-
514
-
515
-
516
-
517
-
518
-
519
-
520
-
521
-
522
-
523
-
524
-
525
-
526
-
527
-
528
-
529
-
530
-
531
-
532
-
533
-
534
-
535
-
536
-
537
-
538
-
539
-
540
-
541
-
542
-
543
-
544
-
545
-
546
-
547
-
548
-
549
-
550
-
551
-
552
- * @example
553
- * // Remove from the back
554
- * const dq = new Deque<number>([1, 2, 3]);
555
- * console.log(dq.pop()); // 3;
556
- * console.log(dq.length); // 2;
371
+ * @example
372
+ * // Remove from the back
373
+ * const dq = new Deque<number>([1, 2, 3]);
374
+ * console.log(dq.pop()); // 3;
375
+ * console.log(dq.length); // 2;
557
376
  */
558
-
559
377
  pop(): E | undefined {
560
378
  if (this._length === 0) return;
561
379
  const element = this._buckets[this._bucketLast][this._lastInBucket];
@@ -579,55 +397,12 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
579
397
  * Remove and return the first element.
580
398
  * @remarks Time O(1) amortized, Space O(1)
581
399
  * @returns Removed element or undefined.
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
-
614
-
615
-
616
-
617
-
618
-
619
-
620
-
621
-
622
-
623
-
624
- * @example
625
- * // Remove from the front
626
- * const dq = new Deque<number>([1, 2, 3]);
627
- * console.log(dq.shift()); // 1;
628
- * console.log(dq.length); // 2;
400
+ * @example
401
+ * // Remove from the front
402
+ * const dq = new Deque<number>([1, 2, 3]);
403
+ * console.log(dq.shift()); // 1;
404
+ * console.log(dq.length); // 2;
629
405
  */
630
-
631
406
  shift(): E | undefined {
632
407
  if (this._length === 0) return;
633
408
  const element = this._buckets[this._bucketFirst][this._firstInBucket];
@@ -652,65 +427,22 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
652
427
  * @remarks Time O(1) amortized, Space O(1)
653
428
  * @param element - Element to prepend.
654
429
  * @returns True when prepended.
655
-
656
-
657
-
658
-
659
-
660
-
661
-
662
-
663
-
664
-
665
-
666
-
667
-
668
-
669
-
670
-
671
-
672
-
673
-
674
-
675
-
676
-
677
-
678
-
679
-
680
-
681
-
682
-
683
-
684
-
685
-
686
-
687
-
688
-
689
-
690
-
691
-
692
-
693
-
694
-
695
-
696
-
697
- * @example
698
- * // Deque shift and unshift operations
699
- * const deque = new Deque<number>([20, 30, 40]);
700
- *
701
- * // Unshift adds to the front
702
- * deque.unshift(10);
703
- * console.log([...deque]); // [10, 20, 30, 40];
704
- *
705
- * // Shift removes from the front (O(1) complexity!)
706
- * const first = deque.shift();
707
- * console.log(first); // 10;
708
- *
709
- * // Verify remaining elements
710
- * console.log([...deque]); // [20, 30, 40];
711
- * console.log(deque.length); // 3;
430
+ * @example
431
+ * // Deque shift and unshift operations
432
+ * const deque = new Deque<number>([20, 30, 40]);
433
+ *
434
+ * // Unshift adds to the front
435
+ * deque.unshift(10);
436
+ * console.log([...deque]); // [10, 20, 30, 40];
437
+ *
438
+ * // Shift removes from the front (O(1) complexity!)
439
+ * const first = deque.shift();
440
+ * console.log(first); // 10;
441
+ *
442
+ * // Verify remaining elements
443
+ * console.log([...deque]); // [20, 30, 40];
444
+ * console.log(deque.length); // 3;
712
445
  */
713
-
714
446
  unshift(element: E): boolean {
715
447
  if (this._length) {
716
448
  if (this._firstInBucket > 0) {
@@ -736,7 +468,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
736
468
  * @param elements - Iterable (or iterable-like) of elements/records.
737
469
  * @returns Array of per-element success flags.
738
470
  */
739
-
740
471
  pushMany(elements: IterableWithSizeOrLength<E> | IterableWithSizeOrLength<R>) {
741
472
  const ans: boolean[] = [];
742
473
  for (const el of elements) {
@@ -755,7 +486,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
755
486
  * @param [elements] - Iterable (or iterable-like) of elements/records.
756
487
  * @returns Array of per-element success flags.
757
488
  */
758
-
759
489
  unshiftMany(elements: IterableWithSizeOrLength<E> | IterableWithSizeOrLength<R> = []) {
760
490
  const ans: boolean[] = [];
761
491
  for (const el of elements) {
@@ -772,52 +502,11 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
772
502
  * Check whether the deque is empty.
773
503
  * @remarks Time O(1), Space O(1)
774
504
  * @returns True if length is 0.
775
-
776
-
777
-
778
-
779
-
780
-
781
-
782
-
783
-
784
-
785
-
786
-
787
-
788
-
789
-
790
-
791
-
792
-
793
-
794
-
795
-
796
-
797
-
798
-
799
-
800
-
801
-
802
-
803
-
804
-
805
-
806
-
807
-
808
-
809
-
810
-
811
-
812
-
813
-
814
-
815
- * @example
816
- * // Check if empty
817
- * const dq = new Deque();
818
- * console.log(dq.isEmpty()); // true;
505
+ * @example
506
+ * // Check if empty
507
+ * const dq = new Deque();
508
+ * console.log(dq.isEmpty()); // true;
819
509
  */
820
-
821
510
  isEmpty(): boolean {
822
511
  return this._length === 0;
823
512
  }
@@ -826,53 +515,12 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
826
515
  * Remove all elements and reset structure.
827
516
  * @remarks Time O(1), Space O(1)
828
517
  * @returns void
829
-
830
-
831
-
832
-
833
-
834
-
835
-
836
-
837
-
838
-
839
-
840
-
841
-
842
-
843
-
844
-
845
-
846
-
847
-
848
-
849
-
850
-
851
-
852
-
853
-
854
-
855
-
856
-
857
-
858
-
859
-
860
-
861
-
862
-
863
-
864
-
865
-
866
-
867
-
868
-
869
- * @example
870
- * // Remove all elements
871
- * const dq = new Deque<number>([1, 2, 3]);
872
- * dq.clear();
873
- * console.log(dq.length); // 0;
518
+ * @example
519
+ * // Remove all elements
520
+ * const dq = new Deque<number>([1, 2, 3]);
521
+ * dq.clear();
522
+ * console.log(dq.length); // 0;
874
523
  */
875
-
876
524
  clear(): void {
877
525
  this._buckets = [new Array(this._bucketSize)];
878
526
  this._bucketCount = 1;
@@ -885,52 +533,12 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
885
533
  * @remarks Time O(1), Space O(1)
886
534
  * @param pos - Zero-based position from the front.
887
535
  * @returns Element or undefined.
888
-
889
-
890
-
891
-
892
-
893
-
894
-
895
-
896
-
897
-
898
-
899
-
900
-
901
-
902
-
903
-
904
-
905
-
906
-
907
-
908
-
909
-
910
-
911
-
912
-
913
-
914
-
915
-
916
-
917
-
918
-
919
-
920
-
921
-
922
-
923
-
924
-
925
-
926
-
927
- * @example
928
- * // Access by index
929
- * const dq = new Deque<string>(['a', 'b', 'c']);
930
- * console.log(dq.at(0)); // 'a';
931
- * console.log(dq.at(2)); // 'c';
536
+ * @example
537
+ * // Access by index
538
+ * const dq = new Deque<string>(['a', 'b', 'c']);
539
+ * console.log(dq.at(0)); // 'a';
540
+ * console.log(dq.at(2)); // 'c';
932
541
  */
933
-
934
542
  at(pos: number): E | undefined {
935
543
  if (pos < 0 || pos >= this._length) return undefined;
936
544
  const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);
@@ -944,7 +552,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
944
552
  * @param element - New element value.
945
553
  * @returns True if updated.
946
554
  */
947
-
948
555
  setAt(pos: number, element: E): boolean {
949
556
  rangeCheck(pos, 0, this._length - 1);
950
557
  const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);
@@ -960,7 +567,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
960
567
  * @param [num] - Number of times to insert (default 1).
961
568
  * @returns True if inserted.
962
569
  */
963
-
964
570
  addAt(pos: number, element: E, num = 1): boolean {
965
571
  const length = this._length;
966
572
  rangeCheck(pos, 0, length);
@@ -988,7 +594,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
988
594
  * @param [isCutSelf] - When true, mutate this deque; otherwise return a new deque.
989
595
  * @returns This deque if in-place; otherwise a new deque of the prefix.
990
596
  */
991
-
992
597
  cut(pos: number, isCutSelf = false): Deque<E> {
993
598
  if (isCutSelf) {
994
599
  if (pos < 0) {
@@ -1007,7 +612,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1007
612
  const v = this.at(i);
1008
613
  if (v !== undefined) newDeque.push(v);
1009
614
  }
1010
-
1011
615
  return newDeque;
1012
616
  }
1013
617
  }
@@ -1020,31 +624,24 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1020
624
  * @param [items] - Elements to insert after `start`.
1021
625
  * @returns A new deque containing the removed elements (typed as `this`).
1022
626
  */
1023
-
1024
627
  override splice(start: number, deleteCount: number = this._length - start, ...items: E[]): this {
1025
628
  rangeCheck(start, 0, this._length);
1026
629
  if (deleteCount < 0) deleteCount = 0;
1027
630
  if (start + deleteCount > this._length) deleteCount = this._length - start;
1028
-
1029
631
  const removed = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
1030
632
  removed._setBucketSize(this._bucketSize);
1031
633
  for (let i = 0; i < deleteCount; i++) {
1032
634
  const v = this.at(start + i);
1033
635
  if (v !== undefined) removed.push(v);
1034
636
  }
1035
-
1036
637
  const tail: E[] = [];
1037
638
  for (let i = start + deleteCount; i < this._length; i++) {
1038
639
  const v = this.at(i);
1039
640
  if (v !== undefined) tail.push(v);
1040
641
  }
1041
-
1042
642
  this.cut(start - 1, true);
1043
-
1044
643
  for (const it of items) this.push(it);
1045
-
1046
644
  for (const v of tail) this.push(v);
1047
-
1048
645
  return removed as unknown as this;
1049
646
  }
1050
647
 
@@ -1055,7 +652,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1055
652
  * @param [isCutSelf] - When true, mutate this deque; otherwise return a new deque.
1056
653
  * @returns This deque if in-place; otherwise a new deque of the suffix.
1057
654
  */
1058
-
1059
655
  cutRest(pos: number, isCutSelf = false): Deque<E> {
1060
656
  if (isCutSelf) {
1061
657
  if (pos < 0) {
@@ -1084,10 +680,8 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1084
680
  * @param pos - Zero-based position from the front.
1085
681
  * @returns Removed element or undefined.
1086
682
  */
1087
-
1088
683
  deleteAt(pos: number): E | undefined {
1089
684
  rangeCheck(pos, 0, this._length - 1);
1090
-
1091
685
  let deleted: E | undefined;
1092
686
  if (pos === 0) {
1093
687
  return this.shift();
@@ -1099,13 +693,11 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1099
693
  const length = this._length - 1;
1100
694
  const { bucketIndex: targetBucket, indexInBucket: targetPointer } = this._getBucketAndPosition(pos);
1101
695
  deleted = this._buckets[targetBucket][targetPointer];
1102
-
1103
696
  for (let i = pos; i < length; i++) {
1104
697
  const { bucketIndex: curBucket, indexInBucket: curPointer } = this._getBucketAndPosition(i);
1105
698
  const { bucketIndex: nextBucket, indexInBucket: nextPointer } = this._getBucketAndPosition(i + 1);
1106
699
  this._buckets[curBucket][curPointer] = this._buckets[nextBucket][nextPointer];
1107
700
  }
1108
-
1109
701
  this.pop();
1110
702
  return deleted;
1111
703
  }
@@ -1116,52 +708,12 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1116
708
  * @remarks Time O(N), Space O(1)
1117
709
  * @param element - Element to remove (using the configured equality).
1118
710
  * @returns True if an element was removed.
1119
-
1120
-
1121
-
1122
-
1123
-
1124
-
1125
-
1126
-
1127
-
1128
-
1129
-
1130
-
1131
-
1132
-
1133
-
1134
-
1135
-
1136
-
1137
-
1138
-
1139
-
1140
-
1141
-
1142
-
1143
-
1144
-
1145
-
1146
-
1147
-
1148
-
1149
-
1150
-
1151
-
1152
-
1153
-
1154
-
1155
-
1156
-
1157
-
1158
- * @example
1159
- * // Remove element
1160
- * const dq = new Deque<number>([1, 2, 3]);
1161
- * dq.delete(2);
1162
- * console.log(dq.length); // 2;
711
+ * @example
712
+ * // Remove element
713
+ * const dq = new Deque<number>([1, 2, 3]);
714
+ * dq.delete(2);
715
+ * console.log(dq.length); // 2;
1163
716
  */
1164
-
1165
717
  delete(element: E): boolean {
1166
718
  const size = this._length;
1167
719
  if (size === 0) return false;
@@ -1185,7 +737,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1185
737
  * @param predicate - Function (value, index, deque) → boolean.
1186
738
  * @returns True if a match was removed.
1187
739
  */
1188
-
1189
740
  deleteWhere(predicate: (value: E, index: number, deque: this) => boolean): boolean {
1190
741
  for (let i = 0; i < this._length; i++) {
1191
742
  const v = this.at(i);
@@ -1203,7 +754,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1203
754
  * @param equals - Equality predicate (a, b) → boolean.
1204
755
  * @returns This deque.
1205
756
  */
1206
-
1207
757
  setEquality(equals: (a: E, b: E) => boolean): this {
1208
758
  this._equals = equals;
1209
759
  return this;
@@ -1213,75 +763,35 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1213
763
  * Reverse the deque by reversing buckets and pointers.
1214
764
  * @remarks Time O(N), Space O(N)
1215
765
  * @returns This deque.
1216
-
1217
-
1218
-
1219
-
1220
-
1221
-
1222
-
1223
-
1224
-
1225
-
1226
-
1227
-
1228
-
1229
-
1230
-
1231
-
1232
-
1233
-
1234
-
1235
-
1236
-
1237
-
1238
-
1239
-
1240
-
1241
-
1242
-
1243
-
1244
-
1245
-
1246
-
1247
-
1248
-
1249
-
1250
-
1251
-
1252
-
1253
-
1254
-
1255
- * @example
1256
- * // Deque for...of iteration and reverse
1257
- * const deque = new Deque<string>(['A', 'B', 'C', 'D']);
1258
- *
1259
- * // Iterate forward
1260
- * const forward: string[] = [];
1261
- * for (const item of deque) {
1262
- * forward.push(item);
1263
- * }
1264
- * console.log(forward); // ['A', 'B', 'C', 'D'];
1265
- *
1266
- * // Reverse the deque
1267
- * deque.reverse();
1268
- * const backward: string[] = [];
1269
- * for (const item of deque) {
1270
- * backward.push(item);
1271
- * }
1272
- * console.log(backward); // ['D', 'C', 'B', 'A'];
766
+ * @example
767
+ * // Deque for...of iteration and reverse
768
+ * const deque = new Deque<string>(['A', 'B', 'C', 'D']);
769
+ *
770
+ * // Iterate forward
771
+ * const forward: string[] = [];
772
+ * for (const item of deque) {
773
+ * forward.push(item);
774
+ * }
775
+ * console.log(forward); // ['A', 'B', 'C', 'D'];
776
+ *
777
+ * // Reverse the deque
778
+ * deque.reverse();
779
+ * const backward: string[] = [];
780
+ * for (const item of deque) {
781
+ * backward.push(item);
782
+ * }
783
+ * console.log(backward); // ['D', 'C', 'B', 'A'];
1273
784
  */
1274
-
1275
785
  /**
1276
786
  * Find the last value matching a predicate (scans back-to-front).
1277
787
  * @remarks Provided for familiarity when migrating from Array. Time O(n), Space O(1).
1278
788
  * @param predicate - Function called with (value, index, deque).
1279
789
  * @returns Matching value or undefined.
1280
- * @example
1281
- * // Find last matching value
1282
- * const d = new Deque([1, 2, 3, 4, 5]);
1283
- * console.log(d.findLast(v => v > 2)); // 5;
1284
- * console.log(d.findLast(v => v % 2 === 0)); // 4;
790
+ * @example
791
+ * // Find last matching value
792
+ * const d = new Deque([1, 2, 3, 4, 5]);
793
+ * console.log(d.findLast(v => v > 2)); // 5;
794
+ * console.log(d.findLast(v => v % 2 === 0)); // 4;
1285
795
  */
1286
796
  findLast(predicate: (value: E, index: number, deque: this) => boolean): E | undefined {
1287
797
  for (let i = this.length - 1; i >= 0; i--) {
@@ -1296,11 +806,11 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1296
806
  * @remarks Provided for familiarity when migrating from Array. Time O(n), Space O(1).
1297
807
  * @param predicate - Function called with (value, index, deque).
1298
808
  * @returns Matching index, or -1 if not found.
1299
- * @example
1300
- * // Find last matching index
1301
- * const d = new Deque([10, 20, 30, 20, 10]);
1302
- * console.log(d.findLastIndex(v => v === 20)); // 3;
1303
- * console.log(d.findLastIndex(v => v === 10)); // 4;
809
+ * @example
810
+ * // Find last matching index
811
+ * const d = new Deque([10, 20, 30, 20, 10]);
812
+ * console.log(d.findLastIndex(v => v === 20)); // 3;
813
+ * console.log(d.findLastIndex(v => v === 10)); // 4;
1304
814
  */
1305
815
  findLastIndex(predicate: (value: E, index: number, deque: this) => boolean): number {
1306
816
  for (let i = this.length - 1; i >= 0; i--) {
@@ -1309,28 +819,26 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1309
819
  return -1;
1310
820
  }
1311
821
 
1312
- /**
822
+ /**
1313
823
  * Deque for...of iteration and reverse
1314
-
1315
-
1316
- * @example
1317
- * // Deque for...of iteration and reverse
1318
- * const deque = new Deque<string>(['A', 'B', 'C', 'D']);
1319
- *
1320
- * // Iterate forward
1321
- * const forward: string[] = [];
1322
- * for (const item of deque) {
1323
- * forward.push(item);
1324
- * }
1325
- * console.log(forward); // ['A', 'B', 'C', 'D'];
1326
- *
1327
- * // Reverse the deque
1328
- * deque.reverse();
1329
- * const backward: string[] = [];
1330
- * for (const item of deque) {
1331
- * backward.push(item);
1332
- * }
1333
- * console.log(backward); // ['D', 'C', 'B', 'A'];
824
+ * @example
825
+ * // Deque for...of iteration and reverse
826
+ * const deque = new Deque<string>(['A', 'B', 'C', 'D']);
827
+ *
828
+ * // Iterate forward
829
+ * const forward: string[] = [];
830
+ * for (const item of deque) {
831
+ * forward.push(item);
832
+ * }
833
+ * console.log(forward); // ['A', 'B', 'C', 'D'];
834
+ *
835
+ * // Reverse the deque
836
+ * deque.reverse();
837
+ * const backward: string[] = [];
838
+ * for (const item of deque) {
839
+ * backward.push(item);
840
+ * }
841
+ * console.log(backward); // ['D', 'C', 'B', 'A'];
1334
842
  */
1335
843
  reverse(): this {
1336
844
  this._buckets.reverse().forEach(function (bucket) {
@@ -1349,7 +857,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1349
857
  * @remarks Time O(N), Space O(1)
1350
858
  * @returns This deque.
1351
859
  */
1352
-
1353
860
  unique(): this {
1354
861
  if (this._length <= 1) {
1355
862
  return this;
@@ -1367,30 +874,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1367
874
  return this;
1368
875
  }
1369
876
 
1370
- /**
1371
- * Trim unused buckets to fit exactly the active range.
1372
- * @remarks Time O(N), Space O(1)
1373
- * @returns void
1374
- */
1375
-
1376
- /**
1377
- * (Protected) Trigger auto-compaction if space utilization drops below threshold.
1378
- * Only checks every `_bucketSize` operations to minimize hot-path overhead.
1379
- * Uses element-based ratio: `elements / (bucketCount * bucketSize)`.
1380
- */
1381
- protected _autoCompact(): void {
1382
- if (this._autoCompactRatio <= 0 || this._bucketCount <= 1) return;
1383
-
1384
- this._compactCounter++;
1385
- if (this._compactCounter < this._bucketSize) return;
1386
- this._compactCounter = 0;
1387
-
1388
- const utilization = this._length / (this._bucketCount * this._bucketSize);
1389
- if (utilization < this._autoCompactRatio) {
1390
- this.shrinkToFit();
1391
- }
1392
- }
1393
-
1394
877
  /**
1395
878
  * Compact the deque by removing unused buckets.
1396
879
  * @remarks Time O(N), Space O(1)
@@ -1400,52 +883,13 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1400
883
  * Compact the deque by removing unused buckets.
1401
884
  * @remarks Time O(N), Space O(1)
1402
885
  * @returns True if compaction was performed (bucket count reduced).
1403
-
1404
-
1405
-
1406
-
1407
-
1408
-
1409
-
1410
-
1411
-
1412
-
1413
-
1414
-
1415
-
1416
-
1417
-
1418
-
1419
-
1420
-
1421
-
1422
-
1423
-
1424
-
1425
-
1426
-
1427
-
1428
-
1429
-
1430
-
1431
-
1432
-
1433
-
1434
-
1435
-
1436
-
1437
-
1438
-
1439
-
1440
-
1441
-
1442
- * @example
1443
- * // Reclaim memory
1444
- * const dq = new Deque<number>([1, 2, 3, 4, 5]);
1445
- * dq.shift();
1446
- * dq.shift();
1447
- * dq.compact();
1448
- * console.log(dq.length); // 3;
886
+ * @example
887
+ * // Reclaim memory
888
+ * const dq = new Deque<number>([1, 2, 3, 4, 5]);
889
+ * dq.shift();
890
+ * dq.shift();
891
+ * dq.compact();
892
+ * console.log(dq.length); // 3;
1449
893
  */
1450
894
  compact(): boolean {
1451
895
  const before = this._bucketCount;
@@ -1479,55 +923,14 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1479
923
  * Deep clone this deque, preserving options.
1480
924
  * @remarks Time O(N), Space O(N)
1481
925
  * @returns A new deque with the same content and options.
1482
-
1483
-
1484
-
1485
-
1486
-
1487
-
1488
-
1489
-
1490
-
1491
-
1492
-
1493
-
1494
-
1495
-
1496
-
1497
-
1498
-
1499
-
1500
-
1501
-
1502
-
1503
-
1504
-
1505
-
1506
-
1507
-
1508
-
1509
-
1510
-
1511
-
1512
-
1513
-
1514
-
1515
-
1516
-
1517
-
1518
-
1519
-
1520
-
1521
-
1522
- * @example
1523
- * // Create independent copy
1524
- * const dq = new Deque<number>([1, 2, 3]);
1525
- * const copy = dq.clone();
1526
- * copy.pop();
1527
- * console.log(dq.length); // 3;
1528
- * console.log(copy.length); // 2;
926
+ * @example
927
+ * // Create independent copy
928
+ * const dq = new Deque<number>([1, 2, 3]);
929
+ * const copy = dq.clone();
930
+ * copy.pop();
931
+ * console.log(dq.length); // 3;
932
+ * console.log(copy.length); // 2;
1529
933
  */
1530
-
1531
934
  clone(): this {
1532
935
  return this._createLike<E, R>(this, {
1533
936
  bucketSize: this.bucketSize,
@@ -1542,53 +945,12 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1542
945
  * @param predicate - Predicate (value, index, deque) → boolean to keep element.
1543
946
  * @param [thisArg] - Value for `this` inside the predicate.
1544
947
  * @returns A new deque with kept elements.
1545
-
1546
-
1547
-
1548
-
1549
-
1550
-
1551
-
1552
-
1553
-
1554
-
1555
-
1556
-
1557
-
1558
-
1559
-
1560
-
1561
-
1562
-
1563
-
1564
-
1565
-
1566
-
1567
-
1568
-
1569
-
1570
-
1571
-
1572
-
1573
-
1574
-
1575
-
1576
-
1577
-
1578
-
1579
-
1580
-
1581
-
1582
-
1583
-
1584
-
1585
- * @example
1586
- * // Filter elements
1587
- * const dq = new Deque<number>([1, 2, 3, 4]);
1588
- * const result = dq.filter(x => x > 2);
1589
- * console.log(result.length); // 2;
948
+ * @example
949
+ * // Filter elements
950
+ * const dq = new Deque<number>([1, 2, 3, 4]);
951
+ * const result = dq.filter(x => x > 2);
952
+ * console.log(result.length); // 2;
1590
953
  */
1591
-
1592
954
  filter(predicate: ElementCallback<E, R, boolean>, thisArg?: unknown): this {
1593
955
  const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
1594
956
  out._setBucketSize(this._bucketSize);
@@ -1607,7 +969,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1607
969
  * @param [thisArg] - Value for `this` inside the callback.
1608
970
  * @returns A new deque with mapped values.
1609
971
  */
1610
-
1611
972
  mapSame(callback: ElementCallback<E, R, E>, thisArg?: unknown): this {
1612
973
  const out = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
1613
974
  out._setBucketSize(this._bucketSize);
@@ -1628,52 +989,12 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1628
989
  * @param [options] - Options for the output deque (e.g., bucketSize, toElementFn, maxLen).
1629
990
  * @param [thisArg] - Value for `this` inside the callback.
1630
991
  * @returns A new Deque with mapped elements.
1631
-
1632
-
1633
-
1634
-
1635
-
1636
-
1637
-
1638
-
1639
-
1640
-
1641
-
1642
-
1643
-
1644
-
1645
-
1646
-
1647
-
1648
-
1649
-
1650
-
1651
-
1652
-
1653
-
1654
-
1655
-
1656
-
1657
-
1658
-
1659
-
1660
-
1661
-
1662
-
1663
-
1664
-
1665
-
1666
-
1667
-
1668
-
1669
-
1670
- * @example
1671
- * // Transform elements
1672
- * const dq = new Deque<number>([1, 2, 3]);
1673
- * const result = dq.map(x => x * 10);
1674
- * console.log(result.toArray()); // [10, 20, 30];
992
+ * @example
993
+ * // Transform elements
994
+ * const dq = new Deque<number>([1, 2, 3]);
995
+ * const result = dq.map(x => x * 10);
996
+ * console.log(result.toArray()); // [10, 20, 30];
1675
997
  */
1676
-
1677
998
  map<EM, RM>(
1678
999
  callback: ElementCallback<E, R, EM>,
1679
1000
  options?: IterableElementBaseOptions<EM, RM>,
@@ -1693,16 +1014,37 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1693
1014
  return out;
1694
1015
  }
1695
1016
 
1017
+ protected _equals: (a: E, b: E) => boolean = (a, b) => Object.is(a, b);
1018
+
1019
+ /**
1020
+ * Trim unused buckets to fit exactly the active range.
1021
+ * @remarks Time O(N), Space O(1)
1022
+ * @returns void
1023
+ */
1024
+ /**
1025
+ * (Protected) Trigger auto-compaction if space utilization drops below threshold.
1026
+ * Only checks every `_bucketSize` operations to minimize hot-path overhead.
1027
+ * Uses element-based ratio: `elements / (bucketCount * bucketSize)`.
1028
+ */
1029
+ protected _autoCompact(): void {
1030
+ if (this._autoCompactRatio <= 0 || this._bucketCount <= 1) return;
1031
+ this._compactCounter++;
1032
+ if (this._compactCounter < this._bucketSize) return;
1033
+ this._compactCounter = 0;
1034
+ const utilization = this._length / (this._bucketCount * this._bucketSize);
1035
+ if (utilization < this._autoCompactRatio) {
1036
+ this.shrinkToFit();
1037
+ }
1038
+ }
1039
+
1696
1040
  /**
1697
1041
  * (Protected) Set the internal bucket size.
1698
1042
  * @remarks Time O(1), Space O(1)
1699
1043
  * @param size - Bucket capacity to assign.
1700
1044
  * @returns void
1701
1045
  */
1702
-
1703
1046
  protected _setBucketSize(size: number): void {
1704
1047
  this._bucketSize = size;
1705
-
1706
1048
  // When adjusting bucketSize on a freshly created empty deque (common in helpers like cut/splice/clone),
1707
1049
  // we must also realign internal pointers/buckets to avoid `_getBucketAndPosition` producing out-of-range
1708
1050
  // indices based on the previous bucketSize.
@@ -1719,7 +1061,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1719
1061
  * @remarks Time O(N), Space O(1)
1720
1062
  * @returns Iterator of elements.
1721
1063
  */
1722
-
1723
1064
  protected *_getIterator(): IterableIterator<E> {
1724
1065
  for (let i = 0; i < this._length; ++i) {
1725
1066
  const v = this.at(i);
@@ -1733,7 +1074,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1733
1074
  * @param [needBucketNum] - How many extra buckets to add; defaults to half of current.
1734
1075
  * @returns void
1735
1076
  */
1736
-
1737
1077
  protected _reallocate(needBucketNum?: number) {
1738
1078
  const newBuckets = [] as E[][];
1739
1079
  const addBucketNum = needBucketNum || this._bucketCount >> 1 || 1;
@@ -1762,23 +1102,18 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1762
1102
  * @param pos - Zero-based position.
1763
1103
  * @returns An object containing bucketIndex and indexInBucket.
1764
1104
  */
1765
-
1766
1105
  protected _getBucketAndPosition(pos: number) {
1767
1106
  let bucketIndex: number;
1768
1107
  let indexInBucket: number;
1769
-
1770
1108
  const overallIndex = this._firstInBucket + pos;
1771
1109
  bucketIndex = this._bucketFirst + Math.floor(overallIndex / this._bucketSize);
1772
-
1773
1110
  if (bucketIndex >= this._bucketCount) {
1774
1111
  bucketIndex -= this._bucketCount;
1775
1112
  }
1776
-
1777
1113
  indexInBucket = ((overallIndex + 1) % this._bucketSize) - 1;
1778
1114
  if (indexInBucket < 0) {
1779
1115
  indexInBucket = this._bucketSize - 1;
1780
1116
  }
1781
-
1782
1117
  return { bucketIndex, indexInBucket };
1783
1118
  }
1784
1119
 
@@ -1788,7 +1123,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1788
1123
  * @param [options] - Options forwarded to the constructor.
1789
1124
  * @returns An empty like-kind deque instance.
1790
1125
  */
1791
-
1792
1126
  protected override _createInstance(options?: LinearBaseOptions<E, R>): this {
1793
1127
  const Ctor = this.constructor as new (
1794
1128
  elements?: IterableWithSizeOrLength<E> | IterableWithSizeOrLength<R>,
@@ -1806,7 +1140,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1806
1140
  * @param [options] - Options forwarded to the constructor.
1807
1141
  * @returns A like-kind Deque instance.
1808
1142
  */
1809
-
1810
1143
  protected _createLike<T = E, RR = R>(
1811
1144
  elements: IterableWithSizeOrLength<T> | IterableWithSizeOrLength<RR> = [],
1812
1145
  options?: DequeOptions<T, RR>
@@ -1823,7 +1156,6 @@ export class Deque<E = any, R = any> extends LinearBase<E, R> {
1823
1156
  * @remarks Time O(N), Space O(1)
1824
1157
  * @returns Iterator of elements.
1825
1158
  */
1826
-
1827
1159
  protected *_getReverseIterator(): IterableIterator<E> {
1828
1160
  for (let i = this._length - 1; i > -1; i--) {
1829
1161
  const v = this.at(i);