data-structure-typed 1.54.3 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/benchmark/report.html +26 -2
  3. package/benchmark/report.json +292 -42
  4. package/dist/cjs/data-structures/base/iterable-element-base.d.ts +14 -40
  5. package/dist/cjs/data-structures/base/iterable-element-base.js +14 -11
  6. package/dist/cjs/data-structures/base/iterable-element-base.js.map +1 -1
  7. package/dist/cjs/data-structures/base/linear-base.d.ts +277 -0
  8. package/dist/cjs/data-structures/base/linear-base.js +553 -0
  9. package/dist/cjs/data-structures/base/linear-base.js.map +1 -0
  10. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +12 -8
  11. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js +50 -37
  12. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
  13. package/dist/cjs/data-structures/binary-tree/avl-tree.d.ts +64 -0
  14. package/dist/cjs/data-structures/binary-tree/avl-tree.js +64 -0
  15. package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
  16. package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +62 -0
  17. package/dist/cjs/data-structures/binary-tree/binary-tree.js +67 -5
  18. package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
  19. package/dist/cjs/data-structures/binary-tree/bst.d.ts +3 -3
  20. package/dist/cjs/data-structures/binary-tree/bst.js +14 -14
  21. package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
  22. package/dist/cjs/data-structures/binary-tree/red-black-tree.d.ts +1 -7
  23. package/dist/cjs/data-structures/binary-tree/red-black-tree.js +1 -7
  24. package/dist/cjs/data-structures/binary-tree/red-black-tree.js.map +1 -1
  25. package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +175 -14
  26. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +210 -40
  27. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
  28. package/dist/cjs/data-structures/graph/abstract-graph.js +16 -16
  29. package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
  30. package/dist/cjs/data-structures/hash/hash-map.d.ts +46 -0
  31. package/dist/cjs/data-structures/hash/hash-map.js +46 -0
  32. package/dist/cjs/data-structures/hash/hash-map.js.map +1 -1
  33. package/dist/cjs/data-structures/heap/heap.d.ts +3 -11
  34. package/dist/cjs/data-structures/heap/heap.js +0 -10
  35. package/dist/cjs/data-structures/heap/heap.js.map +1 -1
  36. package/dist/cjs/data-structures/heap/max-heap.d.ts +2 -2
  37. package/dist/cjs/data-structures/heap/max-heap.js.map +1 -1
  38. package/dist/cjs/data-structures/heap/min-heap.d.ts +2 -2
  39. package/dist/cjs/data-structures/heap/min-heap.js.map +1 -1
  40. package/dist/cjs/data-structures/linked-list/doubly-linked-list.d.ts +65 -94
  41. package/dist/cjs/data-structures/linked-list/doubly-linked-list.js +131 -146
  42. package/dist/cjs/data-structures/linked-list/doubly-linked-list.js.map +1 -1
  43. package/dist/cjs/data-structures/linked-list/singly-linked-list.d.ts +145 -75
  44. package/dist/cjs/data-structures/linked-list/singly-linked-list.js +283 -169
  45. package/dist/cjs/data-structures/linked-list/singly-linked-list.js.map +1 -1
  46. package/dist/cjs/data-structures/priority-queue/max-priority-queue.d.ts +2 -2
  47. package/dist/cjs/data-structures/priority-queue/max-priority-queue.js.map +1 -1
  48. package/dist/cjs/data-structures/priority-queue/min-priority-queue.d.ts +2 -2
  49. package/dist/cjs/data-structures/priority-queue/min-priority-queue.js.map +1 -1
  50. package/dist/cjs/data-structures/priority-queue/priority-queue.d.ts +2 -2
  51. package/dist/cjs/data-structures/priority-queue/priority-queue.js.map +1 -1
  52. package/dist/cjs/data-structures/queue/deque.d.ts +130 -91
  53. package/dist/cjs/data-structures/queue/deque.js +269 -169
  54. package/dist/cjs/data-structures/queue/deque.js.map +1 -1
  55. package/dist/cjs/data-structures/queue/queue.d.ts +131 -40
  56. package/dist/cjs/data-structures/queue/queue.js +181 -50
  57. package/dist/cjs/data-structures/queue/queue.js.map +1 -1
  58. package/dist/cjs/data-structures/stack/stack.d.ts +124 -11
  59. package/dist/cjs/data-structures/stack/stack.js +121 -10
  60. package/dist/cjs/data-structures/stack/stack.js.map +1 -1
  61. package/dist/cjs/data-structures/trie/trie.d.ts +4 -3
  62. package/dist/cjs/data-structures/trie/trie.js +3 -0
  63. package/dist/cjs/data-structures/trie/trie.js.map +1 -1
  64. package/dist/cjs/types/data-structures/base/base.d.ts +9 -4
  65. package/dist/cjs/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -1
  66. package/dist/cjs/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
  67. package/dist/cjs/types/data-structures/linked-list/doubly-linked-list.d.ts +2 -2
  68. package/dist/cjs/types/data-structures/linked-list/singly-linked-list.d.ts +2 -2
  69. package/dist/cjs/types/data-structures/queue/deque.d.ts +2 -3
  70. package/dist/cjs/types/data-structures/queue/queue.d.ts +2 -2
  71. package/dist/esm/data-structures/base/iterable-element-base.d.ts +14 -40
  72. package/dist/esm/data-structures/base/iterable-element-base.js +14 -11
  73. package/dist/esm/data-structures/base/iterable-element-base.js.map +1 -1
  74. package/dist/esm/data-structures/base/linear-base.d.ts +277 -0
  75. package/dist/esm/data-structures/base/linear-base.js +549 -0
  76. package/dist/esm/data-structures/base/linear-base.js.map +1 -0
  77. package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.d.ts +12 -8
  78. package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.js +50 -36
  79. package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
  80. package/dist/esm/data-structures/binary-tree/avl-tree.d.ts +64 -0
  81. package/dist/esm/data-structures/binary-tree/avl-tree.js +64 -0
  82. package/dist/esm/data-structures/binary-tree/avl-tree.js.map +1 -1
  83. package/dist/esm/data-structures/binary-tree/binary-tree.d.ts +62 -0
  84. package/dist/esm/data-structures/binary-tree/binary-tree.js +67 -5
  85. package/dist/esm/data-structures/binary-tree/binary-tree.js.map +1 -1
  86. package/dist/esm/data-structures/binary-tree/bst.d.ts +3 -3
  87. package/dist/esm/data-structures/binary-tree/bst.js +14 -12
  88. package/dist/esm/data-structures/binary-tree/bst.js.map +1 -1
  89. package/dist/esm/data-structures/binary-tree/red-black-tree.d.ts +1 -7
  90. package/dist/esm/data-structures/binary-tree/red-black-tree.js +1 -7
  91. package/dist/esm/data-structures/binary-tree/red-black-tree.js.map +1 -1
  92. package/dist/esm/data-structures/binary-tree/tree-multi-map.d.ts +175 -14
  93. package/dist/esm/data-structures/binary-tree/tree-multi-map.js +210 -39
  94. package/dist/esm/data-structures/binary-tree/tree-multi-map.js.map +1 -1
  95. package/dist/esm/data-structures/graph/abstract-graph.js +16 -16
  96. package/dist/esm/data-structures/graph/abstract-graph.js.map +1 -1
  97. package/dist/esm/data-structures/hash/hash-map.d.ts +46 -0
  98. package/dist/esm/data-structures/hash/hash-map.js +46 -0
  99. package/dist/esm/data-structures/hash/hash-map.js.map +1 -1
  100. package/dist/esm/data-structures/heap/heap.d.ts +3 -11
  101. package/dist/esm/data-structures/heap/heap.js +0 -10
  102. package/dist/esm/data-structures/heap/heap.js.map +1 -1
  103. package/dist/esm/data-structures/heap/max-heap.d.ts +2 -2
  104. package/dist/esm/data-structures/heap/max-heap.js.map +1 -1
  105. package/dist/esm/data-structures/heap/min-heap.d.ts +2 -2
  106. package/dist/esm/data-structures/heap/min-heap.js.map +1 -1
  107. package/dist/esm/data-structures/linked-list/doubly-linked-list.d.ts +65 -94
  108. package/dist/esm/data-structures/linked-list/doubly-linked-list.js +132 -148
  109. package/dist/esm/data-structures/linked-list/doubly-linked-list.js.map +1 -1
  110. package/dist/esm/data-structures/linked-list/singly-linked-list.d.ts +145 -75
  111. package/dist/esm/data-structures/linked-list/singly-linked-list.js +283 -170
  112. package/dist/esm/data-structures/linked-list/singly-linked-list.js.map +1 -1
  113. package/dist/esm/data-structures/priority-queue/max-priority-queue.d.ts +2 -2
  114. package/dist/esm/data-structures/priority-queue/max-priority-queue.js.map +1 -1
  115. package/dist/esm/data-structures/priority-queue/min-priority-queue.d.ts +2 -2
  116. package/dist/esm/data-structures/priority-queue/min-priority-queue.js.map +1 -1
  117. package/dist/esm/data-structures/priority-queue/priority-queue.d.ts +2 -2
  118. package/dist/esm/data-structures/priority-queue/priority-queue.js.map +1 -1
  119. package/dist/esm/data-structures/queue/deque.d.ts +130 -91
  120. package/dist/esm/data-structures/queue/deque.js +269 -169
  121. package/dist/esm/data-structures/queue/deque.js.map +1 -1
  122. package/dist/esm/data-structures/queue/queue.d.ts +131 -40
  123. package/dist/esm/data-structures/queue/queue.js +182 -51
  124. package/dist/esm/data-structures/queue/queue.js.map +1 -1
  125. package/dist/esm/data-structures/stack/stack.d.ts +124 -11
  126. package/dist/esm/data-structures/stack/stack.js +121 -10
  127. package/dist/esm/data-structures/stack/stack.js.map +1 -1
  128. package/dist/esm/data-structures/trie/trie.d.ts +4 -3
  129. package/dist/esm/data-structures/trie/trie.js +3 -0
  130. package/dist/esm/data-structures/trie/trie.js.map +1 -1
  131. package/dist/esm/types/data-structures/base/base.d.ts +9 -4
  132. package/dist/esm/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -1
  133. package/dist/esm/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
  134. package/dist/esm/types/data-structures/linked-list/doubly-linked-list.d.ts +2 -2
  135. package/dist/esm/types/data-structures/linked-list/singly-linked-list.d.ts +2 -2
  136. package/dist/esm/types/data-structures/queue/deque.d.ts +2 -3
  137. package/dist/esm/types/data-structures/queue/queue.d.ts +2 -2
  138. package/dist/individuals/binary-tree/avl-tree-counter.mjs +4701 -0
  139. package/dist/individuals/binary-tree/avl-tree-multi-map.mjs +4514 -0
  140. package/dist/individuals/binary-tree/avl-tree.mjs +4321 -0
  141. package/dist/individuals/binary-tree/binary-tree.mjs +3097 -0
  142. package/dist/individuals/binary-tree/bst.mjs +3858 -0
  143. package/dist/individuals/binary-tree/red-black-tree.mjs +4391 -0
  144. package/dist/individuals/binary-tree/tree-counter.mjs +4806 -0
  145. package/dist/individuals/binary-tree/tree-multi-map.mjs +4582 -0
  146. package/dist/individuals/graph/directed-graph.mjs +2910 -0
  147. package/dist/individuals/graph/undirected-graph.mjs +2745 -0
  148. package/dist/individuals/hash/hash-map.mjs +1040 -0
  149. package/dist/individuals/heap/heap.mjs +909 -0
  150. package/dist/individuals/heap/max-heap.mjs +671 -0
  151. package/dist/individuals/heap/min-heap.mjs +659 -0
  152. package/dist/individuals/linked-list/doubly-linked-list.mjs +1495 -0
  153. package/dist/individuals/linked-list/singly-linked-list.mjs +1479 -0
  154. package/dist/individuals/priority-queue/max-priority-queue.mjs +768 -0
  155. package/dist/individuals/priority-queue/min-priority-queue.mjs +757 -0
  156. package/dist/individuals/priority-queue/priority-queue.mjs +670 -0
  157. package/dist/individuals/queue/deque.mjs +1262 -0
  158. package/dist/individuals/queue/queue.mjs +1865 -0
  159. package/dist/individuals/stack/stack.mjs +415 -0
  160. package/dist/individuals/trie/trie.mjs +687 -0
  161. package/dist/umd/data-structure-typed.js +1260 -649
  162. package/dist/umd/data-structure-typed.min.js +3 -3
  163. package/dist/umd/data-structure-typed.min.js.map +1 -1
  164. package/package.json +7 -7
  165. package/src/data-structures/base/iterable-element-base.ts +29 -20
  166. package/src/data-structures/base/linear-base.ts +649 -0
  167. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +51 -36
  168. package/src/data-structures/binary-tree/avl-tree.ts +64 -0
  169. package/src/data-structures/binary-tree/binary-tree.ts +5 -5
  170. package/src/data-structures/binary-tree/bst.ts +9 -9
  171. package/src/data-structures/binary-tree/tree-multi-map.ts +214 -40
  172. package/src/data-structures/graph/abstract-graph.ts +16 -16
  173. package/src/data-structures/hash/hash-map.ts +46 -0
  174. package/src/data-structures/heap/heap.ts +3 -14
  175. package/src/data-structures/heap/max-heap.ts +2 -2
  176. package/src/data-structures/heap/min-heap.ts +2 -2
  177. package/src/data-structures/linked-list/doubly-linked-list.ts +144 -160
  178. package/src/data-structures/linked-list/singly-linked-list.ts +307 -185
  179. package/src/data-structures/priority-queue/max-priority-queue.ts +2 -5
  180. package/src/data-structures/priority-queue/min-priority-queue.ts +2 -5
  181. package/src/data-structures/priority-queue/priority-queue.ts +2 -2
  182. package/src/data-structures/queue/deque.ts +286 -183
  183. package/src/data-structures/queue/queue.ts +196 -63
  184. package/src/data-structures/stack/stack.ts +124 -18
  185. package/src/data-structures/trie/trie.ts +7 -3
  186. package/src/types/data-structures/base/base.ts +17 -8
  187. package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +1 -1
  188. package/src/types/data-structures/binary-tree/tree-multi-map.ts +1 -1
  189. package/src/types/data-structures/linked-list/doubly-linked-list.ts +2 -2
  190. package/src/types/data-structures/linked-list/singly-linked-list.ts +2 -2
  191. package/src/types/data-structures/queue/deque.ts +2 -3
  192. package/src/types/data-structures/queue/queue.ts +2 -2
  193. package/test/integration/all-in-one.test.ts +1 -1
  194. package/test/integration/avl-tree.test.ts +1 -1
  195. package/test/integration/bst.test.ts +2 -2
  196. package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +168 -0
  197. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +15 -14
  198. package/test/unit/data-structures/binary-tree/red-black-tree.test.ts +1 -1
  199. package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +165 -7
  200. package/test/unit/data-structures/graph/directed-graph.test.ts +37 -37
  201. package/test/unit/data-structures/graph/undirected-graph.test.ts +2 -2
  202. package/test/unit/data-structures/hash/hash-map.test.ts +135 -0
  203. package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +135 -27
  204. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +183 -12
  205. package/test/unit/data-structures/queue/deque.test.ts +241 -60
  206. package/test/unit/data-structures/queue/queue.test.ts +332 -19
  207. package/test/unit/data-structures/stack/stack.test.ts +165 -0
  208. package/test/unit/unrestricted-interconversion.test.ts +1 -1
