graph-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/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
|
@@ -61,7 +61,7 @@ export class MaxHeap<E = any, R = any> extends Heap<E, R> {
|
|
|
61
61
|
* @returns The `filter` method is returning a new `MaxHeap` object that contains the elements that pass
|
|
62
62
|
* the filter condition specified by the `callback` function.
|
|
63
63
|
*/
|
|
64
|
-
override filter(callback: ElementCallback<E, R, boolean
|
|
64
|
+
override filter(callback: ElementCallback<E, R, boolean>, thisArg?: any): MaxHeap<E, R> {
|
|
65
65
|
const filteredList = new MaxHeap<E, R>([], { toElementFn: this.toElementFn, comparator: this.comparator });
|
|
66
66
|
let index = 0;
|
|
67
67
|
for (const current of this) {
|
|
@@ -95,7 +95,7 @@ export class MaxHeap<E = any, R = any> extends Heap<E, R> {
|
|
|
95
95
|
* @returns a new instance of the `MaxHeap` class with the mapped elements.
|
|
96
96
|
*/
|
|
97
97
|
override map<EM, RM>(
|
|
98
|
-
callback: ElementCallback<E, R, EM
|
|
98
|
+
callback: ElementCallback<E, R, EM>,
|
|
99
99
|
comparator: Comparator<EM>,
|
|
100
100
|
toElementFn?: (rawElement: RM) => EM,
|
|
101
101
|
thisArg?: any
|
|
@@ -49,7 +49,7 @@ export class MinHeap<E = any, R = any> extends Heap<E, R> {
|
|
|
49
49
|
* @returns The `filter` method is returning a new `MinHeap` object that contains the elements that pass
|
|
50
50
|
* the filter condition specified by the `callback` function.
|
|
51
51
|
*/
|
|
52
|
-
override filter(callback: ElementCallback<E, R, boolean
|
|
52
|
+
override filter(callback: ElementCallback<E, R, boolean>, thisArg?: any): MinHeap<E, R> {
|
|
53
53
|
const filteredList = new MinHeap<E, R>([], { toElementFn: this.toElementFn, comparator: this.comparator });
|
|
54
54
|
let index = 0;
|
|
55
55
|
for (const current of this) {
|
|
@@ -83,7 +83,7 @@ export class MinHeap<E = any, R = any> extends Heap<E, R> {
|
|
|
83
83
|
* @returns a new instance of the `MinHeap` class with the mapped elements.
|
|
84
84
|
*/
|
|
85
85
|
override map<EM, RM>(
|
|
86
|
-
callback: ElementCallback<E, R, EM
|
|
86
|
+
callback: ElementCallback<E, R, EM>,
|
|
87
87
|
comparator: Comparator<EM>,
|
|
88
88
|
toElementFn?: (rawElement: RM) => EM,
|
|
89
89
|
thisArg?: any
|
|
@@ -6,86 +6,48 @@
|
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
8
|
import type { DoublyLinkedListOptions, ElementCallback } from '../../types';
|
|
9
|
-
import {
|
|
9
|
+
import { LinearLinkedBase, LinkedListNode } from '../base/linear-base';
|
|
10
10
|
|
|
11
|
-
export class DoublyLinkedListNode<E = any> {
|
|
11
|
+
export class DoublyLinkedListNode<E = any> extends LinkedListNode<E> {
|
|
12
12
|
/**
|
|
13
13
|
* The constructor function initializes the value, next, and previous properties of an object.
|
|
14
14
|
* @param {E} value - The "value" parameter is the value that will be stored in the node. It can be of any data type, as it
|
|
15
15
|
* is defined as a generic type "E".
|
|
16
16
|
*/
|
|
17
17
|
constructor(value: E) {
|
|
18
|
+
super(value);
|
|
18
19
|
this._value = value;
|
|
19
20
|
this._next = undefined;
|
|
20
21
|
this._prev = undefined;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
protected
|
|
24
|
+
protected override _next: DoublyLinkedListNode<E> | undefined;
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
* The function returns the value of a protected variable.
|
|
27
|
-
* @returns The value of the variable `_value` is being returned.
|
|
28
|
-
*/
|
|
29
|
-
get value(): E {
|
|
30
|
-
return this._value;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* The above function sets the value of a variable.
|
|
35
|
-
* @param {E} value - The parameter "value" is of type E, which means it can be any type.
|
|
36
|
-
*/
|
|
37
|
-
set value(value: E) {
|
|
38
|
-
this._value = value;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
protected _next: DoublyLinkedListNode<E> | undefined;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* The "next" function returns the next node in a doubly linked list.
|
|
45
|
-
* @returns The `next` property is being returned. It can be either a `DoublyLinkedListNode<E>`
|
|
46
|
-
* object or `undefined`.
|
|
47
|
-
*/
|
|
48
|
-
get next(): DoublyLinkedListNode<E> | undefined {
|
|
26
|
+
override get next(): DoublyLinkedListNode<E> | undefined {
|
|
49
27
|
return this._next;
|
|
50
28
|
}
|
|
51
29
|
|
|
52
|
-
|
|
53
|
-
* The "next" property of a DoublyLinkedListNode is set to the provided value.
|
|
54
|
-
* @param {DoublyLinkedListNode<E> | undefined} value - The `value` parameter is of type
|
|
55
|
-
* `DoublyLinkedListNode<E> | undefined`. This means that it can accept either a
|
|
56
|
-
* `DoublyLinkedListNode` object or `undefined` as its value.
|
|
57
|
-
*/
|
|
58
|
-
set next(value: DoublyLinkedListNode<E> | undefined) {
|
|
30
|
+
override set next(value: DoublyLinkedListNode<E> | undefined) {
|
|
59
31
|
this._next = value;
|
|
60
32
|
}
|
|
61
33
|
|
|
62
34
|
protected _prev: DoublyLinkedListNode<E> | undefined;
|
|
63
35
|
|
|
64
|
-
/**
|
|
65
|
-
* The `prev` function returns the previous node in a doubly linked list.
|
|
66
|
-
* @returns The `prev` property of the `DoublyLinkedListNode` class is being returned. It can either
|
|
67
|
-
* be a `DoublyLinkedListNode` object or `undefined`.
|
|
68
|
-
*/
|
|
69
36
|
get prev(): DoublyLinkedListNode<E> | undefined {
|
|
70
37
|
return this._prev;
|
|
71
38
|
}
|
|
72
39
|
|
|
73
|
-
/**
|
|
74
|
-
* The function sets the previous node of a doubly linked list node.
|
|
75
|
-
* @param {DoublyLinkedListNode<E> | undefined} value - The `value` parameter is of type
|
|
76
|
-
* `DoublyLinkedListNode<E> | undefined`. This means that it can accept either a
|
|
77
|
-
* `DoublyLinkedListNode` object or `undefined` as its value.
|
|
78
|
-
*/
|
|
79
40
|
set prev(value: DoublyLinkedListNode<E> | undefined) {
|
|
80
41
|
this._prev = value;
|
|
81
42
|
}
|
|
82
43
|
}
|
|
83
44
|
|
|
84
45
|
/**
|
|
85
|
-
*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.
|
|
46
|
+
* 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.
|
|
86
47
|
* 2. Bidirectional Traversal: Unlike singly linked lists, doubly linked lists can be easily traversed forwards or backwards. This makes insertions and deletions in the list more flexible and efficient.
|
|
87
48
|
* 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.
|
|
88
49
|
* 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.
|
|
50
|
+
* 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).
|
|
89
51
|
* @example
|
|
90
52
|
* // text editor operation history
|
|
91
53
|
* const actions = [
|
|
@@ -159,7 +121,7 @@ export class DoublyLinkedListNode<E = any> {
|
|
|
159
121
|
* const initialNode = this.currentSong;
|
|
160
122
|
*
|
|
161
123
|
* // Loop through the playlist twice
|
|
162
|
-
* for (let i = 0; i < this.playlist.
|
|
124
|
+
* for (let i = 0; i < this.playlist.length * 2; i++) {
|
|
163
125
|
* playedSongs.push(this.currentSong!.value);
|
|
164
126
|
* this.currentSong = this.currentSong!.next || this.playlist.head; // Loop back to the start if needed
|
|
165
127
|
* }
|
|
@@ -280,7 +242,7 @@ export class DoublyLinkedListNode<E = any> {
|
|
|
280
242
|
* }
|
|
281
243
|
*
|
|
282
244
|
* // Check capacity
|
|
283
|
-
* if (this.list.
|
|
245
|
+
* if (this.list.length >= this.capacity) {
|
|
284
246
|
* // Delete the least recently used element (the tail of the linked list)
|
|
285
247
|
* const removedNode = this.list.tail;
|
|
286
248
|
* if (removedNode) {
|
|
@@ -325,9 +287,9 @@ export class DoublyLinkedListNode<E = any> {
|
|
|
325
287
|
* this.map.clear();
|
|
326
288
|
* }
|
|
327
289
|
*
|
|
328
|
-
* // Get the current cache
|
|
329
|
-
* get
|
|
330
|
-
* return this.list.
|
|
290
|
+
* // Get the current cache length
|
|
291
|
+
* get length(): number {
|
|
292
|
+
* return this.list.length;
|
|
331
293
|
* }
|
|
332
294
|
*
|
|
333
295
|
* // Check if it is empty
|
|
@@ -386,7 +348,7 @@ export class DoublyLinkedListNode<E = any> {
|
|
|
386
348
|
*
|
|
387
349
|
* console.log(cache.delete('a')); // true
|
|
388
350
|
* console.log(cache.get('a')); // undefined
|
|
389
|
-
* console.log(cache.
|
|
351
|
+
* console.log(cache.length); // 1
|
|
390
352
|
*
|
|
391
353
|
* // Should support clearing cache
|
|
392
354
|
* cache.clear();
|
|
@@ -394,7 +356,7 @@ export class DoublyLinkedListNode<E = any> {
|
|
|
394
356
|
* cache.set('b', 2);
|
|
395
357
|
* cache.clear();
|
|
396
358
|
*
|
|
397
|
-
* console.log(cache.
|
|
359
|
+
* console.log(cache.length); // 0
|
|
398
360
|
* console.log(cache.isEmpty); // true
|
|
399
361
|
* @example
|
|
400
362
|
* // finding lyrics by timestamp in Coldplay's "Fix You"
|
|
@@ -513,7 +475,7 @@ export class DoublyLinkedListNode<E = any> {
|
|
|
513
475
|
* scheduler.clear();
|
|
514
476
|
* console.log(scheduler.listProcesses()); // []
|
|
515
477
|
*/
|
|
516
|
-
export class DoublyLinkedList<E = any, R = any> extends
|
|
478
|
+
export class DoublyLinkedList<E = any, R = any> extends LinearLinkedBase<E, R, DoublyLinkedListNode<E>> {
|
|
517
479
|
/**
|
|
518
480
|
* This TypeScript constructor initializes a DoublyLinkedList with optional elements and options.
|
|
519
481
|
* @param {Iterable<E> | Iterable<R>} elements - The `elements` parameter in the constructor is an
|
|
@@ -531,39 +493,32 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
531
493
|
super(options);
|
|
532
494
|
this._head = undefined;
|
|
533
495
|
this._tail = undefined;
|
|
534
|
-
this.
|
|
496
|
+
this._length = 0;
|
|
497
|
+
|
|
498
|
+
if (options) {
|
|
499
|
+
const { maxLen } = options;
|
|
500
|
+
if (typeof maxLen === 'number' && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
|
|
501
|
+
}
|
|
502
|
+
|
|
535
503
|
this.pushMany(elements);
|
|
536
504
|
}
|
|
537
505
|
|
|
538
506
|
protected _head: DoublyLinkedListNode<E> | undefined;
|
|
539
507
|
|
|
540
|
-
/**
|
|
541
|
-
* The `head` function returns the first node of a doubly linked list.
|
|
542
|
-
* @returns The method `getHead()` returns either a `DoublyLinkedListNode<E>` object or `undefined`.
|
|
543
|
-
*/
|
|
544
508
|
get head(): DoublyLinkedListNode<E> | undefined {
|
|
545
509
|
return this._head;
|
|
546
510
|
}
|
|
547
511
|
|
|
548
512
|
protected _tail: DoublyLinkedListNode<E> | undefined;
|
|
549
513
|
|
|
550
|
-
/**
|
|
551
|
-
* The `tail` function returns the last node of a doubly linked list.
|
|
552
|
-
* @returns The `get tail()` method is returning either a `DoublyLinkedListNode<E>` object or
|
|
553
|
-
* `undefined`.
|
|
554
|
-
*/
|
|
555
514
|
get tail(): DoublyLinkedListNode<E> | undefined {
|
|
556
515
|
return this._tail;
|
|
557
516
|
}
|
|
558
517
|
|
|
559
|
-
protected
|
|
518
|
+
protected _length: number;
|
|
560
519
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
* @returns The size of the object, which is a number.
|
|
564
|
-
*/
|
|
565
|
-
get size(): number {
|
|
566
|
-
return this._size;
|
|
520
|
+
get length(): number {
|
|
521
|
+
return this._length;
|
|
567
522
|
}
|
|
568
523
|
|
|
569
524
|
/**
|
|
@@ -640,7 +595,8 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
640
595
|
this.tail!.next = newNode;
|
|
641
596
|
this._tail = newNode;
|
|
642
597
|
}
|
|
643
|
-
this.
|
|
598
|
+
this._length++;
|
|
599
|
+
if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
|
|
644
600
|
return true;
|
|
645
601
|
}
|
|
646
602
|
|
|
@@ -661,7 +617,7 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
661
617
|
this._tail = removedNode.prev;
|
|
662
618
|
this.tail!.next = undefined;
|
|
663
619
|
}
|
|
664
|
-
this.
|
|
620
|
+
this._length--;
|
|
665
621
|
return removedNode.value;
|
|
666
622
|
}
|
|
667
623
|
|
|
@@ -682,7 +638,7 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
682
638
|
this._head = removedNode.next;
|
|
683
639
|
this.head!.prev = undefined;
|
|
684
640
|
}
|
|
685
|
-
this.
|
|
641
|
+
this._length--;
|
|
686
642
|
return removedNode.value;
|
|
687
643
|
}
|
|
688
644
|
|
|
@@ -706,7 +662,8 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
706
662
|
this.head!.prev = newNode;
|
|
707
663
|
this._head = newNode;
|
|
708
664
|
}
|
|
709
|
-
this.
|
|
665
|
+
this._length++;
|
|
666
|
+
if (this._maxLen > 0 && this._length > this._maxLen) this.pop();
|
|
710
667
|
return true;
|
|
711
668
|
}
|
|
712
669
|
|
|
@@ -772,7 +729,7 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
772
729
|
* or the linked list is empty, it will return undefined.
|
|
773
730
|
*/
|
|
774
731
|
at(index: number): E | undefined {
|
|
775
|
-
if (index < 0 || index >= this.
|
|
732
|
+
if (index < 0 || index >= this._length) return undefined;
|
|
776
733
|
let current = this.head;
|
|
777
734
|
for (let i = 0; i < index; i++) {
|
|
778
735
|
current = current!.next;
|
|
@@ -792,7 +749,7 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
792
749
|
* valid range of the linked list, otherwise it returns `undefined`.
|
|
793
750
|
*/
|
|
794
751
|
getNodeAt(index: number): DoublyLinkedListNode<E> | undefined {
|
|
795
|
-
if (index < 0 || index >= this.
|
|
752
|
+
if (index < 0 || index >= this._length) return undefined;
|
|
796
753
|
let current = this.head;
|
|
797
754
|
for (let i = 0; i < index; i++) {
|
|
798
755
|
current = current!.next;
|
|
@@ -822,6 +779,7 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
822
779
|
elementNodeOrPredicate: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean) | undefined
|
|
823
780
|
): DoublyLinkedListNode<E> | undefined {
|
|
824
781
|
if (elementNodeOrPredicate === undefined) return;
|
|
782
|
+
if (this.isNode(elementNodeOrPredicate)) return elementNodeOrPredicate;
|
|
825
783
|
const predicate = this._ensurePredicate(elementNodeOrPredicate);
|
|
826
784
|
let current = this.head;
|
|
827
785
|
|
|
@@ -847,15 +805,15 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
847
805
|
* `addAt` method can be either a value of type `E` or a `DoublyLinkedListNode<E>` object.
|
|
848
806
|
* @returns The `addAt` method returns a boolean value. It returns `true` if the element or node was
|
|
849
807
|
* successfully added at the specified index, and `false` if the index is out of bounds (less than 0
|
|
850
|
-
* or greater than the
|
|
808
|
+
* or greater than the length of the list).
|
|
851
809
|
*/
|
|
852
810
|
addAt(index: number, newElementOrNode: E | DoublyLinkedListNode<E>): boolean {
|
|
853
|
-
if (index < 0 || index > this.
|
|
811
|
+
if (index < 0 || index > this._length) return false;
|
|
854
812
|
if (index === 0) {
|
|
855
813
|
this.unshift(newElementOrNode);
|
|
856
814
|
return true;
|
|
857
815
|
}
|
|
858
|
-
if (index === this.
|
|
816
|
+
if (index === this._length) {
|
|
859
817
|
this.push(newElementOrNode);
|
|
860
818
|
return true;
|
|
861
819
|
}
|
|
@@ -867,7 +825,7 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
867
825
|
newNode.next = nextNode;
|
|
868
826
|
prevNode!.next = newNode;
|
|
869
827
|
nextNode!.prev = newNode;
|
|
870
|
-
this.
|
|
828
|
+
this._length++;
|
|
871
829
|
return true;
|
|
872
830
|
}
|
|
873
831
|
|
|
@@ -905,7 +863,7 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
905
863
|
if (existingNode === this.head) {
|
|
906
864
|
this._head = newNode;
|
|
907
865
|
}
|
|
908
|
-
this.
|
|
866
|
+
this._length++;
|
|
909
867
|
return true;
|
|
910
868
|
}
|
|
911
869
|
|
|
@@ -944,13 +902,35 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
944
902
|
if (existingNode === this.tail) {
|
|
945
903
|
this._tail = newNode;
|
|
946
904
|
}
|
|
947
|
-
this.
|
|
905
|
+
this._length++;
|
|
948
906
|
return true;
|
|
949
907
|
}
|
|
950
908
|
|
|
951
909
|
return false;
|
|
952
910
|
}
|
|
953
911
|
|
|
912
|
+
/**
|
|
913
|
+
* Time Complexity: O(n)
|
|
914
|
+
* Space Complexity: O(1)
|
|
915
|
+
*
|
|
916
|
+
* The function `setAt` updates the value at a specified index in a data structure if the index
|
|
917
|
+
* exists.
|
|
918
|
+
* @param {number} index - The `index` parameter in the `setAt` method refers to the position in the
|
|
919
|
+
* data structure where you want to set a new value.
|
|
920
|
+
* @param {E} value - The `value` parameter in the `setAt` method represents the new value that you
|
|
921
|
+
* want to set at the specified index in the data structure.
|
|
922
|
+
* @returns The `setAt` method returns a boolean value - `true` if the value at the specified index
|
|
923
|
+
* is successfully updated, and `false` if the index is out of bounds.
|
|
924
|
+
*/
|
|
925
|
+
setAt(index: number, value: E): boolean {
|
|
926
|
+
const node = this.getNodeAt(index);
|
|
927
|
+
if (node) {
|
|
928
|
+
node.value = value;
|
|
929
|
+
return true;
|
|
930
|
+
}
|
|
931
|
+
return false;
|
|
932
|
+
}
|
|
933
|
+
|
|
954
934
|
/**
|
|
955
935
|
* Time Complexity: O(n)
|
|
956
936
|
* Space Complexity: O(1)
|
|
@@ -961,15 +941,18 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
961
941
|
* @returns The method `deleteAt` returns the value of the node that was deleted, or `undefined` if the index is out of
|
|
962
942
|
* bounds.
|
|
963
943
|
*/
|
|
964
|
-
deleteAt(index: number):
|
|
965
|
-
if (index < 0 || index >= this.
|
|
944
|
+
deleteAt(index: number): E | undefined {
|
|
945
|
+
if (index < 0 || index >= this._length) return;
|
|
946
|
+
let deleted: E | undefined;
|
|
966
947
|
if (index === 0) {
|
|
948
|
+
deleted = this.first;
|
|
967
949
|
this.shift();
|
|
968
|
-
return
|
|
950
|
+
return deleted;
|
|
969
951
|
}
|
|
970
|
-
if (index === this.
|
|
952
|
+
if (index === this._length - 1) {
|
|
953
|
+
deleted = this.last;
|
|
971
954
|
this.pop();
|
|
972
|
-
return
|
|
955
|
+
return deleted;
|
|
973
956
|
}
|
|
974
957
|
|
|
975
958
|
const removedNode = this.getNodeAt(index);
|
|
@@ -977,8 +960,8 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
977
960
|
const nextNode = removedNode!.next;
|
|
978
961
|
prevNode!.next = nextNode;
|
|
979
962
|
nextNode!.prev = prevNode;
|
|
980
|
-
this.
|
|
981
|
-
return
|
|
963
|
+
this._length--;
|
|
964
|
+
return removedNode?.value;
|
|
982
965
|
}
|
|
983
966
|
|
|
984
967
|
/**
|
|
@@ -1007,7 +990,7 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
1007
990
|
const nextNode = node.next;
|
|
1008
991
|
if (prevNode) prevNode.next = nextNode;
|
|
1009
992
|
if (nextNode) nextNode.prev = prevNode;
|
|
1010
|
-
this.
|
|
993
|
+
this._length--;
|
|
1011
994
|
}
|
|
1012
995
|
return true;
|
|
1013
996
|
}
|
|
@@ -1018,48 +1001,23 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
1018
1001
|
* Time Complexity: O(1)
|
|
1019
1002
|
* Space Complexity: O(1)
|
|
1020
1003
|
*
|
|
1021
|
-
* The function checks if a variable has a
|
|
1004
|
+
* The function checks if a variable has a length greater than zero and returns a boolean value.
|
|
1022
1005
|
* @returns A boolean value is being returned.
|
|
1023
1006
|
*/
|
|
1024
1007
|
isEmpty(): boolean {
|
|
1025
|
-
return this.
|
|
1008
|
+
return this._length === 0;
|
|
1026
1009
|
}
|
|
1027
1010
|
|
|
1028
1011
|
/**
|
|
1029
1012
|
* Time Complexity: O(1)
|
|
1030
1013
|
* Space Complexity: O(1)
|
|
1031
1014
|
*
|
|
1032
|
-
* The `clear` function resets the linked list by setting the head, tail, and
|
|
1015
|
+
* The `clear` function resets the linked list by setting the head, tail, and length to undefined and 0 respectively.
|
|
1033
1016
|
*/
|
|
1034
1017
|
clear(): void {
|
|
1035
1018
|
this._head = undefined;
|
|
1036
1019
|
this._tail = undefined;
|
|
1037
|
-
this.
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
/**
|
|
1041
|
-
* Time Complexity: O(n)
|
|
1042
|
-
* Space Complexity: O(1)
|
|
1043
|
-
*
|
|
1044
|
-
* This function finds the index of a specified element, node, or predicate in a doubly linked list.
|
|
1045
|
-
* @param {E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)} elementNodeOrPredicate
|
|
1046
|
-
* elementNodeOrPredicate - The `indexOf` method takes in a parameter `elementNodeOrPredicate`, which
|
|
1047
|
-
* can be one of the following:
|
|
1048
|
-
* @returns The `indexOf` method returns the index of the element in the doubly linked list that
|
|
1049
|
-
* matches the provided element, node, or predicate. If no match is found, it returns -1.
|
|
1050
|
-
*/
|
|
1051
|
-
indexOf(elementNodeOrPredicate: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)): number {
|
|
1052
|
-
const predicate = this._ensurePredicate(elementNodeOrPredicate);
|
|
1053
|
-
let index = 0;
|
|
1054
|
-
let current = this.head;
|
|
1055
|
-
while (current) {
|
|
1056
|
-
if (predicate(current)) {
|
|
1057
|
-
return index;
|
|
1058
|
-
}
|
|
1059
|
-
index++;
|
|
1060
|
-
current = current.next;
|
|
1061
|
-
}
|
|
1062
|
-
return -1;
|
|
1020
|
+
this._length = 0;
|
|
1063
1021
|
}
|
|
1064
1022
|
|
|
1065
1023
|
/**
|
|
@@ -1128,40 +1086,6 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
1128
1086
|
return this;
|
|
1129
1087
|
}
|
|
1130
1088
|
|
|
1131
|
-
/**
|
|
1132
|
-
* Time Complexity: O(n)
|
|
1133
|
-
* Space Complexity: O(n)
|
|
1134
|
-
*
|
|
1135
|
-
* The `toArray` function converts a linked list into an array.
|
|
1136
|
-
* @returns The `toArray()` method is returning an array of type `E[]`.
|
|
1137
|
-
*/
|
|
1138
|
-
toArray(): E[] {
|
|
1139
|
-
const array: E[] = [];
|
|
1140
|
-
let current = this.head;
|
|
1141
|
-
while (current) {
|
|
1142
|
-
array.push(current.value);
|
|
1143
|
-
current = current.next;
|
|
1144
|
-
}
|
|
1145
|
-
return array;
|
|
1146
|
-
}
|
|
1147
|
-
|
|
1148
|
-
/**
|
|
1149
|
-
* Time Complexity: O(n)
|
|
1150
|
-
* Space Complexity: O(n)
|
|
1151
|
-
*
|
|
1152
|
-
* The `toReversedArray` function converts a doubly linked list into an array in reverse order.
|
|
1153
|
-
* @returns The `toReversedArray()` function returns an array of type `E[]`.
|
|
1154
|
-
*/
|
|
1155
|
-
toReversedArray(): E[] {
|
|
1156
|
-
const array: E[] = [];
|
|
1157
|
-
let current = this.tail;
|
|
1158
|
-
while (current) {
|
|
1159
|
-
array.push(current.value);
|
|
1160
|
-
current = current.prev;
|
|
1161
|
-
}
|
|
1162
|
-
return array;
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
1089
|
/**
|
|
1166
1090
|
* Time Complexity: O(n)
|
|
1167
1091
|
* Space Complexity: O(n)
|
|
@@ -1171,8 +1095,8 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
1171
1095
|
* @returns The `clone()` method is returning a new instance of the `DoublyLinkedList` class, which
|
|
1172
1096
|
* is a copy of the original list.
|
|
1173
1097
|
*/
|
|
1174
|
-
clone():
|
|
1175
|
-
return new DoublyLinkedList<E, R>(this);
|
|
1098
|
+
clone(): this {
|
|
1099
|
+
return new DoublyLinkedList<E, R>(this, { toElementFn: this._toElementFn, maxLen: this._maxLen }) as this;
|
|
1176
1100
|
}
|
|
1177
1101
|
|
|
1178
1102
|
/**
|
|
@@ -1192,8 +1116,8 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
1192
1116
|
* @returns The `filter` method is returning a new `DoublyLinkedList` object that contains the
|
|
1193
1117
|
* elements that pass the filter condition specified by the `callback` function.
|
|
1194
1118
|
*/
|
|
1195
|
-
filter(callback: ElementCallback<E, R, boolean
|
|
1196
|
-
const filteredList =
|
|
1119
|
+
filter(callback: ElementCallback<E, R, boolean>, thisArg?: any): DoublyLinkedList<E, R> {
|
|
1120
|
+
const filteredList = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1197
1121
|
let index = 0;
|
|
1198
1122
|
for (const current of this) {
|
|
1199
1123
|
if (callback.call(thisArg, current, index, this)) {
|
|
@@ -1225,11 +1149,11 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
1225
1149
|
* @returns a new instance of the `DoublyLinkedList` class with elements of type `T` and `RR`.
|
|
1226
1150
|
*/
|
|
1227
1151
|
map<EM, RM>(
|
|
1228
|
-
callback: ElementCallback<E, R, EM
|
|
1152
|
+
callback: ElementCallback<E, R, EM>,
|
|
1229
1153
|
toElementFn?: (rawElement: RM) => EM,
|
|
1230
1154
|
thisArg?: any
|
|
1231
1155
|
): DoublyLinkedList<EM, RM> {
|
|
1232
|
-
const mappedList = new DoublyLinkedList<EM, RM>([], { toElementFn });
|
|
1156
|
+
const mappedList = new DoublyLinkedList<EM, RM>([], { toElementFn, maxLen: this._maxLen });
|
|
1233
1157
|
let index = 0;
|
|
1234
1158
|
for (const current of this) {
|
|
1235
1159
|
mappedList.push(callback.call(thisArg, current, index, this));
|
|
@@ -1277,6 +1201,40 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
1277
1201
|
}
|
|
1278
1202
|
}
|
|
1279
1203
|
|
|
1204
|
+
/**
|
|
1205
|
+
* The function returns an iterator that iterates over the elements of a data structure in reverse
|
|
1206
|
+
* order.
|
|
1207
|
+
*/
|
|
1208
|
+
protected *_getReverseIterator(): IterableIterator<E> {
|
|
1209
|
+
let current = this.tail;
|
|
1210
|
+
|
|
1211
|
+
while (current) {
|
|
1212
|
+
yield current.value;
|
|
1213
|
+
current = current.prev;
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
/**
|
|
1218
|
+
* The function returns an iterator that iterates over the nodes of a doubly linked list starting
|
|
1219
|
+
* from the head.
|
|
1220
|
+
*/
|
|
1221
|
+
protected *_getNodeIterator(): IterableIterator<DoublyLinkedListNode<E>> {
|
|
1222
|
+
let current = this.head;
|
|
1223
|
+
|
|
1224
|
+
while (current) {
|
|
1225
|
+
yield current;
|
|
1226
|
+
current = current.next;
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
// protected *_getReverseNodeIterator(): IterableIterator<DoublyLinkedListNode<E>> {
|
|
1231
|
+
// const reversedArr = [...this._getNodeIterator()].reverse();
|
|
1232
|
+
//
|
|
1233
|
+
// for (const item of reversedArr) {
|
|
1234
|
+
// yield item;
|
|
1235
|
+
// }
|
|
1236
|
+
// }
|
|
1237
|
+
|
|
1280
1238
|
/**
|
|
1281
1239
|
* The function `_isPredicate` checks if the input is a function that takes a `DoublyLinkedListNode`
|
|
1282
1240
|
* as an argument and returns a boolean.
|
|
@@ -1325,4 +1283,30 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
1325
1283
|
|
|
1326
1284
|
return (node: DoublyLinkedListNode<E>) => node.value === elementNodeOrPredicate;
|
|
1327
1285
|
}
|
|
1286
|
+
|
|
1287
|
+
/**
|
|
1288
|
+
* The function `_createInstance` returns a new instance of `DoublyLinkedList` with the specified
|
|
1289
|
+
* options.
|
|
1290
|
+
* @param [options] - The `options` parameter in the `_createInstance` method is of type
|
|
1291
|
+
* `DoublyLinkedListOptions<E, R>`. It is an optional parameter that allows you to pass additional
|
|
1292
|
+
* configuration options when creating a new instance of the `DoublyLinkedList` class.
|
|
1293
|
+
* @returns An instance of the `DoublyLinkedList` class with an empty array and the provided options
|
|
1294
|
+
* is being returned, cast as the current class type.
|
|
1295
|
+
*/
|
|
1296
|
+
protected override _createInstance(options?: DoublyLinkedListOptions<E, R>): this {
|
|
1297
|
+
return new DoublyLinkedList<E, R>([], options) as this;
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
/**
|
|
1301
|
+
* The function `_getPrevNode` returns the previous node of a given node in a doubly linked list.
|
|
1302
|
+
* @param node - The parameter `node` in the `_getPrevNode` method is of type
|
|
1303
|
+
* `DoublyLinkedListNode<E>`, which represents a node in a doubly linked list containing an element
|
|
1304
|
+
* of type `E`.
|
|
1305
|
+
* @returns The `_getPrevNode` method is returning the previous node of the input `node` in a doubly
|
|
1306
|
+
* linked list. If the input node has a previous node, it will return that node. Otherwise, it will
|
|
1307
|
+
* return `undefined`.
|
|
1308
|
+
*/
|
|
1309
|
+
protected _getPrevNode(node: DoublyLinkedListNode<E>): DoublyLinkedListNode<E> | undefined {
|
|
1310
|
+
return node.prev;
|
|
1311
|
+
}
|
|
1328
1312
|
}
|