graph-typed 1.54.2 → 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.
Files changed (84) hide show
  1. package/dist/data-structures/base/iterable-element-base.d.ts +14 -40
  2. package/dist/data-structures/base/iterable-element-base.js +14 -11
  3. package/dist/data-structures/base/linear-base.d.ts +277 -0
  4. package/dist/data-structures/base/linear-base.js +552 -0
  5. package/dist/data-structures/binary-tree/avl-tree-counter.d.ts +21 -20
  6. package/dist/data-structures/binary-tree/avl-tree-counter.js +8 -7
  7. package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +23 -19
  8. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +51 -38
  9. package/dist/data-structures/binary-tree/avl-tree.d.ts +89 -21
  10. package/dist/data-structures/binary-tree/avl-tree.js +76 -8
  11. package/dist/data-structures/binary-tree/binary-tree.d.ts +173 -225
  12. package/dist/data-structures/binary-tree/binary-tree.js +244 -149
  13. package/dist/data-structures/binary-tree/bst.d.ts +62 -56
  14. package/dist/data-structures/binary-tree/bst.js +89 -133
  15. package/dist/data-structures/binary-tree/red-black-tree.d.ts +19 -25
  16. package/dist/data-structures/binary-tree/red-black-tree.js +7 -13
  17. package/dist/data-structures/binary-tree/tree-counter.d.ts +19 -19
  18. package/dist/data-structures/binary-tree/tree-counter.js +12 -12
  19. package/dist/data-structures/binary-tree/tree-multi-map.d.ts +186 -25
  20. package/dist/data-structures/binary-tree/tree-multi-map.js +211 -41
  21. package/dist/data-structures/graph/abstract-graph.js +2 -2
  22. package/dist/data-structures/heap/heap.d.ts +3 -11
  23. package/dist/data-structures/heap/heap.js +0 -10
  24. package/dist/data-structures/heap/max-heap.d.ts +2 -2
  25. package/dist/data-structures/heap/min-heap.d.ts +2 -2
  26. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +65 -94
  27. package/dist/data-structures/linked-list/doubly-linked-list.js +131 -146
  28. package/dist/data-structures/linked-list/singly-linked-list.d.ts +79 -75
  29. package/dist/data-structures/linked-list/singly-linked-list.js +217 -169
  30. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +2 -2
  31. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +2 -2
  32. package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -2
  33. package/dist/data-structures/queue/deque.d.ts +130 -91
  34. package/dist/data-structures/queue/deque.js +269 -169
  35. package/dist/data-structures/queue/queue.d.ts +84 -40
  36. package/dist/data-structures/queue/queue.js +134 -50
  37. package/dist/data-structures/stack/stack.d.ts +3 -11
  38. package/dist/data-structures/stack/stack.js +0 -10
  39. package/dist/data-structures/trie/trie.d.ts +4 -3
  40. package/dist/data-structures/trie/trie.js +3 -0
  41. package/dist/types/data-structures/base/base.d.ts +9 -4
  42. package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -1
  43. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -0
  44. package/dist/types/data-structures/binary-tree/bst.d.ts +1 -1
  45. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
  46. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +2 -2
  47. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +2 -2
  48. package/dist/types/data-structures/queue/deque.d.ts +2 -3
  49. package/dist/types/data-structures/queue/queue.d.ts +2 -2
  50. package/dist/utils/utils.d.ts +2 -2
  51. package/package.json +2 -2
  52. package/src/data-structures/base/iterable-element-base.ts +29 -20
  53. package/src/data-structures/base/linear-base.ts +649 -0
  54. package/src/data-structures/binary-tree/avl-tree-counter.ts +30 -23
  55. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +74 -49
  56. package/src/data-structures/binary-tree/avl-tree.ts +99 -29
  57. package/src/data-structures/binary-tree/binary-tree.ts +474 -257
  58. package/src/data-structures/binary-tree/bst.ts +150 -152
  59. package/src/data-structures/binary-tree/red-black-tree.ts +27 -35
  60. package/src/data-structures/binary-tree/tree-counter.ts +33 -27
  61. package/src/data-structures/binary-tree/tree-multi-map.ts +235 -53
  62. package/src/data-structures/graph/abstract-graph.ts +2 -2
  63. package/src/data-structures/heap/heap.ts +3 -14
  64. package/src/data-structures/heap/max-heap.ts +2 -2
  65. package/src/data-structures/heap/min-heap.ts +2 -2
  66. package/src/data-structures/linked-list/doubly-linked-list.ts +144 -160
  67. package/src/data-structures/linked-list/singly-linked-list.ts +241 -185
  68. package/src/data-structures/priority-queue/max-priority-queue.ts +2 -5
  69. package/src/data-structures/priority-queue/min-priority-queue.ts +2 -5
  70. package/src/data-structures/priority-queue/priority-queue.ts +2 -2
  71. package/src/data-structures/queue/deque.ts +286 -183
  72. package/src/data-structures/queue/queue.ts +149 -63
  73. package/src/data-structures/stack/stack.ts +3 -18
  74. package/src/data-structures/trie/trie.ts +7 -3
  75. package/src/types/data-structures/base/base.ts +17 -8
  76. package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +1 -1
  77. package/src/types/data-structures/binary-tree/binary-tree.ts +1 -0
  78. package/src/types/data-structures/binary-tree/bst.ts +1 -1
  79. package/src/types/data-structures/binary-tree/tree-multi-map.ts +1 -1
  80. package/src/types/data-structures/linked-list/doubly-linked-list.ts +2 -2
  81. package/src/types/data-structures/linked-list/singly-linked-list.ts +2 -2
  82. package/src/types/data-structures/queue/deque.ts +2 -3
  83. package/src/types/data-structures/queue/queue.ts +2 -2
  84. package/src/utils/utils.ts +2 -2
@@ -6,86 +6,48 @@
6
6
  * @license MIT License
7
7
  */
8
8
  import type { DoublyLinkedListOptions, ElementCallback } from '../../types';
9
- import { IterableElementBase } from '../base';
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 _value: E;
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.size * 2; i++) {
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.size >= this.capacity) {
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 size
329
- * get size(): number {
330
- * return this.list.size;
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.size); // 1
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.size); // 0
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 IterableElementBase<E, R, DoublyLinkedList<E, R>> {
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._size = 0;
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 _size: number;
518
+ protected _length: number;
560
519
 
561
- /**
562
- * The function returns the size of an object.
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._size++;
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._size--;
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._size--;
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._size++;
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._size) return undefined;
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._size) return undefined;
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 size of the list).
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._size) return false;
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._size) {
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._size++;
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._size++;
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._size++;
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): boolean {
965
- if (index < 0 || index >= this._size) return false;
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 true;
950
+ return deleted;
969
951
  }
970
- if (index === this._size - 1) {
952
+ if (index === this._length - 1) {
953
+ deleted = this.last;
971
954
  this.pop();
972
- return true;
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._size--;
981
- return true;
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._size--;
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 size greater than zero and returns a boolean value.
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._size === 0;
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 size to undefined and 0 respectively.
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._size = 0;
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(): DoublyLinkedList<E, R> {
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, DoublyLinkedList<E, R>>, thisArg?: any): DoublyLinkedList<E, R> {
1196
- const filteredList = new DoublyLinkedList<E, R>([], { toElementFn: this.toElementFn });
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, DoublyLinkedList<E, R>>,
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
  }