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.
- package/.github/workflows/ci.yml +7 -2
- package/.github/workflows/release-package.yml +9 -2
- package/.husky/pre-commit +3 -0
- package/CHANGELOG.md +1 -1
- package/MIGRATION.md +48 -0
- package/README.md +20 -2
- package/README_CN.md +20 -2
- package/SPECIFICATION.md +24 -0
- package/SPECIFICATION.zh-CN.md +24 -0
- package/dist/cjs/binary-tree.cjs +1897 -19
- package/dist/cjs/graph.cjs +174 -0
- package/dist/cjs/hash.cjs +33 -0
- package/dist/cjs/heap.cjs +71 -0
- package/dist/cjs/index.cjs +2383 -3
- package/dist/cjs/linked-list.cjs +224 -2
- package/dist/cjs/matrix.cjs +24 -0
- package/dist/cjs/priority-queue.cjs +71 -0
- package/dist/cjs/queue.cjs +221 -1
- package/dist/cjs/stack.cjs +59 -0
- package/dist/cjs/trie.cjs +62 -0
- package/dist/cjs-legacy/binary-tree.cjs +1897 -19
- package/dist/cjs-legacy/graph.cjs +174 -0
- package/dist/cjs-legacy/hash.cjs +33 -0
- package/dist/cjs-legacy/heap.cjs +71 -0
- package/dist/cjs-legacy/index.cjs +2383 -3
- package/dist/cjs-legacy/linked-list.cjs +224 -2
- package/dist/cjs-legacy/matrix.cjs +24 -0
- package/dist/cjs-legacy/priority-queue.cjs +71 -0
- package/dist/cjs-legacy/queue.cjs +221 -1
- package/dist/cjs-legacy/stack.cjs +59 -0
- package/dist/cjs-legacy/trie.cjs +62 -0
- package/dist/esm/binary-tree.mjs +1897 -19
- package/dist/esm/graph.mjs +174 -0
- package/dist/esm/hash.mjs +33 -0
- package/dist/esm/heap.mjs +71 -0
- package/dist/esm/index.mjs +2383 -3
- package/dist/esm/linked-list.mjs +224 -2
- package/dist/esm/matrix.mjs +24 -0
- package/dist/esm/priority-queue.mjs +71 -0
- package/dist/esm/queue.mjs +221 -1
- package/dist/esm/stack.mjs +59 -0
- package/dist/esm/trie.mjs +62 -0
- package/dist/esm-legacy/binary-tree.mjs +1897 -19
- package/dist/esm-legacy/graph.mjs +174 -0
- package/dist/esm-legacy/hash.mjs +33 -0
- package/dist/esm-legacy/heap.mjs +71 -0
- package/dist/esm-legacy/index.mjs +2383 -3
- package/dist/esm-legacy/linked-list.mjs +224 -2
- package/dist/esm-legacy/matrix.mjs +24 -0
- package/dist/esm-legacy/priority-queue.mjs +71 -0
- package/dist/esm-legacy/queue.mjs +221 -1
- package/dist/esm-legacy/stack.mjs +59 -0
- package/dist/esm-legacy/trie.mjs +62 -0
- package/dist/types/data-structures/base/iterable-element-base.d.ts +17 -0
- package/dist/types/data-structures/base/linear-base.d.ts +6 -0
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +36 -0
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +42 -0
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +75 -0
- package/dist/types/data-structures/binary-tree/bst.d.ts +72 -0
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +57 -0
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +18 -0
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +375 -0
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +389 -0
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +330 -0
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +438 -0
- package/dist/types/data-structures/graph/directed-graph.d.ts +30 -0
- package/dist/types/data-structures/graph/undirected-graph.d.ts +27 -0
- package/dist/types/data-structures/hash/hash-map.d.ts +33 -0
- package/dist/types/data-structures/heap/heap.d.ts +42 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +75 -2
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +45 -0
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +54 -0
- package/dist/types/data-structures/matrix/matrix.d.ts +24 -0
- package/dist/types/data-structures/queue/deque.d.ts +90 -1
- package/dist/types/data-structures/queue/queue.d.ts +36 -0
- package/dist/types/data-structures/stack/stack.d.ts +30 -0
- package/dist/types/data-structures/trie/trie.d.ts +36 -0
- package/dist/umd/data-structure-typed.js +2383 -3
- package/dist/umd/data-structure-typed.min.js +3 -3
- package/docs-site-docusaurus/docs/api/classes/AVLTree.md +108 -108
- package/docs-site-docusaurus/docs/api/classes/BST.md +101 -101
- package/docs-site-docusaurus/docs/api/classes/BinaryIndexedTree.md +13 -13
- package/docs-site-docusaurus/docs/api/classes/BinaryTree.md +66 -66
- package/docs-site-docusaurus/docs/api/classes/Deque.md +235 -51
- package/docs-site-docusaurus/docs/api/classes/DirectedGraph.md +21 -21
- package/docs-site-docusaurus/docs/api/classes/DoublyLinkedList.md +231 -67
- package/docs-site-docusaurus/docs/api/classes/FibonacciHeap.md +9 -9
- package/docs-site-docusaurus/docs/api/classes/FibonacciHeapNode.md +1 -1
- package/docs-site-docusaurus/docs/api/classes/HashMap.md +14 -14
- package/docs-site-docusaurus/docs/api/classes/Heap.md +117 -34
- package/docs-site-docusaurus/docs/api/classes/IterableElementBase.md +83 -13
- package/docs-site-docusaurus/docs/api/classes/LinearBase.md +124 -20
- package/docs-site-docusaurus/docs/api/classes/LinearLinkedBase.md +140 -32
- package/docs-site-docusaurus/docs/api/classes/LinkedHashMap.md +30 -26
- package/docs-site-docusaurus/docs/api/classes/LinkedListQueue.md +159 -51
- package/docs-site-docusaurus/docs/api/classes/MapGraph.md +20 -20
- package/docs-site-docusaurus/docs/api/classes/Matrix.md +23 -23
- package/docs-site-docusaurus/docs/api/classes/MaxHeap.md +117 -34
- package/docs-site-docusaurus/docs/api/classes/MaxPriorityQueue.md +117 -34
- package/docs-site-docusaurus/docs/api/classes/MinHeap.md +117 -34
- package/docs-site-docusaurus/docs/api/classes/MinPriorityQueue.md +117 -34
- package/docs-site-docusaurus/docs/api/classes/PriorityQueue.md +117 -34
- package/docs-site-docusaurus/docs/api/classes/Queue.md +142 -34
- package/docs-site-docusaurus/docs/api/classes/RedBlackTree.md +117 -117
- package/docs-site-docusaurus/docs/api/classes/SegmentTree.md +8 -8
- package/docs-site-docusaurus/docs/api/classes/SinglyLinkedList.md +158 -50
- package/docs-site-docusaurus/docs/api/classes/SkipList.md +21 -21
- package/docs-site-docusaurus/docs/api/classes/Stack.md +108 -26
- package/docs-site-docusaurus/docs/api/classes/TreeMap.md +33 -33
- package/docs-site-docusaurus/docs/api/classes/TreeMultiMap.md +75 -39
- package/docs-site-docusaurus/docs/api/classes/TreeSet.md +301 -39
- package/docs-site-docusaurus/docs/api/classes/Trie.md +110 -28
- package/docs-site-docusaurus/docs/api/classes/UndirectedGraph.md +20 -20
- package/jest.integration.config.js +1 -2
- package/package.json +51 -50
- package/src/common/error.ts +15 -32
- package/src/common/index.ts +0 -3
- package/src/data-structures/base/iterable-element-base.ts +32 -3
- package/src/data-structures/base/linear-base.ts +13 -36
- package/src/data-structures/binary-tree/avl-tree.ts +31 -493
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +47 -530
- package/src/data-structures/binary-tree/binary-tree.ts +326 -1236
- package/src/data-structures/binary-tree/bst.ts +158 -1010
- package/src/data-structures/binary-tree/red-black-tree.ts +451 -1233
- package/src/data-structures/binary-tree/segment-tree.ts +73 -333
- package/src/data-structures/binary-tree/tree-map.ts +462 -4749
- package/src/data-structures/binary-tree/tree-multi-map.ts +310 -4530
- package/src/data-structures/binary-tree/tree-multi-set.ts +300 -3652
- package/src/data-structures/binary-tree/tree-set.ts +437 -4443
- package/src/data-structures/graph/abstract-graph.ts +98 -167
- package/src/data-structures/graph/directed-graph.ts +137 -532
- package/src/data-structures/graph/map-graph.ts +0 -3
- package/src/data-structures/graph/undirected-graph.ts +132 -484
- package/src/data-structures/hash/hash-map.ts +154 -549
- package/src/data-structures/heap/heap.ts +200 -753
- package/src/data-structures/linked-list/doubly-linked-list.ts +153 -809
- package/src/data-structures/linked-list/singly-linked-list.ts +122 -749
- package/src/data-structures/linked-list/skip-linked-list.ts +211 -864
- package/src/data-structures/matrix/matrix.ts +179 -494
- package/src/data-structures/matrix/navigator.ts +0 -1
- package/src/data-structures/priority-queue/max-priority-queue.ts +1 -6
- package/src/data-structures/priority-queue/min-priority-queue.ts +6 -11
- package/src/data-structures/priority-queue/priority-queue.ts +1 -2
- package/src/data-structures/queue/deque.ts +241 -807
- package/src/data-structures/queue/queue.ts +102 -589
- package/src/data-structures/stack/stack.ts +76 -475
- package/src/data-structures/trie/trie.ts +98 -592
- package/src/types/common.ts +0 -10
- package/src/types/data-structures/binary-tree/bst.ts +0 -7
- package/src/types/data-structures/binary-tree/red-black-tree.ts +0 -1
- package/src/types/data-structures/graph/abstract-graph.ts +0 -2
- package/src/types/data-structures/hash/hash-map.ts +0 -3
- package/src/types/data-structures/hash/index.ts +0 -1
- package/src/types/data-structures/matrix/navigator.ts +0 -2
- package/src/types/utils/utils.ts +0 -7
- package/src/types/utils/validate-type.ts +0 -7
- package/src/utils/number.ts +0 -2
- 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>
|