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 { DoublyLinkedListOptions, ElementCallback, LinearBaseOptions } from '../../types';
10
9
  import { LinearLinkedBase, LinkedListNode } from '../base/linear-base';
11
10
 
@@ -21,7 +20,6 @@ export class DoublyLinkedListNode<E = any> extends LinkedListNode<E> {
21
20
  * @param value - Element value to store.
22
21
  * @returns New node instance.
23
22
  */
24
-
25
23
  constructor(value: E) {
26
24
  super(value);
27
25
  this._value = value;
@@ -36,7 +34,6 @@ export class DoublyLinkedListNode<E = any> extends LinkedListNode<E> {
36
34
  * @remarks Time O(1), Space O(1)
37
35
  * @returns Next node or undefined.
38
36
  */
39
-
40
37
  override get next(): DoublyLinkedListNode<E> | undefined {
41
38
  return this._next;
42
39
  }
@@ -47,7 +44,6 @@ export class DoublyLinkedListNode<E = any> extends LinkedListNode<E> {
47
44
  * @param value - Next node or undefined.
48
45
  * @returns void
49
46
  */
50
-
51
47
  override set next(value: DoublyLinkedListNode<E> | undefined) {
52
48
  this._next = value;
53
49
  }
@@ -59,7 +55,6 @@ export class DoublyLinkedListNode<E = any> extends LinkedListNode<E> {
59
55
  * @remarks Time O(1), Space O(1)
60
56
  * @returns Previous node or undefined.
61
57
  */
62
-
63
58
  get prev(): DoublyLinkedListNode<E> | undefined {
64
59
  return this._prev;
65
60
  }
@@ -70,7 +65,6 @@ export class DoublyLinkedListNode<E = any> extends LinkedListNode<E> {
70
65
  * @param value - Previous node or undefined.
71
66
  * @returns void
72
67
  */
73
-
74
68
  set prev(value: DoublyLinkedListNode<E> | undefined) {
75
69
  this._prev = value;
76
70
  }
@@ -148,8 +142,6 @@ export class DoublyLinkedListNode<E = any> extends LinkedListNode<E> {
148
142
  * console.log(sum); // [1, 2, 3];
149
143
  */
150
144
  export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, DoublyLinkedListNode<E>> {
151
- protected _equals: (a: E, b: E) => boolean = (a, b) => Object.is(a, b);
152
-
153
145
  /**
154
146
  * Create a DoublyLinkedList and optionally bulk-insert elements.
155
147
  * @remarks Time O(N), Space O(N)
@@ -157,7 +149,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
157
149
  * @param [options] - Options such as maxLen and toElementFn.
158
150
  * @returns New DoublyLinkedList instance.
159
151
  */
160
-
161
152
  constructor(
162
153
  elements: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>> = [],
163
154
  options?: DoublyLinkedListOptions<E, R>
@@ -166,11 +157,9 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
166
157
  this._head = undefined;
167
158
  this._tail = undefined;
168
159
  this._length = 0;
169
-
170
160
  if (options?.maxLen && Number.isInteger(options.maxLen) && options.maxLen > 0) {
171
161
  this._maxLen = options.maxLen;
172
162
  }
173
-
174
163
  this.pushMany(elements);
175
164
  }
176
165
 
@@ -181,7 +170,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
181
170
  * @remarks Time O(1), Space O(1)
182
171
  * @returns Head node or undefined.
183
172
  */
184
-
185
173
  get head(): DoublyLinkedListNode<E> | undefined {
186
174
  return this._head;
187
175
  }
@@ -193,7 +181,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
193
181
  * @remarks Time O(1), Space O(1)
194
182
  * @returns Tail node or undefined.
195
183
  */
196
-
197
184
  get tail(): DoublyLinkedListNode<E> | undefined {
198
185
  return this._tail;
199
186
  }
@@ -205,7 +192,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
205
192
  * @remarks Time O(1), Space O(1)
206
193
  * @returns Current length.
207
194
  */
208
-
209
195
  get length(): number {
210
196
  return this._length;
211
197
  }
@@ -215,7 +201,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
215
201
  * @remarks Time O(1), Space O(1)
216
202
  * @returns First element or undefined.
217
203
  */
218
-
219
204
  get first(): E | undefined {
220
205
  return this.head?.value;
221
206
  }
@@ -225,7 +210,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
225
210
  * @remarks Time O(1), Space O(1)
226
211
  * @returns Last element or undefined.
227
212
  */
228
-
229
213
  get last(): E | undefined {
230
214
  return this.tail?.value;
231
215
  }
@@ -239,7 +223,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
239
223
  * @param data - Array of elements to insert.
240
224
  * @returns A new list populated with the array's elements.
241
225
  */
242
-
243
226
  static fromArray<E, R = any>(
244
227
  this: new (
245
228
  elements?: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>,
@@ -256,7 +239,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
256
239
  * @param elementNodeOrPredicate - Element, node, or predicate.
257
240
  * @returns True if the value is a DoublyLinkedListNode.
258
241
  */
259
-
260
242
  isNode(
261
243
  elementNodeOrPredicate: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)
262
244
  ): elementNodeOrPredicate is DoublyLinkedListNode<E> {
@@ -268,65 +250,22 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
268
250
  * @remarks Time O(1), Space O(1)
269
251
  * @param elementOrNode - Element or node to append.
270
252
  * @returns True when appended.
271
-
272
-
273
-
274
-
275
-
276
-
277
-
278
-
279
-
280
-
281
-
282
-
283
-
284
-
285
-
286
-
287
-
288
-
289
-
290
-
291
-
292
-
293
-
294
-
295
-
296
-
297
-
298
-
299
-
300
-
301
-
302
-
303
-
304
-
305
-
306
-
307
-
308
-
309
-
310
-
311
-
312
-
313
- * @example
314
- * // basic DoublyLinkedList creation and push operation
315
- * // Create a simple DoublyLinkedList with initial values
316
- * const list = new DoublyLinkedList([1, 2, 3, 4, 5]);
317
- *
318
- * // Verify the list maintains insertion order
319
- * console.log([...list]); // [1, 2, 3, 4, 5];
320
- *
321
- * // Check length
322
- * console.log(list.length); // 5;
323
- *
324
- * // Push a new element to the end
325
- * list.push(6);
326
- * console.log(list.length); // 6;
327
- * console.log([...list]); // [1, 2, 3, 4, 5, 6];
253
+ * @example
254
+ * // basic DoublyLinkedList creation and push operation
255
+ * // Create a simple DoublyLinkedList with initial values
256
+ * const list = new DoublyLinkedList([1, 2, 3, 4, 5]);
257
+ *
258
+ * // Verify the list maintains insertion order
259
+ * console.log([...list]); // [1, 2, 3, 4, 5];
260
+ *
261
+ * // Check length
262
+ * console.log(list.length); // 5;
263
+ *
264
+ * // Push a new element to the end
265
+ * list.push(6);
266
+ * console.log(list.length); // 6;
267
+ * console.log([...list]); // [1, 2, 3, 4, 5, 6];
328
268
  */
329
-
330
269
  push(elementOrNode: E | DoublyLinkedListNode<E>): boolean {
331
270
  const newNode = this._ensureNode(elementOrNode);
332
271
  if (!this.head) {
@@ -346,65 +285,22 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
346
285
  * Remove and return the tail element.
347
286
  * @remarks Time O(1), Space O(1)
348
287
  * @returns Removed element or undefined.
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
-
387
-
388
-
389
-
390
-
391
- * @example
392
- * // DoublyLinkedList pop and shift operations
393
- * const list = new DoublyLinkedList<number>([10, 20, 30, 40, 50]);
394
- *
395
- * // Pop removes from the end
396
- * const last = list.pop();
397
- * console.log(last); // 50;
398
- *
399
- * // Shift removes from the beginning
400
- * const first = list.shift();
401
- * console.log(first); // 10;
402
- *
403
- * // Verify remaining elements
404
- * console.log([...list]); // [20, 30, 40];
405
- * console.log(list.length); // 3;
288
+ * @example
289
+ * // DoublyLinkedList pop and shift operations
290
+ * const list = new DoublyLinkedList<number>([10, 20, 30, 40, 50]);
291
+ *
292
+ * // Pop removes from the end
293
+ * const last = list.pop();
294
+ * console.log(last); // 50;
295
+ *
296
+ * // Shift removes from the beginning
297
+ * const first = list.shift();
298
+ * console.log(first); // 10;
299
+ *
300
+ * // Verify remaining elements
301
+ * console.log([...list]); // [20, 30, 40];
302
+ * console.log(list.length); // 3;
406
303
  */
407
-
408
304
  pop(): E | undefined {
409
305
  if (!this.tail) return undefined;
410
306
  const removed = this.tail;
@@ -423,55 +319,12 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
423
319
  * Remove and return the head element.
424
320
  * @remarks Time O(1), Space O(1)
425
321
  * @returns Removed element or undefined.
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
-
468
- * @example
469
- * // Remove from the front
470
- * const list = new DoublyLinkedList<number>([10, 20, 30]);
471
- * console.log(list.shift()); // 10;
472
- * console.log(list.first); // 20;
322
+ * @example
323
+ * // Remove from the front
324
+ * const list = new DoublyLinkedList<number>([10, 20, 30]);
325
+ * console.log(list.shift()); // 10;
326
+ * console.log(list.first); // 20;
473
327
  */
474
-
475
328
  shift(): E | undefined {
476
329
  if (!this.head) return undefined;
477
330
  const removed = this.head;
@@ -491,55 +344,12 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
491
344
  * @remarks Time O(1), Space O(1)
492
345
  * @param elementOrNode - Element or node to prepend.
493
346
  * @returns True when prepended.
494
-
495
-
496
-
497
-
498
-
499
-
500
-
501
-
502
-
503
-
504
-
505
-
506
-
507
-
508
-
509
-
510
-
511
-
512
-
513
-
514
-
515
-
516
-
517
-
518
-
519
-
520
-
521
-
522
-
523
-
524
-
525
-
526
-
527
-
528
-
529
-
530
-
531
-
532
-
533
-
534
-
535
-
536
- * @example
537
- * // Add to the front
538
- * const list = new DoublyLinkedList<number>([2, 3]);
539
- * list.unshift(1);
540
- * console.log([...list]); // [1, 2, 3];
347
+ * @example
348
+ * // Add to the front
349
+ * const list = new DoublyLinkedList<number>([2, 3]);
350
+ * list.unshift(1);
351
+ * console.log([...list]); // [1, 2, 3];
541
352
  */
542
-
543
353
  unshift(elementOrNode: E | DoublyLinkedListNode<E>): boolean {
544
354
  const newNode = this._ensureNode(elementOrNode);
545
355
  if (!this.head) {
@@ -561,7 +371,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
561
371
  * @param elements - Iterable of elements or nodes (or raw records if toElementFn is provided).
562
372
  * @returns Array of per-element success flags.
563
373
  */
564
-
565
374
  pushMany(elements: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>): boolean[] {
566
375
  const ans: boolean[] = [];
567
376
  for (const el of elements) {
@@ -577,7 +386,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
577
386
  * @param elements - Iterable of elements or nodes (or raw records if toElementFn is provided).
578
387
  * @returns Array of per-element success flags.
579
388
  */
580
-
581
389
  unshiftMany(elements: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>): boolean[] {
582
390
  const ans: boolean[] = [];
583
391
  for (const el of elements) {
@@ -592,55 +400,12 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
592
400
  * @remarks Time O(N), Space O(1)
593
401
  * @param index - Zero-based index.
594
402
  * @returns Element or undefined.
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
-
625
-
626
-
627
-
628
-
629
-
630
-
631
-
632
-
633
-
634
-
635
-
636
-
637
- * @example
638
- * // Access by index
639
- * const list = new DoublyLinkedList<string>(['a', 'b', 'c']);
640
- * console.log(list.at(1)); // 'b';
641
- * console.log(list.at(2)); // 'c';
403
+ * @example
404
+ * // Access by index
405
+ * const list = new DoublyLinkedList<string>(['a', 'b', 'c']);
406
+ * console.log(list.at(1)); // 'b';
407
+ * console.log(list.at(2)); // 'c';
642
408
  */
643
-
644
409
  at(index: number): E | undefined {
645
410
  if (index < 0 || index >= this._length) return undefined;
646
411
  let current = this.head;
@@ -653,51 +418,11 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
653
418
  * @remarks Time O(N), Space O(1)
654
419
  * @param index - Zero-based index.
655
420
  * @returns Node or undefined.
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
- * @example
696
- * // Get node at index
697
- * const list = new DoublyLinkedList<string>(['a', 'b', 'c']);
698
- * console.log(list.getNodeAt(1)?.value); // 'b';
421
+ * @example
422
+ * // Get node at index
423
+ * const list = new DoublyLinkedList<string>(['a', 'b', 'c']);
424
+ * console.log(list.getNodeAt(1)?.value); // 'b';
699
425
  */
700
-
701
426
  getNodeAt(index: number): DoublyLinkedListNode<E> | undefined {
702
427
  if (index < 0 || index >= this._length) return undefined;
703
428
  let current = this.head;
@@ -711,21 +436,17 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
711
436
  * @param [elementNodeOrPredicate] - Element, node, or predicate to match.
712
437
  * @returns Matching node or undefined.
713
438
  */
714
-
715
439
  getNode(
716
440
  elementNodeOrPredicate: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean) | undefined
717
441
  ): DoublyLinkedListNode<E> | undefined {
718
442
  if (elementNodeOrPredicate === undefined) return;
719
-
720
443
  if (this.isNode(elementNodeOrPredicate)) {
721
444
  const target = elementNodeOrPredicate;
722
-
723
445
  let cur = this.head;
724
446
  while (cur) {
725
447
  if (cur === target) return target;
726
448
  cur = cur.next;
727
449
  }
728
-
729
450
  const isMatch = (node: DoublyLinkedListNode<E>) => this._equals(node.value, target.value);
730
451
  cur = this.head;
731
452
  while (cur) {
@@ -734,7 +455,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
734
455
  }
735
456
  return undefined;
736
457
  }
737
-
738
458
  const predicate = this._ensurePredicate(elementNodeOrPredicate);
739
459
  let current = this.head;
740
460
  while (current) {
@@ -750,57 +470,16 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
750
470
  * @param index - Zero-based index.
751
471
  * @param newElementOrNode - Element or node to insert.
752
472
  * @returns True if inserted.
753
-
754
-
755
-
756
-
757
-
758
-
759
-
760
-
761
-
762
-
763
-
764
-
765
-
766
-
767
-
768
-
769
-
770
-
771
-
772
-
773
-
774
-
775
-
776
-
777
-
778
-
779
-
780
-
781
-
782
-
783
-
784
-
785
-
786
-
787
-
788
-
789
-
790
-
791
-
792
- * @example
793
- * // Insert at position
794
- * const list = new DoublyLinkedList<number>([1, 3]);
795
- * list.addAt(1, 2);
796
- * console.log(list.toArray()); // [1, 2, 3];
473
+ * @example
474
+ * // Insert at position
475
+ * const list = new DoublyLinkedList<number>([1, 3]);
476
+ * list.addAt(1, 2);
477
+ * console.log(list.toArray()); // [1, 2, 3];
797
478
  */
798
-
799
479
  addAt(index: number, newElementOrNode: E | DoublyLinkedListNode<E>): boolean {
800
480
  if (index < 0 || index > this._length) return false;
801
481
  if (index === 0) return this.unshift(newElementOrNode);
802
482
  if (index === this._length) return this.push(newElementOrNode);
803
-
804
483
  const newNode = this._ensureNode(newElementOrNode);
805
484
  const prevNode = this.getNodeAt(index - 1)!;
806
485
  const nextNode = prevNode.next!;
@@ -819,7 +498,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
819
498
  * @param newElementOrNode - Element or node to insert.
820
499
  * @returns True if inserted.
821
500
  */
822
-
823
501
  addBefore(
824
502
  existingElementOrNode: E | DoublyLinkedListNode<E>,
825
503
  newElementOrNode: E | DoublyLinkedListNode<E>
@@ -828,7 +506,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
828
506
  ? existingElementOrNode
829
507
  : this.getNode(existingElementOrNode);
830
508
  if (!existingNode) return false;
831
-
832
509
  const newNode = this._ensureNode(newElementOrNode);
833
510
  newNode.prev = existingNode.prev;
834
511
  if (existingNode.prev) existingNode.prev.next = newNode;
@@ -846,13 +523,11 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
846
523
  * @param newElementOrNode - Element or node to insert.
847
524
  * @returns True if inserted.
848
525
  */
849
-
850
526
  addAfter(existingElementOrNode: E | DoublyLinkedListNode<E>, newElementOrNode: E | DoublyLinkedListNode<E>): boolean {
851
527
  const existingNode = this.isNode(existingElementOrNode)
852
528
  ? existingElementOrNode
853
529
  : this.getNode(existingElementOrNode);
854
530
  if (!existingNode) return false;
855
-
856
531
  const newNode = this._ensureNode(newElementOrNode);
857
532
  newNode.next = existingNode.next;
858
533
  if (existingNode.next) existingNode.next.prev = newNode;
@@ -870,7 +545,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
870
545
  * @param value - New value.
871
546
  * @returns True if updated.
872
547
  */
873
-
874
548
  setAt(index: number, value: E): boolean {
875
549
  const node = this.getNodeAt(index);
876
550
  if (!node) return false;
@@ -883,57 +557,16 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
883
557
  * @remarks Time O(N), Space O(1)
884
558
  * @param index - Zero-based index.
885
559
  * @returns Removed element or undefined.
886
-
887
-
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
- * @example
926
- * // Remove by index
927
- * const list = new DoublyLinkedList<string>(['a', 'b', 'c']);
928
- * list.deleteAt(1);
929
- * console.log(list.toArray()); // ['a', 'c'];
560
+ * @example
561
+ * // Remove by index
562
+ * const list = new DoublyLinkedList<string>(['a', 'b', 'c']);
563
+ * list.deleteAt(1);
564
+ * console.log(list.toArray()); // ['a', 'c'];
930
565
  */
931
-
932
566
  deleteAt(index: number): E | undefined {
933
567
  if (index < 0 || index >= this._length) return;
934
568
  if (index === 0) return this.shift();
935
569
  if (index === this._length - 1) return this.pop();
936
-
937
570
  const removedNode = this.getNodeAt(index)!;
938
571
  const prevNode = removedNode.prev!;
939
572
  const nextNode = removedNode.next!;
@@ -948,56 +581,15 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
948
581
  * @remarks Time O(N), Space O(1)
949
582
  * @param [elementOrNode] - Element or node to remove.
950
583
  * @returns True if removed.
951
-
952
-
953
-
954
-
955
-
956
-
957
-
958
-
959
-
960
-
961
-
962
-
963
-
964
-
965
-
966
-
967
-
968
-
969
-
970
-
971
-
972
-
973
-
974
-
975
-
976
-
977
-
978
-
979
-
980
-
981
-
982
-
983
-
984
-
985
-
986
-
987
-
988
-
989
-
990
- * @example
991
- * // Remove first occurrence
992
- * const list = new DoublyLinkedList<number>([1, 2, 3, 2]);
993
- * list.delete(2);
994
- * console.log(list.toArray()); // [1, 3, 2];
584
+ * @example
585
+ * // Remove first occurrence
586
+ * const list = new DoublyLinkedList<number>([1, 2, 3, 2]);
587
+ * list.delete(2);
588
+ * console.log(list.toArray()); // [1, 3, 2];
995
589
  */
996
-
997
590
  delete(elementOrNode: E | DoublyLinkedListNode<E> | undefined): boolean {
998
591
  const node = this.getNode(elementOrNode);
999
592
  if (!node) return false;
1000
-
1001
593
  if (node === this.head) this.shift();
1002
594
  else if (node === this.tail) this.pop();
1003
595
  else {
@@ -1014,51 +606,10 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1014
606
  * Check whether the list is empty.
1015
607
  * @remarks Time O(1), Space O(1)
1016
608
  * @returns True if length is 0.
1017
-
1018
-
1019
-
1020
-
1021
-
1022
-
1023
-
1024
-
1025
-
1026
-
1027
-
1028
-
1029
-
1030
-
1031
-
1032
-
1033
-
1034
-
1035
-
1036
-
1037
-
1038
-
1039
-
1040
-
1041
-
1042
-
1043
-
1044
-
1045
-
1046
-
1047
-
1048
-
1049
-
1050
-
1051
-
1052
-
1053
-
1054
-
1055
-
1056
-
1057
- * @example
1058
- * // Check empty
1059
- * console.log(new DoublyLinkedList().isEmpty()); // true;
609
+ * @example
610
+ * // Check empty
611
+ * console.log(new DoublyLinkedList().isEmpty()); // true;
1060
612
  */
1061
-
1062
613
  isEmpty(): boolean {
1063
614
  return this._length === 0;
1064
615
  }
@@ -1067,53 +618,12 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1067
618
  * Remove all nodes and reset length.
1068
619
  * @remarks Time O(N), Space O(1)
1069
620
  * @returns void
1070
-
1071
-
1072
-
1073
-
1074
-
1075
-
1076
-
1077
-
1078
-
1079
-
1080
-
1081
-
1082
-
1083
-
1084
-
1085
-
1086
-
1087
-
1088
-
1089
-
1090
-
1091
-
1092
-
1093
-
1094
-
1095
-
1096
-
1097
-
1098
-
1099
-
1100
-
1101
-
1102
-
1103
-
1104
-
1105
-
1106
-
1107
-
1108
-
1109
-
1110
- * @example
1111
- * // Remove all
1112
- * const list = new DoublyLinkedList<number>([1, 2]);
1113
- * list.clear();
1114
- * console.log(list.isEmpty()); // true;
621
+ * @example
622
+ * // Remove all
623
+ * const list = new DoublyLinkedList<number>([1, 2]);
624
+ * list.clear();
625
+ * console.log(list.isEmpty()); // true;
1115
626
  */
1116
-
1117
627
  clear(): void {
1118
628
  this._head = undefined;
1119
629
  this._tail = undefined;
@@ -1125,52 +635,12 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1125
635
  * @remarks Time O(N), Space O(1)
1126
636
  * @param elementNodeOrPredicate - Element, node, or predicate to match.
1127
637
  * @returns Matched value or undefined.
1128
-
1129
-
1130
-
1131
-
1132
-
1133
-
1134
-
1135
-
1136
-
1137
-
1138
-
1139
-
1140
-
1141
-
1142
-
1143
-
1144
-
1145
-
1146
-
1147
-
1148
-
1149
-
1150
-
1151
-
1152
-
1153
-
1154
-
1155
-
1156
-
1157
-
1158
-
1159
-
1160
-
1161
-
1162
-
1163
-
1164
-
1165
-
1166
-
1167
- * @example
1168
- * // Search with predicate
1169
- * const list = new DoublyLinkedList<number>([10, 20, 30]);
1170
- * const found = list.search(node => node.value > 15);
1171
- * console.log(found); // 20;
638
+ * @example
639
+ * // Search with predicate
640
+ * const list = new DoublyLinkedList<number>([10, 20, 30]);
641
+ * const found = list.search(node => node.value > 15);
642
+ * console.log(found); // 20;
1172
643
  */
1173
-
1174
644
  search(
1175
645
  elementNodeOrPredicate: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)
1176
646
  ): E | undefined {
@@ -1188,50 +658,13 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1188
658
  * @remarks Time O(N), Space O(1)
1189
659
  * @param elementNodeOrPredicate - Element, node, or predicate to match.
1190
660
  * @returns Matched value or undefined.
1191
-
1192
-
1193
-
1194
-
1195
-
1196
-
1197
-
1198
-
1199
-
1200
-
1201
-
1202
-
1203
-
1204
-
1205
-
1206
-
1207
-
1208
-
1209
-
1210
-
1211
-
1212
-
1213
-
1214
-
1215
-
1216
-
1217
-
1218
-
1219
-
1220
-
1221
-
1222
-
1223
-
1224
-
1225
-
1226
-
1227
- * @example
1228
- * // Find value scanning from tail
1229
- * const list = new DoublyLinkedList<number>([1, 2, 3, 4]);
1230
- * // findLast scans from tail to head, returns first match
1231
- * const found = list.findLast(node => node.value < 4);
1232
- * console.log(found); // 3;
661
+ * @example
662
+ * // Find value scanning from tail
663
+ * const list = new DoublyLinkedList<number>([1, 2, 3, 4]);
664
+ * // findLast scans from tail to head, returns first match
665
+ * const found = list.findLast(node => node.value < 4);
666
+ * console.log(found); // 3;
1233
667
  */
1234
-
1235
668
  /**
1236
669
  * @deprecated Use `findLast` instead. Will be removed in a future major version.
1237
670
  */
@@ -1246,14 +679,12 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1246
679
  * @remarks Time O(N), Space O(1)
1247
680
  * @param elementNodeOrPredicate - Element, node, or predicate to match.
1248
681
  * @returns Matching value or undefined.
1249
-
1250
-
1251
- * @example
1252
- * // Find value scanning from tail
1253
- * const list = new DoublyLinkedList<number>([1, 2, 3, 4]);
1254
- * // findLast scans from tail to head, returns first match
1255
- * const found = list.findLast(node => node.value < 4);
1256
- * console.log(found); // 3;
682
+ * @example
683
+ * // Find value scanning from tail
684
+ * const list = new DoublyLinkedList<number>([1, 2, 3, 4]);
685
+ * // findLast scans from tail to head, returns first match
686
+ * const found = list.findLast(node => node.value < 4);
687
+ * console.log(found); // 3;
1257
688
  */
1258
689
  findLast(
1259
690
  elementNodeOrPredicate: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)
@@ -1288,55 +719,12 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1288
719
  * Reverse the list in place.
1289
720
  * @remarks Time O(N), Space O(1)
1290
721
  * @returns This list.
1291
-
1292
-
1293
-
1294
-
1295
-
1296
-
1297
-
1298
-
1299
-
1300
-
1301
-
1302
-
1303
-
1304
-
1305
-
1306
-
1307
-
1308
-
1309
-
1310
-
1311
-
1312
-
1313
-
1314
-
1315
-
1316
-
1317
-
1318
-
1319
-
1320
-
1321
-
1322
-
1323
-
1324
-
1325
-
1326
-
1327
-
1328
-
1329
-
1330
-
1331
-
1332
-
1333
- * @example
1334
- * // Reverse in-place
1335
- * const list = new DoublyLinkedList<number>([1, 2, 3]);
1336
- * list.reverse();
1337
- * console.log([...list]); // [3, 2, 1];
722
+ * @example
723
+ * // Reverse in-place
724
+ * const list = new DoublyLinkedList<number>([1, 2, 3]);
725
+ * list.reverse();
726
+ * console.log([...list]); // [3, 2, 1];
1338
727
  */
1339
-
1340
728
  reverse(): this {
1341
729
  let current = this.head;
1342
730
  [this._head, this._tail] = [this.tail, this.head];
@@ -1374,7 +762,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1374
762
  * @param equals - Equality predicate (a, b) → boolean.
1375
763
  * @returns This list.
1376
764
  */
1377
-
1378
765
  setEquality(equals: (a: E, b: E) => boolean): this {
1379
766
  this._equals = equals;
1380
767
  return this;
@@ -1384,54 +771,13 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1384
771
  * Deep clone this list (values are copied by reference).
1385
772
  * @remarks Time O(N), Space O(N)
1386
773
  * @returns A new list with the same element sequence.
1387
-
1388
-
1389
-
1390
-
1391
-
1392
-
1393
-
1394
-
1395
-
1396
-
1397
-
1398
-
1399
-
1400
-
1401
-
1402
-
1403
-
1404
-
1405
-
1406
-
1407
-
1408
-
1409
-
1410
-
1411
-
1412
-
1413
-
1414
-
1415
-
1416
-
1417
-
1418
-
1419
-
1420
-
1421
-
1422
-
1423
-
1424
-
1425
-
1426
-
1427
- * @example
1428
- * // Deep copy
1429
- * const list = new DoublyLinkedList<number>([1, 2, 3]);
1430
- * const copy = list.clone();
1431
- * copy.pop();
1432
- * console.log(list.length); // 3;
774
+ * @example
775
+ * // Deep copy
776
+ * const list = new DoublyLinkedList<number>([1, 2, 3]);
777
+ * const copy = list.clone();
778
+ * copy.pop();
779
+ * console.log(list.length); // 3;
1433
780
  */
1434
-
1435
781
  clone(): this {
1436
782
  const out = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
1437
783
  for (const v of this) out.push(v);
@@ -1444,55 +790,12 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1444
790
  * @param callback - Predicate (value, index, list) → boolean to keep value.
1445
791
  * @param [thisArg] - Value for `this` inside the callback.
1446
792
  * @returns A new list with kept values.
1447
-
1448
-
1449
-
1450
-
1451
-
1452
-
1453
-
1454
-
1455
-
1456
-
1457
-
1458
-
1459
-
1460
-
1461
-
1462
-
1463
-
1464
-
1465
-
1466
-
1467
-
1468
-
1469
-
1470
-
1471
-
1472
-
1473
-
1474
-
1475
-
1476
-
1477
-
1478
-
1479
-
1480
-
1481
-
1482
-
1483
-
1484
-
1485
-
1486
-
1487
-
1488
-
1489
- * @example
1490
- * // Filter elements
1491
- * const list = new DoublyLinkedList<number>([1, 2, 3, 4, 5]);
1492
- * const evens = list.filter(n => n % 2 === 0);
1493
- * console.log([...evens]); // [2, 4];
793
+ * @example
794
+ * // Filter elements
795
+ * const list = new DoublyLinkedList<number>([1, 2, 3, 4, 5]);
796
+ * const evens = list.filter(n => n % 2 === 0);
797
+ * console.log([...evens]); // [2, 4];
1494
798
  */
1495
-
1496
799
  filter(callback: ElementCallback<E, R, boolean>, thisArg?: unknown): this {
1497
800
  const out = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
1498
801
  let index = 0;
@@ -1507,7 +810,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1507
810
  * @param [thisArg] - Value for `this` inside the callback.
1508
811
  * @returns A new list with mapped values.
1509
812
  */
1510
-
1511
813
  mapSame(callback: ElementCallback<E, R, E>, thisArg?: unknown): this {
1512
814
  const out = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
1513
815
  let index = 0;
@@ -1527,64 +829,21 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1527
829
  * @param [options] - Options for the output list (e.g., maxLen, toElementFn).
1528
830
  * @param [thisArg] - Value for `this` inside the callback.
1529
831
  * @returns A new DoublyLinkedList with mapped values.
1530
-
1531
-
1532
-
1533
-
1534
-
1535
-
1536
-
1537
-
1538
-
1539
-
1540
-
1541
-
1542
-
1543
-
1544
-
1545
-
1546
-
1547
-
1548
-
1549
-
1550
-
1551
-
1552
-
1553
-
1554
-
1555
-
1556
-
1557
-
1558
-
1559
-
1560
-
1561
-
1562
-
1563
-
1564
-
1565
-
1566
-
1567
-
1568
-
1569
-
1570
-
1571
-
1572
- * @example
1573
- * // DoublyLinkedList for...of iteration and map operation
1574
- * const list = new DoublyLinkedList<number>([1, 2, 3, 4, 5]);
1575
- *
1576
- * // Iterate through list
1577
- * const doubled = list.map(value => value * 2);
1578
- * console.log(doubled.length); // 5;
1579
- *
1580
- * // Use for...of loop
1581
- * const result: number[] = [];
1582
- * for (const item of list) {
1583
- * result.push(item);
1584
- * }
1585
- * console.log(result); // [1, 2, 3, 4, 5];
832
+ * @example
833
+ * // DoublyLinkedList for...of iteration and map operation
834
+ * const list = new DoublyLinkedList<number>([1, 2, 3, 4, 5]);
835
+ *
836
+ * // Iterate through list
837
+ * const doubled = list.map(value => value * 2);
838
+ * console.log(doubled.length); // 5;
839
+ *
840
+ * // Use for...of loop
841
+ * const result: number[] = [];
842
+ * for (const item of list) {
843
+ * result.push(item);
844
+ * }
845
+ * console.log(result); // [1, 2, 3, 4, 5];
1586
846
  */
1587
-
1588
847
  map<EM, RM>(
1589
848
  callback: ElementCallback<E, R, EM>,
1590
849
  options?: DoublyLinkedListOptions<EM, RM>,
@@ -1596,13 +855,14 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1596
855
  return out;
1597
856
  }
1598
857
 
858
+ protected _equals: (a: E, b: E) => boolean = (a, b) => Object.is(a, b);
859
+
1599
860
  /**
1600
861
  * (Protected) Create or return a node for the given input (node or raw element).
1601
862
  * @remarks Time O(1), Space O(1)
1602
863
  * @param elementOrNode - Element value or node to normalize.
1603
864
  * @returns A DoublyLinkedListNode for the provided input.
1604
865
  */
1605
-
1606
866
  protected _ensureNode(elementOrNode: E | DoublyLinkedListNode<E>) {
1607
867
  if (this.isNode(elementOrNode)) return elementOrNode;
1608
868
  return new DoublyLinkedListNode<E>(elementOrNode);
@@ -1614,7 +874,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1614
874
  * @param elementNodeOrPredicate - Element, node, or node predicate.
1615
875
  * @returns A predicate function taking a node and returning true/false.
1616
876
  */
1617
-
1618
877
  protected _ensurePredicate(
1619
878
  elementNodeOrPredicate: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)
1620
879
  ): (node: DoublyLinkedListNode<E>) => boolean {
@@ -1635,7 +894,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1635
894
  * @param node - A node in the list.
1636
895
  * @returns Previous node or undefined.
1637
896
  */
1638
-
1639
897
  protected _getPrevNode(node: DoublyLinkedListNode<E>): DoublyLinkedListNode<E> | undefined {
1640
898
  return node.prev;
1641
899
  }
@@ -1646,7 +904,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1646
904
  * @param [options] - Options forwarded to the constructor.
1647
905
  * @returns An empty like-kind list instance.
1648
906
  */
1649
-
1650
907
  protected override _createInstance(options?: LinearBaseOptions<E, R>): this {
1651
908
  const Ctor = this.constructor as new (
1652
909
  elements?: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>,
@@ -1664,7 +921,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1664
921
  * @param [options] - Options forwarded to the constructor.
1665
922
  * @returns A like-kind DoublyLinkedList instance.
1666
923
  */
1667
-
1668
924
  protected _createLike<EM = E, RM = R>(
1669
925
  elements: Iterable<EM> | Iterable<RM> | Iterable<DoublyLinkedListNode<EM>> = [],
1670
926
  options?: DoublyLinkedListOptions<EM, RM>