data-structure-typed 2.5.3 → 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 (158) hide show
  1. package/.github/workflows/ci.yml +7 -2
  2. package/.github/workflows/release-package.yml +9 -2
  3. package/.husky/pre-commit +3 -0
  4. package/CHANGELOG.md +1 -1
  5. package/MIGRATION.md +48 -0
  6. package/README.md +20 -2
  7. package/README_CN.md +20 -2
  8. package/SPECIFICATION.md +24 -0
  9. package/SPECIFICATION.zh-CN.md +24 -0
  10. package/dist/cjs/binary-tree.cjs +1897 -19
  11. package/dist/cjs/graph.cjs +174 -0
  12. package/dist/cjs/hash.cjs +33 -0
  13. package/dist/cjs/heap.cjs +71 -0
  14. package/dist/cjs/index.cjs +2383 -3
  15. package/dist/cjs/linked-list.cjs +224 -2
  16. package/dist/cjs/matrix.cjs +24 -0
  17. package/dist/cjs/priority-queue.cjs +71 -0
  18. package/dist/cjs/queue.cjs +221 -1
  19. package/dist/cjs/stack.cjs +59 -0
  20. package/dist/cjs/trie.cjs +62 -0
  21. package/dist/cjs-legacy/binary-tree.cjs +1897 -19
  22. package/dist/cjs-legacy/graph.cjs +174 -0
  23. package/dist/cjs-legacy/hash.cjs +33 -0
  24. package/dist/cjs-legacy/heap.cjs +71 -0
  25. package/dist/cjs-legacy/index.cjs +2383 -3
  26. package/dist/cjs-legacy/linked-list.cjs +224 -2
  27. package/dist/cjs-legacy/matrix.cjs +24 -0
  28. package/dist/cjs-legacy/priority-queue.cjs +71 -0
  29. package/dist/cjs-legacy/queue.cjs +221 -1
  30. package/dist/cjs-legacy/stack.cjs +59 -0
  31. package/dist/cjs-legacy/trie.cjs +62 -0
  32. package/dist/esm/binary-tree.mjs +1897 -19
  33. package/dist/esm/graph.mjs +174 -0
  34. package/dist/esm/hash.mjs +33 -0
  35. package/dist/esm/heap.mjs +71 -0
  36. package/dist/esm/index.mjs +2383 -3
  37. package/dist/esm/linked-list.mjs +224 -2
  38. package/dist/esm/matrix.mjs +24 -0
  39. package/dist/esm/priority-queue.mjs +71 -0
  40. package/dist/esm/queue.mjs +221 -1
  41. package/dist/esm/stack.mjs +59 -0
  42. package/dist/esm/trie.mjs +62 -0
  43. package/dist/esm-legacy/binary-tree.mjs +1897 -19
  44. package/dist/esm-legacy/graph.mjs +174 -0
  45. package/dist/esm-legacy/hash.mjs +33 -0
  46. package/dist/esm-legacy/heap.mjs +71 -0
  47. package/dist/esm-legacy/index.mjs +2383 -3
  48. package/dist/esm-legacy/linked-list.mjs +224 -2
  49. package/dist/esm-legacy/matrix.mjs +24 -0
  50. package/dist/esm-legacy/priority-queue.mjs +71 -0
  51. package/dist/esm-legacy/queue.mjs +221 -1
  52. package/dist/esm-legacy/stack.mjs +59 -0
  53. package/dist/esm-legacy/trie.mjs +62 -0
  54. package/dist/types/data-structures/base/iterable-element-base.d.ts +17 -0
  55. package/dist/types/data-structures/base/linear-base.d.ts +6 -0
  56. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +36 -0
  57. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +42 -0
  58. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +75 -0
  59. package/dist/types/data-structures/binary-tree/bst.d.ts +72 -0
  60. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +57 -0
  61. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +18 -0
  62. package/dist/types/data-structures/binary-tree/tree-map.d.ts +375 -0
  63. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +389 -0
  64. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +330 -0
  65. package/dist/types/data-structures/binary-tree/tree-set.d.ts +438 -0
  66. package/dist/types/data-structures/graph/directed-graph.d.ts +30 -0
  67. package/dist/types/data-structures/graph/undirected-graph.d.ts +27 -0
  68. package/dist/types/data-structures/hash/hash-map.d.ts +33 -0
  69. package/dist/types/data-structures/heap/heap.d.ts +42 -0
  70. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +75 -2
  71. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +45 -0
  72. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +54 -0
  73. package/dist/types/data-structures/matrix/matrix.d.ts +24 -0
  74. package/dist/types/data-structures/queue/deque.d.ts +90 -1
  75. package/dist/types/data-structures/queue/queue.d.ts +36 -0
  76. package/dist/types/data-structures/stack/stack.d.ts +30 -0
  77. package/dist/types/data-structures/trie/trie.d.ts +36 -0
  78. package/dist/umd/data-structure-typed.js +2383 -3
  79. package/dist/umd/data-structure-typed.min.js +3 -3
  80. package/docs-site-docusaurus/docs/api/classes/AVLTree.md +108 -108
  81. package/docs-site-docusaurus/docs/api/classes/BST.md +101 -101
  82. package/docs-site-docusaurus/docs/api/classes/BinaryIndexedTree.md +13 -13
  83. package/docs-site-docusaurus/docs/api/classes/BinaryTree.md +66 -66
  84. package/docs-site-docusaurus/docs/api/classes/Deque.md +235 -51
  85. package/docs-site-docusaurus/docs/api/classes/DirectedGraph.md +21 -21
  86. package/docs-site-docusaurus/docs/api/classes/DoublyLinkedList.md +231 -67
  87. package/docs-site-docusaurus/docs/api/classes/FibonacciHeap.md +9 -9
  88. package/docs-site-docusaurus/docs/api/classes/FibonacciHeapNode.md +1 -1
  89. package/docs-site-docusaurus/docs/api/classes/HashMap.md +14 -14
  90. package/docs-site-docusaurus/docs/api/classes/Heap.md +117 -34
  91. package/docs-site-docusaurus/docs/api/classes/IterableElementBase.md +83 -13
  92. package/docs-site-docusaurus/docs/api/classes/LinearBase.md +124 -20
  93. package/docs-site-docusaurus/docs/api/classes/LinearLinkedBase.md +140 -32
  94. package/docs-site-docusaurus/docs/api/classes/LinkedHashMap.md +30 -26
  95. package/docs-site-docusaurus/docs/api/classes/LinkedListQueue.md +159 -51
  96. package/docs-site-docusaurus/docs/api/classes/MapGraph.md +20 -20
  97. package/docs-site-docusaurus/docs/api/classes/Matrix.md +23 -23
  98. package/docs-site-docusaurus/docs/api/classes/MaxHeap.md +117 -34
  99. package/docs-site-docusaurus/docs/api/classes/MaxPriorityQueue.md +117 -34
  100. package/docs-site-docusaurus/docs/api/classes/MinHeap.md +117 -34
  101. package/docs-site-docusaurus/docs/api/classes/MinPriorityQueue.md +117 -34
  102. package/docs-site-docusaurus/docs/api/classes/PriorityQueue.md +117 -34
  103. package/docs-site-docusaurus/docs/api/classes/Queue.md +142 -34
  104. package/docs-site-docusaurus/docs/api/classes/RedBlackTree.md +117 -117
  105. package/docs-site-docusaurus/docs/api/classes/SegmentTree.md +8 -8
  106. package/docs-site-docusaurus/docs/api/classes/SinglyLinkedList.md +158 -50
  107. package/docs-site-docusaurus/docs/api/classes/SkipList.md +21 -21
  108. package/docs-site-docusaurus/docs/api/classes/Stack.md +108 -26
  109. package/docs-site-docusaurus/docs/api/classes/TreeMap.md +33 -33
  110. package/docs-site-docusaurus/docs/api/classes/TreeMultiMap.md +75 -39
  111. package/docs-site-docusaurus/docs/api/classes/TreeSet.md +301 -39
  112. package/docs-site-docusaurus/docs/api/classes/Trie.md +110 -28
  113. package/docs-site-docusaurus/docs/api/classes/UndirectedGraph.md +20 -20
  114. package/jest.integration.config.js +1 -2
  115. package/package.json +51 -50
  116. package/src/common/error.ts +15 -32
  117. package/src/common/index.ts +0 -3
  118. package/src/data-structures/base/iterable-element-base.ts +32 -3
  119. package/src/data-structures/base/linear-base.ts +13 -36
  120. package/src/data-structures/binary-tree/avl-tree.ts +31 -493
  121. package/src/data-structures/binary-tree/binary-indexed-tree.ts +47 -530
  122. package/src/data-structures/binary-tree/binary-tree.ts +326 -1236
  123. package/src/data-structures/binary-tree/bst.ts +158 -1010
  124. package/src/data-structures/binary-tree/red-black-tree.ts +451 -1233
  125. package/src/data-structures/binary-tree/segment-tree.ts +73 -333
  126. package/src/data-structures/binary-tree/tree-map.ts +462 -4749
  127. package/src/data-structures/binary-tree/tree-multi-map.ts +310 -4530
  128. package/src/data-structures/binary-tree/tree-multi-set.ts +300 -3652
  129. package/src/data-structures/binary-tree/tree-set.ts +437 -4443
  130. package/src/data-structures/graph/abstract-graph.ts +98 -167
  131. package/src/data-structures/graph/directed-graph.ts +137 -532
  132. package/src/data-structures/graph/map-graph.ts +0 -3
  133. package/src/data-structures/graph/undirected-graph.ts +132 -484
  134. package/src/data-structures/hash/hash-map.ts +154 -549
  135. package/src/data-structures/heap/heap.ts +200 -753
  136. package/src/data-structures/linked-list/doubly-linked-list.ts +153 -809
  137. package/src/data-structures/linked-list/singly-linked-list.ts +122 -749
  138. package/src/data-structures/linked-list/skip-linked-list.ts +211 -864
  139. package/src/data-structures/matrix/matrix.ts +179 -494
  140. package/src/data-structures/matrix/navigator.ts +0 -1
  141. package/src/data-structures/priority-queue/max-priority-queue.ts +1 -6
  142. package/src/data-structures/priority-queue/min-priority-queue.ts +6 -11
  143. package/src/data-structures/priority-queue/priority-queue.ts +1 -2
  144. package/src/data-structures/queue/deque.ts +241 -807
  145. package/src/data-structures/queue/queue.ts +102 -589
  146. package/src/data-structures/stack/stack.ts +76 -475
  147. package/src/data-structures/trie/trie.ts +98 -592
  148. package/src/types/common.ts +0 -10
  149. package/src/types/data-structures/binary-tree/bst.ts +0 -7
  150. package/src/types/data-structures/binary-tree/red-black-tree.ts +0 -1
  151. package/src/types/data-structures/graph/abstract-graph.ts +0 -2
  152. package/src/types/data-structures/hash/hash-map.ts +0 -3
  153. package/src/types/data-structures/hash/index.ts +0 -1
  154. package/src/types/data-structures/matrix/navigator.ts +0 -2
  155. package/src/types/utils/utils.ts +0 -7
  156. package/src/types/utils/validate-type.ts +0 -7
  157. package/src/utils/number.ts +0 -2
  158. 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,62 +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