@@ -1,95 +1,121 @@
1
- import { IterableElementBase } from '../base';
2
- export class SinglyLinkedListNode {
1
+ import { LinearLinkedBase, LinkedListNode } from '../base/linear-base';
2
+ export class SinglyLinkedListNode extends LinkedListNode {
3
3
  /**
4
4
  * The constructor function initializes an instance of a class with a given value and sets the next property to undefined.
5
5
  * @param {E} value - The "value" parameter is of type E, which means it can be any data type. It represents the value that
6
6
  * will be stored in the node of a linked list.
7
7
  */
8
8
  constructor(value) {
9
+ super(value);
9
10
  this._value = value;
10
11
  this._next = undefined;
11
12
  }
12
- _value;
13
- /**
14
- * The function returns the value of a protected variable.
15
- * @returns The value of the variable `_value` is being returned.
16
- */
17
- get value() {
18
- return this._value;
19
- }
20
- /**
21
- * The above function sets the value of a variable.
22
- * @param {E} value - The parameter "value" is of type E, which means it can be any type.
23
- */
24
- set value(value) {
25
- this._value = value;
26
- }
27
13
  _next;
28
- /**
29
- * The `next` function returns the next node in a singly linked list.
30
- * @returns The `next` property is being returned. It can be either a `SinglyLinkedListNode<E>`
31
- * object or `undefined`.
32
- */
33
14
  get next() {
34
15
  return this._next;
35
16
  }
36
- /**
37
- * The "next" property of a SinglyLinkedListNode is set to the provided value.
38
- * @param {SinglyLinkedListNode<E> | undefined} value - The `value` parameter is of type
39
- * `SinglyLinkedListNode<E> | undefined`. This means that it can accept either a
40
- * `SinglyLinkedListNode` object or `undefined` as its value.
41
- */
42
17
  set next(value) {
43
18
  this._next = value;
44
19
  }
45
20
  }
46
21
  /**
22
+ * 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.
23
+ * 2. Bidirectional Traversal: Unlike doubly linked lists, singly linked lists can be easily traversed forwards but not backwards.
24
+ * 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.
25
+ * 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.
26
+ * 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).
27
+ *
28
+ * @example
29
+ * // implementation of a basic text editor
30
+ * class TextEditor {
31
+ * private content: SinglyLinkedList<string>;
32
+ * private cursorIndex: number;
33
+ * private undoStack: Stack<{ operation: string; data?: any }>;
34
+ *
35
+ * constructor() {
36
+ * this.content = new SinglyLinkedList<string>();
37
+ * this.cursorIndex = 0; // Cursor starts at the beginning
38
+ * this.undoStack = new Stack<{ operation: string; data?: any }>(); // Stack to keep track of operations for undo
39
+ * }
40
+ *
41
+ * insert(char: string) {
42
+ * this.content.addAt(this.cursorIndex, char);
43
+ * this.cursorIndex++;
44
+ * this.undoStack.push({ operation: 'insert', data: { index: this.cursorIndex - 1 } });
45
+ * }
46
+ *
47
+ * delete() {
48
+ * if (this.cursorIndex === 0) return; // Nothing to delete
49
+ * const deleted = this.content.deleteAt(this.cursorIndex - 1);
50
+ * this.cursorIndex--;
51
+ * this.undoStack.push({ operation: 'delete', data: { index: this.cursorIndex, char: deleted } });
52
+ * }
53
+ *
54
+ * moveCursor(index: number) {
55
+ * this.cursorIndex = Math.max(0, Math.min(index, this.content.length));
56
+ * }
57
+ *
58
+ * undo() {
59
+ * if (this.undoStack.size === 0) return; // No operations to undo
60
+ * const lastAction = this.undoStack.pop();
61
+ *
62
+ * if (lastAction!.operation === 'insert') {
63
+ * this.content.deleteAt(lastAction!.data.index);
64
+ * this.cursorIndex = lastAction!.data.index;
65
+ * } else if (lastAction!.operation === 'delete') {
66
+ * this.content.addAt(lastAction!.data.index, lastAction!.data.char);
67
+ * this.cursorIndex = lastAction!.data.index + 1;
68
+ * }
69
+ * }
47
70
  *
71
+ * getText(): string {
72
+ * return [...this.content].join('');
73
+ * }
74
+ * }
75
+ *
76
+ * // Example Usage
77
+ * const editor = new TextEditor();
78
+ * editor.insert('H');
79
+ * editor.insert('e');
80
+ * editor.insert('l');
81
+ * editor.insert('l');
82
+ * editor.insert('o');
83
+ * console.log(editor.getText()); // 'Hello' // Output: "Hello"
84
+ *
85
+ * editor.delete();
86
+ * console.log(editor.getText()); // 'Hell' // Output: "Hell"
87
+ *
88
+ * editor.undo();
89
+ * console.log(editor.getText()); // 'Hello' // Output: "Hello"
90
+ *
91
+ * editor.moveCursor(1);
92
+ * editor.insert('a');
93
+ * console.log(editor.getText()); // 'Haello'
48
94
  */
49
- export class SinglyLinkedList extends IterableElementBase {
95
+ export class SinglyLinkedList extends LinearLinkedBase {
50
96
  constructor(elements = [], options) {
51
97
  super(options);
98
+ if (options) {
99
+ }
52
100
  this.pushMany(elements);
53
101
  }
54
102
  _head;
55
- /**
56
- * The `head` function returns the first node of a singly linked list.
57
- * @returns The method is returning either a SinglyLinkedListNode object or undefined.
58
- */
59
103
  get head() {
60
104
  return this._head;
61
105
  }
62
106
  _tail;
63
- /**
64
- * The `tail` function returns the last node of a singly linked list.
65
- * @returns The method is returning either a SinglyLinkedListNode object or undefined.
66
- */
67
107
  get tail() {
68
108
  return this._tail;
69
109
  }
70
- /**
71
- * The above function returns the value of the first element in a linked list, or undefined if the
72
- * list is empty.
73
- * @returns The value of the first node in the linked list, or undefined if the linked list is empty.
74
- */
75
110
  get first() {
76
111
  return this.head?.value;
77
112
  }
78
- /**
79
- * The function returns the value of the last element in a linked list, or undefined if the list is
80
- * empty.
81
- * @returns The value of the last node in the linked list, or undefined if the linked list is empty.
82
- */
83
113
  get last() {
84
114
  return this.tail?.value;
85
115
  }
86
- _size = 0;
87
- /**
88
- * The function returns the size of an object.
89
- * @returns The size of the object, which is a number.
90
- */
91
- get size() {
92
- return this._size;
116
+ _length = 0;
117
+ get length() {
118
+ return this._length;
93
119
  }
94
120
  /**
95
121
  * Time Complexity: O(n)
@@ -126,7 +152,9 @@ export class SinglyLinkedList extends IterableElementBase {
126
152
  this.tail.next = newNode;
127
153
  this._tail = newNode;
128
154
  }
129
- this._size++;
155
+ this._length++;
156
+ if (this._maxLen > 0 && this.length > this._maxLen)
157
+ this.shift();
130
158
  return true;
131
159
  }
132
160
  /**
@@ -144,7 +172,7 @@ export class SinglyLinkedList extends IterableElementBase {
144
172
  const value = this.head.value;
145
173
  this._head = undefined;
146
174
  this._tail = undefined;
147
- this._size--;
175
+ this._length--;
148
176
  return value;
149
177
  }
150
178
  let current = this.head;
@@ -154,7 +182,7 @@ export class SinglyLinkedList extends IterableElementBase {
154
182
  const value = this.tail.value;
155
183
  current.next = undefined;
156
184
  this._tail = current;
157
- this._size--;
185
+ this._length--;
158
186
  return value;
159
187
  }
160
188
  /**
@@ -169,7 +197,7 @@ export class SinglyLinkedList extends IterableElementBase {
169
197
  return undefined;
170
198
  const removedNode = this.head;
171
199
  this._head = this.head.next;
172
- this._size--;
200
+ this._length--;
173
201
  return removedNode.value;
174
202
  }
175
203
  /**
@@ -193,7 +221,7 @@ export class SinglyLinkedList extends IterableElementBase {
193
221
  newNode.next = this.head;
194
222
  this._head = newNode;
195
223
  }
196
- this._size++;
224
+ this._length++;
197
225
  return true;
198
226
  }
199
227
  /**
@@ -276,7 +304,7 @@ export class SinglyLinkedList extends IterableElementBase {
276
304
  * `undefined` if the index is out of bounds.
277
305
  */
278
306
  at(index) {
279
- if (index < 0 || index >= this._size)
307
+ if (index < 0 || index >= this._length)
280
308
  return undefined;
281
309
  let current = this.head;
282
310
  for (let i = 0; i < index; i++) {
@@ -328,21 +356,25 @@ export class SinglyLinkedList extends IterableElementBase {
328
356
  * bounds.
329
357
  */
330
358
  deleteAt(index) {
331
- if (index < 0 || index >= this._size)
332
- return false;
359
+ if (index < 0 || index >= this._length)
360
+ return;
361
+ let deleted;
333
362
  if (index === 0) {
363
+ deleted = this.first;
334
364
  this.shift();
335
- return true;
365
+ return deleted;
336
366
  }
337
- if (index === this._size - 1) {
338
- this.pop();
339
- return true;
367
+ const targetNode = this.getNodeAt(index);
368
+ const prevNode = this._getPrevNode(targetNode);
369
+ if (prevNode && targetNode) {
370
+ deleted = targetNode.value;
371
+ prevNode.next = targetNode.next;
372
+ if (targetNode === this.tail)
373
+ this._tail = prevNode;
374
+ this._length--;
375
+ return deleted;
340
376
  }
341
- const prevNode = this.getNodeAt(index - 1);
342
- const removedNode = prevNode.next;
343
- prevNode.next = removedNode.next;
344
- this._size--;
345
- return true;
377
+ return;
346
378
  }
347
379
  /**
348
380
  * Time Complexity: O(n)
@@ -355,37 +387,25 @@ export class SinglyLinkedList extends IterableElementBase {
355
387
  * successfully deleted from the linked list, and `false` if the value or node is not found in the linked list.
356
388
  */
357
389
  delete(elementOrNode) {
358
- if (elementOrNode === undefined)
390
+ if (elementOrNode === undefined || !this.head)
359
391
  return false;
360
- let value;
361
- if (elementOrNode instanceof SinglyLinkedListNode) {
362
- value = elementOrNode.value;
392
+ const node = this.isNode(elementOrNode) ? elementOrNode : this.getNode(elementOrNode);
393
+ if (!node)
394
+ return false;
395
+ const prevNode = this._getPrevNode(node);
396
+ if (!prevNode) {
397
+ // The node is the head
398
+ this._head = node.next;
399
+ if (node === this.tail)
400
+ this._tail = undefined;
363
401
  }
364
402
  else {
365
- value = elementOrNode;
403
+ prevNode.next = node.next;
404
+ if (node === this.tail)
405
+ this._tail = prevNode;
366
406
  }
367
- let current = this.head, prev = undefined;
368
- while (current) {
369
- if (current.value === value) {
370
- if (prev === undefined) {
371
- this._head = current.next;
372
- if (current === this.tail) {
373
- this._tail = undefined;
374
- }
375
- }
376
- else {
377
- prev.next = current.next;
378
- if (current === this.tail) {
379
- this._tail = prev;
380
- }
381
- }
382
- this._size--;
383
- return true;
384
- }
385
- prev = current;
386
- current = current.next;
387
- }
388
- return false;
407
+ this._length--;
408
+ return true;
389
409
  }
390
410
  /**
391
411
  * Time Complexity: O(n)
@@ -403,13 +423,13 @@ export class SinglyLinkedList extends IterableElementBase {
403
423
  * successfully added at the specified index, and `false` if the index is out of bounds.
404
424
  */
405
425
  addAt(index, newElementOrNode) {
406
- if (index < 0 || index > this._size)
426
+ if (index < 0 || index > this._length)
407
427
  return false;
408
428
  if (index === 0) {
409
429
  this.unshift(newElementOrNode);
410
430
  return true;
411
431
  }
412
- if (index === this._size) {
432
+ if (index === this._length) {
413
433
  this.push(newElementOrNode);
414
434
  return true;
415
435
  }
@@ -417,9 +437,31 @@ export class SinglyLinkedList extends IterableElementBase {
417
437
  const prevNode = this.getNodeAt(index - 1);
418
438
  newNode.next = prevNode.next;
419
439
  prevNode.next = newNode;
420
- this._size++;
440
+ this._length++;
421
441
  return true;
422
442
  }
443
+ /**
444
+ * Time Complexity: O(n)
445
+ * Space Complexity: O(1)
446
+ *
447
+ * The function setAt(index, value) updates the value at a specified index in a data structure if the
448
+ * index exists.
449
+ * @param {number} index - The `index` parameter in the `setAt` method refers to the position in the
450
+ * data structure where you want to set a new value.
451
+ * @param {E} value - The `value` parameter in the `setAt` method represents the new value that you
452
+ * want to set at the specified index in the data structure.
453
+ * @returns The `setAt` method returns a boolean value - `true` if the value at the specified index
454
+ * is successfully updated, and `false` if the index is out of bounds (i.e., the node at that index
455
+ * does not exist).
456
+ */
457
+ setAt(index, value) {
458
+ const node = this.getNodeAt(index);
459
+ if (node) {
460
+ node.value = value;
461
+ return true;
462
+ }
463
+ return false;
464
+ }
423
465
  /**
424
466
  * Time Complexity: O(1)
425
467
  * Space Complexity: O(1)
@@ -429,7 +471,7 @@ export class SinglyLinkedList extends IterableElementBase {
429
471
  * @returns A boolean value indicating whether the length of the object is equal to 0.
430
472
  */
431
473
  isEmpty() {
432
- return this._size === 0;
474
+ return this._length === 0;
433
475
  }
434
476
  /**
435
477
  * Time Complexity: O(1)
@@ -440,23 +482,7 @@ export class SinglyLinkedList extends IterableElementBase {
440
482
  clear() {
441
483
  this._head = undefined;
442
484
  this._tail = undefined;
443
- this._size = 0;
444
- }
445
- /**
446
- * Time Complexity: O(n)
447
- * Space Complexity: O(n)
448
- *
449
- * The `toArray` function converts a linked list into an array.
450
- * @returns The `toArray()` method is returning an array of type `E[]`.
451
- */
452
- toArray() {
453
- const array = [];
454
- let current = this.head;
455
- while (current) {
456
- array.push(current.value);
457
- current = current.next;
458
- }
459
- return array;
485
+ this._length = 0;
460
486
  }
461
487
  /**
462
488
  * Time Complexity: O(n)
@@ -480,32 +506,6 @@ export class SinglyLinkedList extends IterableElementBase {
480
506
  [this._head, this._tail] = [this.tail, this.head];
481
507
  return this;
482
508
  }
483
- /**
484
- * Time Complexity: O(n)
485
- * Space Complexity: O(1)
486
- *
487
- * The `indexOf` function in TypeScript searches for a specific element or node in a singly linked
488
- * list and returns its index if found.
489
- * @param {E | SinglyLinkedListNode<E> | ((node: SinglyLinkedListNode<E>) => boolean)} elementNodeOrPredicate
490
- * elementNodeOrPredicate - The `elementNodeOrPredicate` parameter in the `indexOf` method can be one
491
- * of the following types:
492
- * @returns The `indexOf` method returns the index of the first occurrence of the element that
493
- * matches the provided predicate in the singly linked list. If no matching element is found, it
494
- * returns -1.
495
- */
496
- indexOf(elementNodeOrPredicate) {
497
- const predicate = this._ensurePredicate(elementNodeOrPredicate);
498
- let index = 0;
499
- let current = this.head;
500
- while (current) {
501
- if (predicate(current)) {
502
- return index;
503
- }
504
- index++;
505
- current = current.next;
506
- }
507
- return -1;
508
- }
509
509
  /**
510
510
  * Time Complexity: O(n)
511
511
  * Space Complexity: O(1)
@@ -522,6 +522,8 @@ export class SinglyLinkedList extends IterableElementBase {
522
522
  getNode(elementNodeOrPredicate) {
523
523
  if (elementNodeOrPredicate === undefined)
524
524
  return;
525
+ if (this.isNode(elementNodeOrPredicate))
526
+ return elementNodeOrPredicate;
525
527
  const predicate = this._ensurePredicate(elementNodeOrPredicate);
526
528
  let current = this.head;
527
529
  while (current) {
@@ -549,31 +551,21 @@ export class SinglyLinkedList extends IterableElementBase {
549
551
  * unsuccessful.
550
552
  */
551
553
  addBefore(existingElementOrNode, newElementOrNode) {
552
- if (!this.head)
554
+ const existingNode = this.getNode(existingElementOrNode);
555
+ if (!existingNode)
553
556
  return false;
554
- let existingValue;
555
- if (this.isNode(existingElementOrNode)) {
556
- existingValue = existingElementOrNode.value;
557
+ const prevNode = this._getPrevNode(existingNode);
558
+ const newNode = this._ensureNode(newElementOrNode);
559
+ if (!prevNode) {
560
+ // Add at the head
561
+ this.unshift(newNode);
557
562
  }
558
563
  else {
559
- existingValue = existingElementOrNode;
564
+ prevNode.next = newNode;
565
+ newNode.next = existingNode;
566
+ this._length++;
560
567
  }
561
- if (this.head.value === existingValue) {
562
- this.unshift(newElementOrNode);
563
- return true;
564
- }
565
- let current = this.head;
566
- while (current.next) {
567
- if (current.next.value === existingValue) {
568
- const newNode = this._ensureNode(newElementOrNode);
569
- newNode.next = current.next;
570
- current.next = newNode;
571
- this._size++;
572
- return true;
573
- }
574
- current = current.next;
575
- }
576
- return false;
568
+ return true;
577
569
  }
578
570
  /**
579
571
  * Time Complexity: O(n)
@@ -600,11 +592,74 @@ export class SinglyLinkedList extends IterableElementBase {
600
592
  if (existingNode === this.tail) {
601
593
  this._tail = newNode;
602
594
  }
603
- this._size++;
595
+ this._length++;
604
596
  return true;
605
597
  }
606
598
  return false;
607
599
  }
600
+ /**
601
+ * Time Complexity: O(n)
602
+ * Space Complexity: O(1)
603
+ *
604
+ * The function `splice` in TypeScript overrides the default behavior to remove and insert elements
605
+ * in a singly linked list while handling boundary cases.
606
+ * @param {number} start - The `start` parameter in the `splice` method indicates the index at which
607
+ * to start modifying the list. It specifies the position where elements will be added or removed.
608
+ * @param {number} [deleteCount=0] - The `deleteCount` parameter in the `splice` method specifies the
609
+ * number of elements to remove from the array starting at the specified `start` index. If
610
+ * `deleteCount` is not provided, it defaults to 0, meaning no elements will be removed but new
611
+ * elements can still be inserted at
612
+ * @param {E[]} items - The `items` parameter in the `splice` method represents the elements to be
613
+ * inserted into the list at the specified `start` index. These elements will be inserted in place of
614
+ * the elements that are removed from the list. The `splice` method allows you to add new elements to
615
+ * the list while
616
+ * @returns The `splice` method is returning a `SinglyLinkedList` containing the elements that were
617
+ * removed from the original list during the splice operation.
618
+ */
619
+ splice(start, deleteCount = 0, ...items) {
620
+ const removedList = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
621
+ // If `start` is out of range, perform boundary processing
622
+ start = Math.max(0, Math.min(start, this.length));
623
+ deleteCount = Math.max(0, deleteCount);
624
+ // Find the predecessor node of `start`
625
+ const prevNode = start === 0 ? undefined : this.getNodeAt(start - 1);
626
+ const startNode = prevNode ? prevNode.next : this.head;
627
+ let current = startNode;
628
+ for (let i = 0; i < deleteCount && current; i++) {
629
+ removedList.push(current.value);
630
+ current = current.next;
631
+ }
632
+ const nextNode = current;
633
+ let lastInsertedNode = undefined;
634
+ for (const item of items) {
635
+ const newNode = this._ensureNode(item);
636
+ if (!lastInsertedNode) {
637
+ if (prevNode) {
638
+ prevNode.next = newNode;
639
+ }
640
+ else {
641
+ this._head = newNode;
642
+ }
643
+ }
644
+ else {
645
+ lastInsertedNode.next = newNode;
646
+ }
647
+ lastInsertedNode = newNode;
648
+ }
649
+ // Connect new node to `nextNode`
650
+ if (lastInsertedNode) {
651
+ lastInsertedNode.next = nextNode;
652
+ }
653
+ else if (prevNode) {
654
+ prevNode.next = nextNode;
655
+ }
656
+ // Update tail node and length
657
+ if (!nextNode) {
658
+ this._tail = lastInsertedNode || prevNode;
659
+ }
660
+ this._length += items.length - removedList.length;
661
+ return removedList;
662
+ }
608
663
  /**
609
664
  * Time Complexity: O(n)
610
665
  * Space Complexity: O(1)
@@ -638,7 +693,7 @@ export class SinglyLinkedList extends IterableElementBase {
638
693
  * is a clone of the original list.
639
694
  */
640
695
  clone() {
641
- return new SinglyLinkedList(this, { toElementFn: this.toElementFn });
696
+ return new SinglyLinkedList(this, { toElementFn: this.toElementFn, maxLen: this._maxLen });
642
697
  }
643
698
  /**
644
699
  * Time Complexity: O(n)
@@ -658,7 +713,7 @@ export class SinglyLinkedList extends IterableElementBase {
658
713
  * elements that pass the filter condition specified by the `callback` function.
659
714
  */
660
715
  filter(callback, thisArg) {
661
- const filteredList = new SinglyLinkedList([], { toElementFn: this.toElementFn });
716
+ const filteredList = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
662
717
  let index = 0;
663
718
  for (const current of this) {
664
719
  if (callback.call(thisArg, current, index, this)) {
@@ -689,7 +744,7 @@ export class SinglyLinkedList extends IterableElementBase {
689
744
  * @returns a new instance of the `SinglyLinkedList` class with the mapped elements.
690
745
  */
691
746
  map(callback, toElementFn, thisArg) {
692
- const mappedList = new SinglyLinkedList([], { toElementFn });
747
+ const mappedList = new SinglyLinkedList([], { toElementFn, maxLen: this._maxLen });
693
748
  let index = 0;
694
749
  for (const current of this) {
695
750
  mappedList.push(callback.call(thisArg, current, index, this));
@@ -697,6 +752,19 @@ export class SinglyLinkedList extends IterableElementBase {
697
752
  }
698
753
  return mappedList;
699
754
  }
755
+ /**
756
+ * The function `_createInstance` returns a new instance of `SinglyLinkedList` with the specified
757
+ * options.
758
+ * @param [options] - The `options` parameter in the `_createInstance` method is of type
759
+ * `SinglyLinkedListOptions<E, R>`, which is used to configure the behavior of the `SinglyLinkedList`
760
+ * instance being created. It is an optional parameter, meaning it can be omitted when calling the
761
+ * method.
762
+ * @returns An instance of the `SinglyLinkedList` class with an empty array and the provided options
763
+ * is being returned.
764
+ */
765
+ _createInstance(options) {
766
+ return new SinglyLinkedList([], options);
767
+ }
700
768
  /**
701
769
  * The function `_getIterator` returns an iterable iterator that yields the values of a linked list.
702
770
  */
@@ -707,6 +775,33 @@ export class SinglyLinkedList extends IterableElementBase {
707
775
  current = current.next;
708
776
  }
709
777
  }
778
+ /**
779
+ * The function returns an iterator that iterates over the elements of a collection in reverse order.
780
+ */
781
+ *_getReverseIterator() {
782
+ const reversedArr = [...this].reverse();
783
+ for (const item of reversedArr) {
784
+ yield item;
785
+ }
786
+ }
787
+ /**
788
+ * The function `_getNodeIterator` returns an iterator that iterates over the nodes of a singly
789
+ * linked list.
790
+ */
791
+ *_getNodeIterator() {
792
+ let current = this.head;
793
+ while (current) {
794
+ yield current;
795
+ current = current.next;
796
+ }
797
+ }
798
+ // protected *_getReverseNodeIterator(): IterableIterator<SinglyLinkedListNode<E>> {
799
+ // const reversedArr = [...this._getNodeIterator()].reverse();
800
+ //
801
+ // for (const item of reversedArr) {
802
+ // yield item;
803
+ // }
804
+ // }
710
805
  /**
711
806
  * The _isPredicate function in TypeScript checks if the input is a function that takes a
712
807
  * SinglyLinkedListNode as an argument and returns a boolean.
@@ -749,5 +844,23 @@ export class SinglyLinkedList extends IterableElementBase {
749
844
  return elementNodeOrPredicate;
750
845
  return (node) => node.value === elementNodeOrPredicate;
751
846
  }
847
+ /**
848
+ * The function `_getPrevNode` returns the node before a given node in a singly linked list.
849
+ * @param node - The `node` parameter in the `_getPrevNode` method is a reference to a node in a
850
+ * singly linked list. The method is used to find the node that comes before the given node in the
851
+ * linked list.
852
+ * @returns The `_getPrevNode` method returns either the previous node of the input node in a singly
853
+ * linked list or `undefined` if the input node is the head of the list or if the input node is not
854
+ * found in the list.
855
+ */
856
+ _getPrevNode(node) {
857
+ if (!this.head || this.head === node)
858
+ return undefined;
859
+ let current = this.head;
860
+ while (current.next && current.next !== node) {
861
+ current = current.next;
862
+ }
863
+ return current.next === node ? current : undefined;
864
+ }
752
865
  }
753
866
  //# sourceMappingURL=singly-linked-list.js.map