doubly-linked-list-typed 1.54.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/dist/data-structures/base/iterable-element-base.d.ts +14 -40
- package/dist/data-structures/base/iterable-element-base.js +14 -11
- package/dist/data-structures/base/linear-base.d.ts +277 -0
- package/dist/data-structures/base/linear-base.js +552 -0
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +12 -8
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +50 -37
- package/dist/data-structures/binary-tree/avl-tree.d.ts +64 -0
- package/dist/data-structures/binary-tree/avl-tree.js +64 -0
- package/dist/data-structures/binary-tree/binary-tree.js +5 -5
- package/dist/data-structures/binary-tree/bst.js +11 -11
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +175 -14
- package/dist/data-structures/binary-tree/tree-multi-map.js +210 -40
- package/dist/data-structures/graph/abstract-graph.js +2 -2
- package/dist/data-structures/heap/heap.d.ts +3 -11
- package/dist/data-structures/heap/heap.js +0 -10
- package/dist/data-structures/heap/max-heap.d.ts +2 -2
- package/dist/data-structures/heap/min-heap.d.ts +2 -2
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +65 -94
- package/dist/data-structures/linked-list/doubly-linked-list.js +131 -146
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +79 -75
- package/dist/data-structures/linked-list/singly-linked-list.js +217 -169
- package/dist/data-structures/priority-queue/max-priority-queue.d.ts +2 -2
- package/dist/data-structures/priority-queue/min-priority-queue.d.ts +2 -2
- package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -2
- package/dist/data-structures/queue/deque.d.ts +130 -91
- package/dist/data-structures/queue/deque.js +269 -169
- package/dist/data-structures/queue/queue.d.ts +84 -40
- package/dist/data-structures/queue/queue.js +134 -50
- package/dist/data-structures/stack/stack.d.ts +3 -11
- package/dist/data-structures/stack/stack.js +0 -10
- package/dist/data-structures/trie/trie.d.ts +4 -3
- package/dist/data-structures/trie/trie.js +3 -0
- package/dist/types/data-structures/base/base.d.ts +9 -4
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +2 -2
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +2 -2
- package/dist/types/data-structures/queue/deque.d.ts +2 -3
- package/dist/types/data-structures/queue/queue.d.ts +2 -2
- package/package.json +2 -2
- package/src/data-structures/base/iterable-element-base.ts +29 -20
- package/src/data-structures/base/linear-base.ts +649 -0
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +51 -36
- package/src/data-structures/binary-tree/avl-tree.ts +64 -0
- package/src/data-structures/binary-tree/binary-tree.ts +5 -5
- package/src/data-structures/binary-tree/bst.ts +9 -9
- package/src/data-structures/binary-tree/tree-multi-map.ts +214 -40
- package/src/data-structures/graph/abstract-graph.ts +2 -2
- package/src/data-structures/heap/heap.ts +3 -14
- package/src/data-structures/heap/max-heap.ts +2 -2
- package/src/data-structures/heap/min-heap.ts +2 -2
- package/src/data-structures/linked-list/doubly-linked-list.ts +144 -160
- package/src/data-structures/linked-list/singly-linked-list.ts +241 -185
- package/src/data-structures/priority-queue/max-priority-queue.ts +2 -5
- package/src/data-structures/priority-queue/min-priority-queue.ts +2 -5
- package/src/data-structures/priority-queue/priority-queue.ts +2 -2
- package/src/data-structures/queue/deque.ts +286 -183
- package/src/data-structures/queue/queue.ts +149 -63
- package/src/data-structures/stack/stack.ts +3 -18
- package/src/data-structures/trie/trie.ts +7 -3
- package/src/types/data-structures/base/base.ts +17 -8
- package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +1 -1
- package/src/types/data-structures/binary-tree/tree-multi-map.ts +1 -1
- package/src/types/data-structures/linked-list/doubly-linked-list.ts +2 -2
- package/src/types/data-structures/linked-list/singly-linked-list.ts +2 -2
- package/src/types/data-structures/queue/deque.ts +2 -3
- package/src/types/data-structures/queue/queue.ts +2 -2
|
@@ -1,97 +1,58 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SinglyLinkedList = exports.SinglyLinkedListNode = void 0;
|
|
4
|
-
const
|
|
5
|
-
class SinglyLinkedListNode {
|
|
4
|
+
const linear_base_1 = require("../base/linear-base");
|
|
5
|
+
class SinglyLinkedListNode extends linear_base_1.LinkedListNode {
|
|
6
6
|
/**
|
|
7
7
|
* The constructor function initializes an instance of a class with a given value and sets the next property to undefined.
|
|
8
8
|
* @param {E} value - The "value" parameter is of type E, which means it can be any data type. It represents the value that
|
|
9
9
|
* will be stored in the node of a linked list.
|
|
10
10
|
*/
|
|
11
11
|
constructor(value) {
|
|
12
|
+
super(value);
|
|
12
13
|
this._value = value;
|
|
13
14
|
this._next = undefined;
|
|
14
15
|
}
|
|
15
|
-
/**
|
|
16
|
-
* The function returns the value of a protected variable.
|
|
17
|
-
* @returns The value of the variable `_value` is being returned.
|
|
18
|
-
*/
|
|
19
|
-
get value() {
|
|
20
|
-
return this._value;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* The above function sets the value of a variable.
|
|
24
|
-
* @param {E} value - The parameter "value" is of type E, which means it can be any type.
|
|
25
|
-
*/
|
|
26
|
-
set value(value) {
|
|
27
|
-
this._value = value;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* The `next` function returns the next node in a singly linked list.
|
|
31
|
-
* @returns The `next` property is being returned. It can be either a `SinglyLinkedListNode<E>`
|
|
32
|
-
* object or `undefined`.
|
|
33
|
-
*/
|
|
34
16
|
get next() {
|
|
35
17
|
return this._next;
|
|
36
18
|
}
|
|
37
|
-
/**
|
|
38
|
-
* The "next" property of a SinglyLinkedListNode is set to the provided value.
|
|
39
|
-
* @param {SinglyLinkedListNode<E> | undefined} value - The `value` parameter is of type
|
|
40
|
-
* `SinglyLinkedListNode<E> | undefined`. This means that it can accept either a
|
|
41
|
-
* `SinglyLinkedListNode` object or `undefined` as its value.
|
|
42
|
-
*/
|
|
43
19
|
set next(value) {
|
|
44
20
|
this._next = value;
|
|
45
21
|
}
|
|
46
22
|
}
|
|
47
23
|
exports.SinglyLinkedListNode = SinglyLinkedListNode;
|
|
48
24
|
/**
|
|
25
|
+
* 1. Node Structure: Each node contains three parts: a data field, a pointer (or reference) to the previous node, and a pointer to the next node. This structure allows traversal of the linked list in both directions.
|
|
26
|
+
* 2. Bidirectional Traversal: Unlike doubly linked lists, singly linked lists can be easily traversed forwards but not backwards.
|
|
27
|
+
* 3. No Centralized Index: Unlike arrays, elements in a linked list are not stored contiguously, so there is no centralized index. Accessing elements in a linked list typically requires traversing from the head or tail node.
|
|
28
|
+
* 4. High Efficiency in Insertion and Deletion: Adding or removing elements in a linked list does not require moving other elements, making these operations more efficient than in arrays.
|
|
29
|
+
* Caution: Although our linked list classes provide methods such as at, setAt, addAt, and indexOf that are based on array indices, their time complexity, like that of the native Array.lastIndexOf, is 𝑂(𝑛). If you need to use these methods frequently, you might want to consider other data structures, such as Deque or Queue (designed for random access). Similarly, since the native Array.shift method has a time complexity of 𝑂(𝑛), using an array to simulate a queue can be inefficient. In such cases, you should use Queue or Deque, as these data structures leverage deferred array rearrangement, effectively reducing the average time complexity to 𝑂(1).
|
|
49
30
|
*
|
|
50
31
|
*/
|
|
51
|
-
class SinglyLinkedList extends
|
|
32
|
+
class SinglyLinkedList extends linear_base_1.LinearLinkedBase {
|
|
52
33
|
constructor(elements = [], options) {
|
|
53
34
|
super(options);
|
|
54
|
-
this.
|
|
35
|
+
this._length = 0;
|
|
36
|
+
if (options) {
|
|
37
|
+
}
|
|
55
38
|
this.pushMany(elements);
|
|
56
39
|
}
|
|
57
|
-
/**
|
|
58
|
-
* The `head` function returns the first node of a singly linked list.
|
|
59
|
-
* @returns The method is returning either a SinglyLinkedListNode object or undefined.
|
|
60
|
-
*/
|
|
61
40
|
get head() {
|
|
62
41
|
return this._head;
|
|
63
42
|
}
|
|
64
|
-
/**
|
|
65
|
-
* The `tail` function returns the last node of a singly linked list.
|
|
66
|
-
* @returns The method is returning either a SinglyLinkedListNode object or undefined.
|
|
67
|
-
*/
|
|
68
43
|
get tail() {
|
|
69
44
|
return this._tail;
|
|
70
45
|
}
|
|
71
|
-
/**
|
|
72
|
-
* The above function returns the value of the first element in a linked list, or undefined if the
|
|
73
|
-
* list is empty.
|
|
74
|
-
* @returns The value of the first node in the linked list, or undefined if the linked list is empty.
|
|
75
|
-
*/
|
|
76
46
|
get first() {
|
|
77
47
|
var _a;
|
|
78
48
|
return (_a = this.head) === null || _a === void 0 ? void 0 : _a.value;
|
|
79
49
|
}
|
|
80
|
-
/**
|
|
81
|
-
* The function returns the value of the last element in a linked list, or undefined if the list is
|
|
82
|
-
* empty.
|
|
83
|
-
* @returns The value of the last node in the linked list, or undefined if the linked list is empty.
|
|
84
|
-
*/
|
|
85
50
|
get last() {
|
|
86
51
|
var _a;
|
|
87
52
|
return (_a = this.tail) === null || _a === void 0 ? void 0 : _a.value;
|
|
88
53
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
* @returns The size of the object, which is a number.
|
|
92
|
-
*/
|
|
93
|
-
get size() {
|
|
94
|
-
return this._size;
|
|
54
|
+
get length() {
|
|
55
|
+
return this._length;
|
|
95
56
|
}
|
|
96
57
|
/**
|
|
97
58
|
* Time Complexity: O(n)
|
|
@@ -128,7 +89,9 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
128
89
|
this.tail.next = newNode;
|
|
129
90
|
this._tail = newNode;
|
|
130
91
|
}
|
|
131
|
-
this.
|
|
92
|
+
this._length++;
|
|
93
|
+
if (this._maxLen > 0 && this.length > this._maxLen)
|
|
94
|
+
this.shift();
|
|
132
95
|
return true;
|
|
133
96
|
}
|
|
134
97
|
/**
|
|
@@ -146,7 +109,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
146
109
|
const value = this.head.value;
|
|
147
110
|
this._head = undefined;
|
|
148
111
|
this._tail = undefined;
|
|
149
|
-
this.
|
|
112
|
+
this._length--;
|
|
150
113
|
return value;
|
|
151
114
|
}
|
|
152
115
|
let current = this.head;
|
|
@@ -156,7 +119,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
156
119
|
const value = this.tail.value;
|
|
157
120
|
current.next = undefined;
|
|
158
121
|
this._tail = current;
|
|
159
|
-
this.
|
|
122
|
+
this._length--;
|
|
160
123
|
return value;
|
|
161
124
|
}
|
|
162
125
|
/**
|
|
@@ -171,7 +134,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
171
134
|
return undefined;
|
|
172
135
|
const removedNode = this.head;
|
|
173
136
|
this._head = this.head.next;
|
|
174
|
-
this.
|
|
137
|
+
this._length--;
|
|
175
138
|
return removedNode.value;
|
|
176
139
|
}
|
|
177
140
|
/**
|
|
@@ -195,7 +158,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
195
158
|
newNode.next = this.head;
|
|
196
159
|
this._head = newNode;
|
|
197
160
|
}
|
|
198
|
-
this.
|
|
161
|
+
this._length++;
|
|
199
162
|
return true;
|
|
200
163
|
}
|
|
201
164
|
/**
|
|
@@ -278,7 +241,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
278
241
|
* `undefined` if the index is out of bounds.
|
|
279
242
|
*/
|
|
280
243
|
at(index) {
|
|
281
|
-
if (index < 0 || index >= this.
|
|
244
|
+
if (index < 0 || index >= this._length)
|
|
282
245
|
return undefined;
|
|
283
246
|
let current = this.head;
|
|
284
247
|
for (let i = 0; i < index; i++) {
|
|
@@ -330,21 +293,25 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
330
293
|
* bounds.
|
|
331
294
|
*/
|
|
332
295
|
deleteAt(index) {
|
|
333
|
-
if (index < 0 || index >= this.
|
|
334
|
-
return
|
|
296
|
+
if (index < 0 || index >= this._length)
|
|
297
|
+
return;
|
|
298
|
+
let deleted;
|
|
335
299
|
if (index === 0) {
|
|
300
|
+
deleted = this.first;
|
|
336
301
|
this.shift();
|
|
337
|
-
return
|
|
302
|
+
return deleted;
|
|
338
303
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
304
|
+
const targetNode = this.getNodeAt(index);
|
|
305
|
+
const prevNode = this._getPrevNode(targetNode);
|
|
306
|
+
if (prevNode && targetNode) {
|
|
307
|
+
deleted = targetNode.value;
|
|
308
|
+
prevNode.next = targetNode.next;
|
|
309
|
+
if (targetNode === this.tail)
|
|
310
|
+
this._tail = prevNode;
|
|
311
|
+
this._length--;
|
|
312
|
+
return deleted;
|
|
342
313
|
}
|
|
343
|
-
|
|
344
|
-
const removedNode = prevNode.next;
|
|
345
|
-
prevNode.next = removedNode.next;
|
|
346
|
-
this._size--;
|
|
347
|
-
return true;
|
|
314
|
+
return;
|
|
348
315
|
}
|
|
349
316
|
/**
|
|
350
317
|
* Time Complexity: O(n)
|
|
@@ -357,37 +324,25 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
357
324
|
* successfully deleted from the linked list, and `false` if the value or node is not found in the linked list.
|
|
358
325
|
*/
|
|
359
326
|
delete(elementOrNode) {
|
|
360
|
-
if (elementOrNode === undefined)
|
|
327
|
+
if (elementOrNode === undefined || !this.head)
|
|
328
|
+
return false;
|
|
329
|
+
const node = this.isNode(elementOrNode) ? elementOrNode : this.getNode(elementOrNode);
|
|
330
|
+
if (!node)
|
|
361
331
|
return false;
|
|
362
|
-
|
|
363
|
-
if (
|
|
364
|
-
|
|
332
|
+
const prevNode = this._getPrevNode(node);
|
|
333
|
+
if (!prevNode) {
|
|
334
|
+
// The node is the head
|
|
335
|
+
this._head = node.next;
|
|
336
|
+
if (node === this.tail)
|
|
337
|
+
this._tail = undefined;
|
|
365
338
|
}
|
|
366
339
|
else {
|
|
367
|
-
|
|
340
|
+
prevNode.next = node.next;
|
|
341
|
+
if (node === this.tail)
|
|
342
|
+
this._tail = prevNode;
|
|
368
343
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
if (current.value === value) {
|
|
372
|
-
if (prev === undefined) {
|
|
373
|
-
this._head = current.next;
|
|
374
|
-
if (current === this.tail) {
|
|
375
|
-
this._tail = undefined;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
else {
|
|
379
|
-
prev.next = current.next;
|
|
380
|
-
if (current === this.tail) {
|
|
381
|
-
this._tail = prev;
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
this._size--;
|
|
385
|
-
return true;
|
|
386
|
-
}
|
|
387
|
-
prev = current;
|
|
388
|
-
current = current.next;
|
|
389
|
-
}
|
|
390
|
-
return false;
|
|
344
|
+
this._length--;
|
|
345
|
+
return true;
|
|
391
346
|
}
|
|
392
347
|
/**
|
|
393
348
|
* Time Complexity: O(n)
|
|
@@ -405,13 +360,13 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
405
360
|
* successfully added at the specified index, and `false` if the index is out of bounds.
|
|
406
361
|
*/
|
|
407
362
|
addAt(index, newElementOrNode) {
|
|
408
|
-
if (index < 0 || index > this.
|
|
363
|
+
if (index < 0 || index > this._length)
|
|
409
364
|
return false;
|
|
410
365
|
if (index === 0) {
|
|
411
366
|
this.unshift(newElementOrNode);
|
|
412
367
|
return true;
|
|
413
368
|
}
|
|
414
|
-
if (index === this.
|
|
369
|
+
if (index === this._length) {
|
|
415
370
|
this.push(newElementOrNode);
|
|
416
371
|
return true;
|
|
417
372
|
}
|
|
@@ -419,9 +374,31 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
419
374
|
const prevNode = this.getNodeAt(index - 1);
|
|
420
375
|
newNode.next = prevNode.next;
|
|
421
376
|
prevNode.next = newNode;
|
|
422
|
-
this.
|
|
377
|
+
this._length++;
|
|
423
378
|
return true;
|
|
424
379
|
}
|
|
380
|
+
/**
|
|
381
|
+
* Time Complexity: O(n)
|
|
382
|
+
* Space Complexity: O(1)
|
|
383
|
+
*
|
|
384
|
+
* The function setAt(index, value) updates the value at a specified index in a data structure if the
|
|
385
|
+
* index exists.
|
|
386
|
+
* @param {number} index - The `index` parameter in the `setAt` method refers to the position in the
|
|
387
|
+
* data structure where you want to set a new value.
|
|
388
|
+
* @param {E} value - The `value` parameter in the `setAt` method represents the new value that you
|
|
389
|
+
* want to set at the specified index in the data structure.
|
|
390
|
+
* @returns The `setAt` method returns a boolean value - `true` if the value at the specified index
|
|
391
|
+
* is successfully updated, and `false` if the index is out of bounds (i.e., the node at that index
|
|
392
|
+
* does not exist).
|
|
393
|
+
*/
|
|
394
|
+
setAt(index, value) {
|
|
395
|
+
const node = this.getNodeAt(index);
|
|
396
|
+
if (node) {
|
|
397
|
+
node.value = value;
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
425
402
|
/**
|
|
426
403
|
* Time Complexity: O(1)
|
|
427
404
|
* Space Complexity: O(1)
|
|
@@ -431,7 +408,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
431
408
|
* @returns A boolean value indicating whether the length of the object is equal to 0.
|
|
432
409
|
*/
|
|
433
410
|
isEmpty() {
|
|
434
|
-
return this.
|
|
411
|
+
return this._length === 0;
|
|
435
412
|
}
|
|
436
413
|
/**
|
|
437
414
|
* Time Complexity: O(1)
|
|
@@ -442,23 +419,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
442
419
|
clear() {
|
|
443
420
|
this._head = undefined;
|
|
444
421
|
this._tail = undefined;
|
|
445
|
-
this.
|
|
446
|
-
}
|
|
447
|
-
/**
|
|
448
|
-
* Time Complexity: O(n)
|
|
449
|
-
* Space Complexity: O(n)
|
|
450
|
-
*
|
|
451
|
-
* The `toArray` function converts a linked list into an array.
|
|
452
|
-
* @returns The `toArray()` method is returning an array of type `E[]`.
|
|
453
|
-
*/
|
|
454
|
-
toArray() {
|
|
455
|
-
const array = [];
|
|
456
|
-
let current = this.head;
|
|
457
|
-
while (current) {
|
|
458
|
-
array.push(current.value);
|
|
459
|
-
current = current.next;
|
|
460
|
-
}
|
|
461
|
-
return array;
|
|
422
|
+
this._length = 0;
|
|
462
423
|
}
|
|
463
424
|
/**
|
|
464
425
|
* Time Complexity: O(n)
|
|
@@ -482,32 +443,6 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
482
443
|
[this._head, this._tail] = [this.tail, this.head];
|
|
483
444
|
return this;
|
|
484
445
|
}
|
|
485
|
-
/**
|
|
486
|
-
* Time Complexity: O(n)
|
|
487
|
-
* Space Complexity: O(1)
|
|
488
|
-
*
|
|
489
|
-
* The `indexOf` function in TypeScript searches for a specific element or node in a singly linked
|
|
490
|
-
* list and returns its index if found.
|
|
491
|
-
* @param {E | SinglyLinkedListNode<E> | ((node: SinglyLinkedListNode<E>) => boolean)} elementNodeOrPredicate
|
|
492
|
-
* elementNodeOrPredicate - The `elementNodeOrPredicate` parameter in the `indexOf` method can be one
|
|
493
|
-
* of the following types:
|
|
494
|
-
* @returns The `indexOf` method returns the index of the first occurrence of the element that
|
|
495
|
-
* matches the provided predicate in the singly linked list. If no matching element is found, it
|
|
496
|
-
* returns -1.
|
|
497
|
-
*/
|
|
498
|
-
indexOf(elementNodeOrPredicate) {
|
|
499
|
-
const predicate = this._ensurePredicate(elementNodeOrPredicate);
|
|
500
|
-
let index = 0;
|
|
501
|
-
let current = this.head;
|
|
502
|
-
while (current) {
|
|
503
|
-
if (predicate(current)) {
|
|
504
|
-
return index;
|
|
505
|
-
}
|
|
506
|
-
index++;
|
|
507
|
-
current = current.next;
|
|
508
|
-
}
|
|
509
|
-
return -1;
|
|
510
|
-
}
|
|
511
446
|
/**
|
|
512
447
|
* Time Complexity: O(n)
|
|
513
448
|
* Space Complexity: O(1)
|
|
@@ -524,6 +459,8 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
524
459
|
getNode(elementNodeOrPredicate) {
|
|
525
460
|
if (elementNodeOrPredicate === undefined)
|
|
526
461
|
return;
|
|
462
|
+
if (this.isNode(elementNodeOrPredicate))
|
|
463
|
+
return elementNodeOrPredicate;
|
|
527
464
|
const predicate = this._ensurePredicate(elementNodeOrPredicate);
|
|
528
465
|
let current = this.head;
|
|
529
466
|
while (current) {
|
|
@@ -551,31 +488,21 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
551
488
|
* unsuccessful.
|
|
552
489
|
*/
|
|
553
490
|
addBefore(existingElementOrNode, newElementOrNode) {
|
|
554
|
-
|
|
491
|
+
const existingNode = this.getNode(existingElementOrNode);
|
|
492
|
+
if (!existingNode)
|
|
555
493
|
return false;
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
494
|
+
const prevNode = this._getPrevNode(existingNode);
|
|
495
|
+
const newNode = this._ensureNode(newElementOrNode);
|
|
496
|
+
if (!prevNode) {
|
|
497
|
+
// Add at the head
|
|
498
|
+
this.unshift(newNode);
|
|
559
499
|
}
|
|
560
500
|
else {
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
this.unshift(newElementOrNode);
|
|
565
|
-
return true;
|
|
566
|
-
}
|
|
567
|
-
let current = this.head;
|
|
568
|
-
while (current.next) {
|
|
569
|
-
if (current.next.value === existingValue) {
|
|
570
|
-
const newNode = this._ensureNode(newElementOrNode);
|
|
571
|
-
newNode.next = current.next;
|
|
572
|
-
current.next = newNode;
|
|
573
|
-
this._size++;
|
|
574
|
-
return true;
|
|
575
|
-
}
|
|
576
|
-
current = current.next;
|
|
501
|
+
prevNode.next = newNode;
|
|
502
|
+
newNode.next = existingNode;
|
|
503
|
+
this._length++;
|
|
577
504
|
}
|
|
578
|
-
return
|
|
505
|
+
return true;
|
|
579
506
|
}
|
|
580
507
|
/**
|
|
581
508
|
* Time Complexity: O(n)
|
|
@@ -602,11 +529,74 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
602
529
|
if (existingNode === this.tail) {
|
|
603
530
|
this._tail = newNode;
|
|
604
531
|
}
|
|
605
|
-
this.
|
|
532
|
+
this._length++;
|
|
606
533
|
return true;
|
|
607
534
|
}
|
|
608
535
|
return false;
|
|
609
536
|
}
|
|
537
|
+
/**
|
|
538
|
+
* Time Complexity: O(n)
|
|
539
|
+
* Space Complexity: O(1)
|
|
540
|
+
*
|
|
541
|
+
* The function `splice` in TypeScript overrides the default behavior to remove and insert elements
|
|
542
|
+
* in a singly linked list while handling boundary cases.
|
|
543
|
+
* @param {number} start - The `start` parameter in the `splice` method indicates the index at which
|
|
544
|
+
* to start modifying the list. It specifies the position where elements will be added or removed.
|
|
545
|
+
* @param {number} [deleteCount=0] - The `deleteCount` parameter in the `splice` method specifies the
|
|
546
|
+
* number of elements to remove from the array starting at the specified `start` index. If
|
|
547
|
+
* `deleteCount` is not provided, it defaults to 0, meaning no elements will be removed but new
|
|
548
|
+
* elements can still be inserted at
|
|
549
|
+
* @param {E[]} items - The `items` parameter in the `splice` method represents the elements to be
|
|
550
|
+
* inserted into the list at the specified `start` index. These elements will be inserted in place of
|
|
551
|
+
* the elements that are removed from the list. The `splice` method allows you to add new elements to
|
|
552
|
+
* the list while
|
|
553
|
+
* @returns The `splice` method is returning a `SinglyLinkedList` containing the elements that were
|
|
554
|
+
* removed from the original list during the splice operation.
|
|
555
|
+
*/
|
|
556
|
+
splice(start, deleteCount = 0, ...items) {
|
|
557
|
+
const removedList = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
|
|
558
|
+
// If `start` is out of range, perform boundary processing
|
|
559
|
+
start = Math.max(0, Math.min(start, this.length));
|
|
560
|
+
deleteCount = Math.max(0, deleteCount);
|
|
561
|
+
// Find the predecessor node of `start`
|
|
562
|
+
const prevNode = start === 0 ? undefined : this.getNodeAt(start - 1);
|
|
563
|
+
const startNode = prevNode ? prevNode.next : this.head;
|
|
564
|
+
let current = startNode;
|
|
565
|
+
for (let i = 0; i < deleteCount && current; i++) {
|
|
566
|
+
removedList.push(current.value);
|
|
567
|
+
current = current.next;
|
|
568
|
+
}
|
|
569
|
+
const nextNode = current;
|
|
570
|
+
let lastInsertedNode = undefined;
|
|
571
|
+
for (const item of items) {
|
|
572
|
+
const newNode = this._ensureNode(item);
|
|
573
|
+
if (!lastInsertedNode) {
|
|
574
|
+
if (prevNode) {
|
|
575
|
+
prevNode.next = newNode;
|
|
576
|
+
}
|
|
577
|
+
else {
|
|
578
|
+
this._head = newNode;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
else {
|
|
582
|
+
lastInsertedNode.next = newNode;
|
|
583
|
+
}
|
|
584
|
+
lastInsertedNode = newNode;
|
|
585
|
+
}
|
|
586
|
+
// Connect new node to `nextNode`
|
|
587
|
+
if (lastInsertedNode) {
|
|
588
|
+
lastInsertedNode.next = nextNode;
|
|
589
|
+
}
|
|
590
|
+
else if (prevNode) {
|
|
591
|
+
prevNode.next = nextNode;
|
|
592
|
+
}
|
|
593
|
+
// Update tail node and length
|
|
594
|
+
if (!nextNode) {
|
|
595
|
+
this._tail = lastInsertedNode || prevNode;
|
|
596
|
+
}
|
|
597
|
+
this._length += items.length - removedList.length;
|
|
598
|
+
return removedList;
|
|
599
|
+
}
|
|
610
600
|
/**
|
|
611
601
|
* Time Complexity: O(n)
|
|
612
602
|
* Space Complexity: O(1)
|
|
@@ -640,7 +630,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
640
630
|
* is a clone of the original list.
|
|
641
631
|
*/
|
|
642
632
|
clone() {
|
|
643
|
-
return new SinglyLinkedList(this, { toElementFn: this.toElementFn });
|
|
633
|
+
return new SinglyLinkedList(this, { toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
644
634
|
}
|
|
645
635
|
/**
|
|
646
636
|
* Time Complexity: O(n)
|
|
@@ -660,7 +650,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
660
650
|
* elements that pass the filter condition specified by the `callback` function.
|
|
661
651
|
*/
|
|
662
652
|
filter(callback, thisArg) {
|
|
663
|
-
const filteredList =
|
|
653
|
+
const filteredList = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
664
654
|
let index = 0;
|
|
665
655
|
for (const current of this) {
|
|
666
656
|
if (callback.call(thisArg, current, index, this)) {
|
|
@@ -691,7 +681,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
691
681
|
* @returns a new instance of the `SinglyLinkedList` class with the mapped elements.
|
|
692
682
|
*/
|
|
693
683
|
map(callback, toElementFn, thisArg) {
|
|
694
|
-
const mappedList = new SinglyLinkedList([], { toElementFn });
|
|
684
|
+
const mappedList = new SinglyLinkedList([], { toElementFn, maxLen: this._maxLen });
|
|
695
685
|
let index = 0;
|
|
696
686
|
for (const current of this) {
|
|
697
687
|
mappedList.push(callback.call(thisArg, current, index, this));
|
|
@@ -699,6 +689,19 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
699
689
|
}
|
|
700
690
|
return mappedList;
|
|
701
691
|
}
|
|
692
|
+
/**
|
|
693
|
+
* The function `_createInstance` returns a new instance of `SinglyLinkedList` with the specified
|
|
694
|
+
* options.
|
|
695
|
+
* @param [options] - The `options` parameter in the `_createInstance` method is of type
|
|
696
|
+
* `SinglyLinkedListOptions<E, R>`, which is used to configure the behavior of the `SinglyLinkedList`
|
|
697
|
+
* instance being created. It is an optional parameter, meaning it can be omitted when calling the
|
|
698
|
+
* method.
|
|
699
|
+
* @returns An instance of the `SinglyLinkedList` class with an empty array and the provided options
|
|
700
|
+
* is being returned.
|
|
701
|
+
*/
|
|
702
|
+
_createInstance(options) {
|
|
703
|
+
return new SinglyLinkedList([], options);
|
|
704
|
+
}
|
|
702
705
|
/**
|
|
703
706
|
* The function `_getIterator` returns an iterable iterator that yields the values of a linked list.
|
|
704
707
|
*/
|
|
@@ -709,6 +712,33 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
709
712
|
current = current.next;
|
|
710
713
|
}
|
|
711
714
|
}
|
|
715
|
+
/**
|
|
716
|
+
* The function returns an iterator that iterates over the elements of a collection in reverse order.
|
|
717
|
+
*/
|
|
718
|
+
*_getReverseIterator() {
|
|
719
|
+
const reversedArr = [...this].reverse();
|
|
720
|
+
for (const item of reversedArr) {
|
|
721
|
+
yield item;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* The function `_getNodeIterator` returns an iterator that iterates over the nodes of a singly
|
|
726
|
+
* linked list.
|
|
727
|
+
*/
|
|
728
|
+
*_getNodeIterator() {
|
|
729
|
+
let current = this.head;
|
|
730
|
+
while (current) {
|
|
731
|
+
yield current;
|
|
732
|
+
current = current.next;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
// protected *_getReverseNodeIterator(): IterableIterator<SinglyLinkedListNode<E>> {
|
|
736
|
+
// const reversedArr = [...this._getNodeIterator()].reverse();
|
|
737
|
+
//
|
|
738
|
+
// for (const item of reversedArr) {
|
|
739
|
+
// yield item;
|
|
740
|
+
// }
|
|
741
|
+
// }
|
|
712
742
|
/**
|
|
713
743
|
* The _isPredicate function in TypeScript checks if the input is a function that takes a
|
|
714
744
|
* SinglyLinkedListNode as an argument and returns a boolean.
|
|
@@ -751,5 +781,23 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
751
781
|
return elementNodeOrPredicate;
|
|
752
782
|
return (node) => node.value === elementNodeOrPredicate;
|
|
753
783
|
}
|
|
784
|
+
/**
|
|
785
|
+
* The function `_getPrevNode` returns the node before a given node in a singly linked list.
|
|
786
|
+
* @param node - The `node` parameter in the `_getPrevNode` method is a reference to a node in a
|
|
787
|
+
* singly linked list. The method is used to find the node that comes before the given node in the
|
|
788
|
+
* linked list.
|
|
789
|
+
* @returns The `_getPrevNode` method returns either the previous node of the input node in a singly
|
|
790
|
+
* linked list or `undefined` if the input node is the head of the list or if the input node is not
|
|
791
|
+
* found in the list.
|
|
792
|
+
*/
|
|
793
|
+
_getPrevNode(node) {
|
|
794
|
+
if (!this.head || this.head === node)
|
|
795
|
+
return undefined;
|
|
796
|
+
let current = this.head;
|
|
797
|
+
while (current.next && current.next !== node) {
|
|
798
|
+
current = current.next;
|
|
799
|
+
}
|
|
800
|
+
return current.next === node ? current : undefined;
|
|
801
|
+
}
|
|
754
802
|
}
|
|
755
803
|
exports.SinglyLinkedList = SinglyLinkedList;
|
|
@@ -45,7 +45,7 @@ export declare class MaxPriorityQueue<E = any, R = any> extends PriorityQueue<E,
|
|
|
45
45
|
* @returns The `filter` method is returning a new `MaxPriorityQueue` object that contains the elements that pass
|
|
46
46
|
* the filter condition specified by the `callback` function.
|
|
47
47
|
*/
|
|
48
|
-
filter(callback: ElementCallback<E, R, boolean
|
|
48
|
+
filter(callback: ElementCallback<E, R, boolean>, thisArg?: any): MaxPriorityQueue<E, R>;
|
|
49
49
|
/**
|
|
50
50
|
* Time Complexity: O(n log n)
|
|
51
51
|
* Space Complexity: O(n)
|
|
@@ -67,5 +67,5 @@ export declare class MaxPriorityQueue<E = any, R = any> extends PriorityQueue<E,
|
|
|
67
67
|
* value of
|
|
68
68
|
* @returns a new instance of the `MaxPriorityQueue` class with the mapped elements.
|
|
69
69
|
*/
|
|
70
|
-
map<EM, RM>(callback: ElementCallback<E, R, EM
|
|
70
|
+
map<EM, RM>(callback: ElementCallback<E, R, EM>, comparator: Comparator<EM>, toElementFn?: (rawElement: RM) => EM, thisArg?: any): MaxPriorityQueue<EM, RM>;
|
|
71
71
|
}
|
|
@@ -46,7 +46,7 @@ export declare class MinPriorityQueue<E = any, R = any> extends PriorityQueue<E,
|
|
|
46
46
|
* @returns The `filter` method is returning a new `MinPriorityQueue` object that contains the elements that pass
|
|
47
47
|
* the filter condition specified by the `callback` function.
|
|
48
48
|
*/
|
|
49
|
-
filter(callback: ElementCallback<E, R, boolean
|
|
49
|
+
filter(callback: ElementCallback<E, R, boolean>, thisArg?: any): MinPriorityQueue<E, R>;
|
|
50
50
|
/**
|
|
51
51
|
* Time Complexity: O(n log n)
|
|
52
52
|
* Space Complexity: O(n)
|
|
@@ -68,5 +68,5 @@ export declare class MinPriorityQueue<E = any, R = any> extends PriorityQueue<E,
|
|
|
68
68
|
* value of
|
|
69
69
|
* @returns a new instance of the `MinPriorityQueue` class with the mapped elements.
|
|
70
70
|
*/
|
|
71
|
-
map<EM, RM>(callback: ElementCallback<E, R, EM
|
|
71
|
+
map<EM, RM>(callback: ElementCallback<E, R, EM>, comparator: Comparator<EM>, toElementFn?: (rawElement: RM) => EM, thisArg?: any): MinPriorityQueue<EM, RM>;
|
|
72
72
|
}
|
|
@@ -48,7 +48,7 @@ export declare class PriorityQueue<E = any, R = any> extends Heap<E, R> {
|
|
|
48
48
|
* @returns The `filter` method is returning a new `PriorityQueue` object that contains the elements that pass
|
|
49
49
|
* the filter condition specified by the `callback` function.
|
|
50
50
|
*/
|
|
51
|
-
filter(callback: ElementCallback<E, R, boolean
|
|
51
|
+
filter(callback: ElementCallback<E, R, boolean>, thisArg?: any): PriorityQueue<E, R>;
|
|
52
52
|
/**
|
|
53
53
|
* Time Complexity: O(n log n)
|
|
54
54
|
* Space Complexity: O(n)
|
|
@@ -70,5 +70,5 @@ export declare class PriorityQueue<E = any, R = any> extends Heap<E, R> {
|
|
|
70
70
|
* value of
|
|
71
71
|
* @returns a new instance of the `PriorityQueue` class with the mapped elements.
|
|
72
72
|
*/
|
|
73
|
-
map<EM, RM>(callback: ElementCallback<E, R, EM
|
|
73
|
+
map<EM, RM>(callback: ElementCallback<E, R, EM>, comparator: Comparator<EM>, toElementFn?: (rawElement: RM) => EM, thisArg?: any): PriorityQueue<EM, RM>;
|
|
74
74
|
}
|