- * @example
311
- * // basic DoublyLinkedList creation and push operation
312
- * // Create a simple DoublyLinkedList with initial values
313
- * const list = new DoublyLinkedList([1, 2, 3, 4, 5]);
314
- *
315
- * // Verify the list maintains insertion order
316
- * console.log([...list]); // [1, 2, 3, 4, 5];
317
- *
318
- * // Check length
319
- * console.log(list.length); // 5;
320
- *
321
- * // Push a new element to the end
322
- * list.push(6);
323
- * console.log(list.length); // 6;
324
- * 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];
325
268
  */
326
-
327
269
  push(elementOrNode: E | DoublyLinkedListNode<E>): boolean {
328
270
  const newNode = this._ensureNode(elementOrNode);
329
271
  if (!this.head) {
@@ -343,62 +285,22 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
343
285
  * Remove and return the tail element.
344
286
  * @remarks Time O(1), Space O(1)
345
287
  * @returns Removed element or undefined.
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
- * @example
386
- * // DoublyLinkedList pop and shift operations
387
- * const list = new DoublyLinkedList<number>([10, 20, 30, 40, 50]);
388
- *
389
- * // Pop removes from the end
390
- * const last = list.pop();
391
- * console.log(last); // 50;
392
- *
393
- * // Shift removes from the beginning
394
- * const first = list.shift();
395
- * console.log(first); // 10;
396
- *
397
- * // Verify remaining elements
398
- * console.log([...list]); // [20, 30, 40];
399
- * 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;
400
303
  */
401
-
402
304
  pop(): E | undefined {
403
305
  if (!this.tail) return undefined;
404
306
  const removed = this.tail;
@@ -417,52 +319,12 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
417
319
  * Remove and return the head element.
418
320
  * @remarks Time O(1), Space O(1)
419
321
  * @returns Removed element or undefined.
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
-
457
-
458
-
459
- * @example
460
- * // Remove from the front
461
- * const list = new DoublyLinkedList<number>([10, 20, 30]);
462
- * console.log(list.shift()); // 10;
463
- * 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;
464
327
  */
465
-
466
328
  shift(): E | undefined {
467
329
  if (!this.head) return undefined;
468
330
  const removed = this.head;
@@ -482,52 +344,12 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
482
344
  * @remarks Time O(1), Space O(1)
483
345
  * @param elementOrNode - Element or node to prepend.
484
346
  * @returns True when prepended.
485
-
486
-
487
-
488
-
489
-
490
-
491
-
492
-
493
-
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
- * @example
525
- * // Add to the front
526
- * const list = new DoublyLinkedList<number>([2, 3]);
527
- * list.unshift(1);
528
- * 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];
529
352
  */
530
-
531
353
  unshift(elementOrNode: E | DoublyLinkedListNode<E>): boolean {
532
354
  const newNode = this._ensureNode(elementOrNode);
533
355
  if (!this.head) {
@@ -549,7 +371,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
549
371
  * @param elements - Iterable of elements or nodes (or raw records if toElementFn is provided).
550
372
  * @returns Array of per-element success flags.
551
373
  */
552
-
553
374
  pushMany(elements: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>): boolean[] {
554
375
  const ans: boolean[] = [];
555
376
  for (const el of elements) {
@@ -565,7 +386,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
565
386
  * @param elements - Iterable of elements or nodes (or raw records if toElementFn is provided).
566
387
  * @returns Array of per-element success flags.
567
388
  */
568
-
569
389
  unshiftMany(elements: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>): boolean[] {
570
390
  const ans: boolean[] = [];
571
391
  for (const el of elements) {
@@ -580,52 +400,12 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
580
400
  * @remarks Time O(N), Space O(1)
581
401
  * @param index - Zero-based index.
582
402
  * @returns Element or undefined.
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
- * @example
623
- * // Access by index
624
- * const list = new DoublyLinkedList<string>(['a', 'b', 'c']);
625
- * console.log(list.at(1)); // 'b';
626
- * 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';
627
408
  */
628
-
629
409
  at(index: number): E | undefined {
630
410
  if (index < 0 || index >= this._length) return undefined;
631
411
  let current = this.head;
@@ -638,48 +418,11 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
638
418
  * @remarks Time O(N), Space O(1)
639
419
  * @param index - Zero-based index.
640
420
  * @returns Node or undefined.
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
-
668
-
669
-
670
-
671
-
672
-
673
-
674
-
675
-
676
-
677
- * @example
678
- * // Get node at index
679
- * const list = new DoublyLinkedList<string>(['a', 'b', 'c']);
680
- * 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';
681
425
  */
682
-
683
426
  getNodeAt(index: number): DoublyLinkedListNode<E> | undefined {
684
427
  if (index < 0 || index >= this._length) return undefined;
685
428
  let current = this.head;
@@ -693,21 +436,17 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
693
436
  * @param [elementNodeOrPredicate] - Element, node, or predicate to match.
694
437
  * @returns Matching node or undefined.
695
438
  */
696
-
697
439
  getNode(
698
440
  elementNodeOrPredicate: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean) | undefined
699
441
  ): DoublyLinkedListNode<E> | undefined {
700
442
  if (elementNodeOrPredicate === undefined) return;
701
-
702
443
  if (this.isNode(elementNodeOrPredicate)) {
703
444
  const target = elementNodeOrPredicate;
704
-
705
445
  let cur = this.head;
706
446
  while (cur) {
707
447
  if (cur === target) return target;
708
448
  cur = cur.next;
709
449
  }
710
-
711
450
  const isMatch = (node: DoublyLinkedListNode<E>) => this._equals(node.value, target.value);
712
451
  cur = this.head;
713
452
  while (cur) {
@@ -716,7 +455,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
716
455
  }
717
456
  return undefined;
718
457
  }
719
-
720
458
  const predicate = this._ensurePredicate(elementNodeOrPredicate);
721
459
  let current = this.head;
722
460
  while (current) {
@@ -732,54 +470,16 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
732
470
  * @param index - Zero-based index.
733
471
  * @param newElementOrNode - Element or node to insert.
734
472
  * @returns True if inserted.
735
-
736
-
737
-
738
-
739
-
740
-
741
-
742
-
743
-
744
-
745
-
746
-
747
-
748
-
749
-
750
-
751
-
752
-
753
-
754
-
755
-
756
-
757
-
758
-
759
-
760
-
761
-
762
-
763
-
764
-
765
-
766
-
767
-
768
-
769
-
770
-
771
- * @example
772
- * // Insert at position
773
- * const list = new DoublyLinkedList<number>([1, 3]);
774
- * list.addAt(1, 2);
775
- * 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];
776
478
  */
777
-
778
479
  addAt(index: number, newElementOrNode: E | DoublyLinkedListNode<E>): boolean {
779
480
  if (index < 0 || index > this._length) return false;
780
481
  if (index === 0) return this.unshift(newElementOrNode);
781
482
  if (index === this._length) return this.push(newElementOrNode);
782
-
783
483
  const newNode = this._ensureNode(newElementOrNode);
784
484
  const prevNode = this.getNodeAt(index - 1)!;
785
485
  const nextNode = prevNode.next!;
@@ -798,7 +498,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
798
498
  * @param newElementOrNode - Element or node to insert.
799
499
  * @returns True if inserted.
800
500
  */
801
-
802
501
  addBefore(
803
502
  existingElementOrNode: E | DoublyLinkedListNode<E>,
804
503
  newElementOrNode: E | DoublyLinkedListNode<E>
@@ -807,7 +506,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
807
506
  ? existingElementOrNode
808
507
  : this.getNode(existingElementOrNode);
809
508
  if (!existingNode) return false;
810
-
811
509
  const newNode = this._ensureNode(newElementOrNode);
812
510
  newNode.prev = existingNode.prev;
813
511
  if (existingNode.prev) existingNode.prev.next = newNode;
@@ -825,13 +523,11 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
825
523
  * @param newElementOrNode - Element or node to insert.
826
524
  * @returns True if inserted.
827
525
  */
828
-
829
526
  addAfter(existingElementOrNode: E | DoublyLinkedListNode<E>, newElementOrNode: E | DoublyLinkedListNode<E>): boolean {
830
527
  const existingNode = this.isNode(existingElementOrNode)
831
528
  ? existingElementOrNode
832
529
  : this.getNode(existingElementOrNode);
833
530
  if (!existingNode) return false;
834
-
835
531
  const newNode = this._ensureNode(newElementOrNode);
836
532
  newNode.next = existingNode.next;
837
533
  if (existingNode.next) existingNode.next.prev = newNode;
@@ -849,7 +545,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
849
545
  * @param value - New value.
850
546
  * @returns True if updated.
851
547
  */
852
-
853
548
  setAt(index: number, value: E): boolean {
854
549
  const node = this.getNodeAt(index);
855
550
  if (!node) return false;
@@ -862,54 +557,16 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
862
557
  * @remarks Time O(N), Space O(1)
863
558
  * @param index - Zero-based index.
864
559
  * @returns Removed element or undefined.
865
-
866
-
867
-
868
-
869
-
870
-
871
-
872
-
873
-
874
-
875
-
876
-
877
-
878
-
879
-
880
-
881
-
882
-
883
-
884
-
885
-
886
-
887
-
888
-
889
-
890
-
891
-
892
-
893
-
894
-
895
-
896
-
897
-
898
-
899
-
900
-
901
- * @example
902
- * // Remove by index
903
- * const list = new DoublyLinkedList<string>(['a', 'b', 'c']);
904
- * list.deleteAt(1);
905
- * 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'];
906
565
  */
907
-
908
566
  deleteAt(index: number): E | undefined {
909
567
  if (index < 0 || index >= this._length) return;
910
568
  if (index === 0) return this.shift();
911
569
  if (index === this._length - 1) return this.pop();
912
-
913
570
  const removedNode = this.getNodeAt(index)!;
914
571
  const prevNode = removedNode.prev!;
915
572
  const nextNode = removedNode.next!;
@@ -924,53 +581,15 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
924
581
  * @remarks Time O(N), Space O(1)
925
582
  * @param [elementOrNode] - Element or node to remove.
926
583
  * @returns True if removed.
927
-
928
-
929
-
930
-
931
-
932
-
933
-
934
-
935
-
936
-
937
-
938
-
939
-
940
-
941
-
942
-
943
-
944
-
945
-
946
-
947
-
948
-
949
-
950
-
951
-
952
-
953
-
954
-
955
-
956
-
957
-
958
-
959
-
960
-
961
-
962
-
963
- * @example
964
- * // Remove first occurrence
965
- * const list = new DoublyLinkedList<number>([1, 2, 3, 2]);
966
- * list.delete(2);
967
- * 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];
968
589
  */
969
-
970
590
  delete(elementOrNode: E | DoublyLinkedListNode<E> | undefined): boolean {
971
591
  const node = this.getNode(elementOrNode);
972
592
  if (!node) return false;
973
-
974
593
  if (node === this.head) this.shift();
975
594
  else if (node === this.tail) this.pop();
976
595
  else {
@@ -987,48 +606,10 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
987
606
  * Check whether the list is empty.
988
607
  * @remarks Time O(1), Space O(1)
989
608
  * @returns True if length is 0.
990
-
991
-
992
-
993
-
994
-
995
-
996
-
997
-
998
-
999
-
1000
-
1001
-
1002
-
1003
-
1004
-
1005
-
1006
-
1007
-
1008
-
1009
-
1010
-
1011
-
1012
-
1013
-
1014
-
1015
-
1016
-
1017
-
1018
-
1019
-
1020
-
1021
-
1022
-
1023
-
1024
-
1025
-
1026
-
1027
- * @example
1028
- * // Check empty
1029
- * console.log(new DoublyLinkedList().isEmpty()); // true;
609
+ * @example
610
+ * // Check empty
611
+ * console.log(new DoublyLinkedList().isEmpty()); // true;
1030
612
  */
1031
-
1032
613
  isEmpty(): boolean {
1033
614
  return this._length === 0;
1034
615
  }
@@ -1037,50 +618,12 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1037
618
  * Remove all nodes and reset length.
1038
619
  * @remarks Time O(N), Space O(1)
1039
620
  * @returns void
1040
-
1041
-
1042
-
1043
-
1044
-
1045
-
1046
-
1047
-
1048
-
1049
-
1050
-
1051
-
1052
-
1053
-
1054
-
1055
-
1056
-
1057
-
1058
-
1059
-
1060
-
1061
-
1062
-
1063
-
1064
-
1065
-
1066
-
1067
-
1068
-
1069
-
1070
-
1071
-
1072
-
1073
-
1074
-
1075
-
1076
-
1077
- * @example
1078
- * // Remove all
1079
- * const list = new DoublyLinkedList<number>([1, 2]);
1080
- * list.clear();
1081
- * 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;
1082
626
  */
1083
-
1084
627
  clear(): void {
1085
628
  this._head = undefined;
1086
629
  this._tail = undefined;
@@ -1092,49 +635,12 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1092
635
  * @remarks Time O(N), Space O(1)
1093
636
  * @param elementNodeOrPredicate - Element, node, or predicate to match.
1094
637
  * @returns Matched value or undefined.
1095
-
1096
-
1097
-
1098
-
1099
-
1100
-
1101
-
1102
-
1103
-
1104
-
1105
-
1106
-
1107
-
1108
-
1109
-
1110
-
1111
-
1112
-
1113
-
1114
-
1115
-
1116
-
1117
-
1118
-
1119
-
1120
-
1121
-
1122
-
1123
-
1124
-
1125
-
1126
-
1127
-
1128
-
1129
-
1130
-
1131
- * @example
1132
- * // Search with predicate
1133
- * const list = new DoublyLinkedList<number>([10, 20, 30]);
1134
- * const found = list.search(node => node.value > 15);
1135
- * 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;
1136
643
  */
1137
-
1138
644
  search(
1139
645
  elementNodeOrPredicate: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)
1140
646
  ): E | undefined {
@@ -1152,52 +658,36 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1152
658
  * @remarks Time O(N), Space O(1)
1153
659
  * @param elementNodeOrPredicate - Element, node, or predicate to match.
1154
660
  * @returns Matched value or undefined.
1155
-
1156
-
1157
-
1158
-
1159
-
1160
-
1161
-
1162
-
1163
-
1164
-
1165
-
1166
-
1167
-
1168
-
1169
-
1170
-
1171
-
1172
-
1173
-
1174
-
1175
-
1176
-
1177
-
1178
-
1179
-
1180
-
1181
-
1182
-
1183
-
1184
-
1185
-
1186
-
1187
-
1188
-
1189
-
1190
-
1191
- * @example
1192
- * // Find value scanning from tail
1193
- * const list = new DoublyLinkedList<number>([1, 2, 3, 4]);
1194
- * // getBackward scans from tail to head, returns first match
1195
- * const found = list.getBackward(node => node.value < 4);
1196
- * 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;
667
+ */
668
+ /**
669
+ * @deprecated Use `findLast` instead. Will be removed in a future major version.
1197
670
  */
1198
-
1199
671
  getBackward(
1200
672
  elementNodeOrPredicate: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)
673
+ ): E | undefined {
674
+ return this.findLast(elementNodeOrPredicate);
675
+ }
676
+
677
+ /**
678
+ * Find the first value matching a predicate scanning backward (tail → head).
679
+ * @remarks Time O(N), Space O(1)
680
+ * @param elementNodeOrPredicate - Element, node, or predicate to match.
681
+ * @returns Matching value or undefined.
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;
688
+ */
689
+ findLast(
690
+ elementNodeOrPredicate: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)
1201
691
  ): E | undefined {
1202
692
  const predicate = this._ensurePredicate(elementNodeOrPredicate);
1203
693
  let current = this.tail;
@@ -1208,56 +698,33 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1208
698
  return undefined;
1209
699
  }
1210
700
 
701
+ /**
702
+ * Find the index of the last value matching a predicate (scans tail → head).
703
+ * @remarks Provided for familiarity when migrating from Array. Time O(n), Space O(1).
704
+ * @param predicate - Function called with (value, index, list).
705
+ * @returns Matching index, or -1 if not found.
706
+ */
707
+ findLastIndex(predicate: (value: E, index: number, list: this) => boolean): number {
708
+ let current = this.tail;
709
+ let index = this.length - 1;
710
+ while (current) {
711
+ if (predicate(current.value, index, this)) return index;
712
+ current = current.prev;
713
+ index--;
714
+ }
715
+ return -1;
716
+ }
717
+
1211
718
  /**
1212
719
  * Reverse the list in place.
1213
720
  * @remarks Time O(N), Space O(1)
1214
721
  * @returns This list.
1215
-
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
- * @example
1255
- * // Reverse in-place
1256
- * const list = new DoublyLinkedList<number>([1, 2, 3]);
1257
- * list.reverse();
1258
- * 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];
1259
727
  */
1260
-
1261
728
  reverse(): this {
1262
729
  let current = this.head;
1263
730
  [this._head, this._tail] = [this.tail, this.head];
@@ -1295,7 +762,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1295
762
  * @param equals - Equality predicate (a, b) → boolean.
1296
763
  * @returns This list.
1297
764
  */
1298
-
1299
765
  setEquality(equals: (a: E, b: E) => boolean): this {
1300
766
  this._equals = equals;
1301
767
  return this;
@@ -1305,51 +771,13 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1305
771
  * Deep clone this list (values are copied by reference).
1306
772
  * @remarks Time O(N), Space O(N)
1307
773
  * @returns A new list with the same element sequence.
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
-
1334
-
1335
-
1336
-
1337
-
1338
-
1339
-
1340
-
1341
-
1342
-
1343
-
1344
-
1345
- * @example
1346
- * // Deep copy
1347
- * const list = new DoublyLinkedList<number>([1, 2, 3]);
1348
- * const copy = list.clone();
1349
- * copy.pop();
1350
- * 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;
1351
780
  */
1352
-
1353
781
  clone(): this {
1354
782
  const out = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
1355
783
  for (const v of this) out.push(v);
@@ -1362,52 +790,12 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1362
790
  * @param callback - Predicate (value, index, list) → boolean to keep value.
1363
791
  * @param [thisArg] - Value for `this` inside the callback.
1364
792
  * @returns A new list with kept values.
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
-
1403
-
1404
- * @example
1405
- * // Filter elements
1406
- * const list = new DoublyLinkedList<number>([1, 2, 3, 4, 5]);
1407
- * const evens = list.filter(n => n % 2 === 0);
1408
- * 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];
1409
798
  */
1410
-
1411
799
  filter(callback: ElementCallback<E, R, boolean>, thisArg?: unknown): this {
1412
800
  const out = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
1413
801
  let index = 0;
@@ -1422,7 +810,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1422
810
  * @param [thisArg] - Value for `this` inside the callback.
1423
811
  * @returns A new list with mapped values.
1424
812
  */
1425
-
1426
813
  mapSame(callback: ElementCallback<E, R, E>, thisArg?: unknown): this {
1427
814
  const out = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
1428
815
  let index = 0;
@@ -1442,61 +829,21 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1442
829
  * @param [options] - Options for the output list (e.g., maxLen, toElementFn).
1443
830
  * @param [thisArg] - Value for `this` inside the callback.
1444
831
  * @returns A new DoublyLinkedList with mapped values.
1445
-
1446
-
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
- * @example
1485
- * // DoublyLinkedList for...of iteration and map operation
1486
- * const list = new DoublyLinkedList<number>([1, 2, 3, 4, 5]);
1487
- *
1488
- * // Iterate through list
1489
- * const doubled = list.map(value => value * 2);
1490
- * console.log(doubled.length); // 5;
1491
- *
1492
- * // Use for...of loop
1493
- * const result: number[] = [];
1494
- * for (const item of list) {
1495
- * result.push(item);
1496
- * }
1497
- * 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];
1498
846
  */
1499
-
1500
847
  map<EM, RM>(
1501
848
  callback: ElementCallback<E, R, EM>,
1502
849
  options?: DoublyLinkedListOptions<EM, RM>,
@@ -1508,13 +855,14 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1508
855
  return out;
1509
856
  }
1510
857
 
858
+ protected _equals: (a: E, b: E) => boolean = (a, b) => Object.is(a, b);
859
+
1511
860
  /**
1512
861
  * (Protected) Create or return a node for the given input (node or raw element).
1513
862
  * @remarks Time O(1), Space O(1)
1514
863
  * @param elementOrNode - Element value or node to normalize.
1515
864
  * @returns A DoublyLinkedListNode for the provided input.
1516
865
  */
1517
-
1518
866
  protected _ensureNode(elementOrNode: E | DoublyLinkedListNode<E>) {
1519
867
  if (this.isNode(elementOrNode)) return elementOrNode;
1520
868
  return new DoublyLinkedListNode<E>(elementOrNode);
@@ -1526,7 +874,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1526
874
  * @param elementNodeOrPredicate - Element, node, or node predicate.
1527
875
  * @returns A predicate function taking a node and returning true/false.
1528
876
  */
1529
-
1530
877
  protected _ensurePredicate(
1531
878
  elementNodeOrPredicate: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)
1532
879
  ): (node: DoublyLinkedListNode<E>) => boolean {
@@ -1547,7 +894,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1547
894
  * @param node - A node in the list.
1548
895
  * @returns Previous node or undefined.
1549
896
  */
1550
-
1551
897
  protected _getPrevNode(node: DoublyLinkedListNode<E>): DoublyLinkedListNode<E> | undefined {
1552
898
  return node.prev;
1553
899
  }
@@ -1558,7 +904,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1558
904
  * @param [options] - Options forwarded to the constructor.
1559
905
  * @returns An empty like-kind list instance.
1560
906
  */
1561
-
1562
907
  protected override _createInstance(options?: LinearBaseOptions<E, R>): this {
1563
908
  const Ctor = this.constructor as new (
1564
909
  elements?: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>,
@@ -1576,7 +921,6 @@ export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, D
1576
921
  * @param [options] - Options forwarded to the constructor.
1577
922
  * @returns A like-kind DoublyLinkedList instance.
1578
923
  */
1579
-
1580
924
  protected _createLike<EM = E, RM = R>(
1581
925
  elements: Iterable<EM> | Iterable<RM> | Iterable<DoublyLinkedListNode<EM>> = [],
1582
926
  options?: DoublyLinkedListOptions<EM, RM>