data-structure-typed 1.12.21 → 1.15.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 (48) hide show
  1. package/README.md +278 -179
  2. package/dist/data-structures/binary-tree/binary-tree.d.ts +46 -1
  3. package/dist/data-structures/binary-tree/binary-tree.js +67 -0
  4. package/dist/data-structures/binary-tree/segment-tree.d.ts +29 -0
  5. package/dist/data-structures/binary-tree/segment-tree.js +45 -0
  6. package/dist/data-structures/graph/abstract-graph.d.ts +40 -5
  7. package/dist/data-structures/graph/abstract-graph.js +47 -7
  8. package/dist/data-structures/graph/directed-graph.d.ts +8 -0
  9. package/dist/data-structures/graph/directed-graph.js +14 -2
  10. package/dist/data-structures/graph/undirected-graph.d.ts +10 -0
  11. package/dist/data-structures/graph/undirected-graph.js +23 -1
  12. package/dist/data-structures/hash/coordinate-map.d.ts +7 -1
  13. package/dist/data-structures/hash/coordinate-map.js +16 -0
  14. package/dist/data-structures/hash/coordinate-set.d.ts +7 -1
  15. package/dist/data-structures/hash/coordinate-set.js +16 -0
  16. package/dist/data-structures/heap/heap.d.ts +16 -0
  17. package/dist/data-structures/heap/heap.js +38 -0
  18. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +30 -7
  19. package/dist/data-structures/linked-list/doubly-linked-list.js +71 -4
  20. package/dist/data-structures/linked-list/singly-linked-list.d.ts +262 -328
  21. package/dist/data-structures/linked-list/singly-linked-list.js +258 -273
  22. package/dist/data-structures/priority-queue/priority-queue.d.ts +7 -1
  23. package/dist/data-structures/priority-queue/priority-queue.js +18 -2
  24. package/dist/data-structures/queue/deque.d.ts +18 -7
  25. package/dist/data-structures/queue/deque.js +50 -3
  26. package/dist/data-structures/types/abstract-graph.d.ts +2 -2
  27. package/dist/utils/types/utils.d.ts +0 -49
  28. package/dist/utils/types/utils.js +14 -52
  29. package/dist/utils/utils.d.ts +1 -97
  30. package/dist/utils/utils.js +197 -546
  31. package/package.json +4 -3
  32. package/src/data-structures/binary-tree/aa-tree.ts +1 -1
  33. package/src/data-structures/binary-tree/binary-tree.ts +84 -14
  34. package/src/data-structures/binary-tree/segment-tree.ts +45 -13
  35. package/src/data-structures/graph/abstract-graph.ts +58 -15
  36. package/src/data-structures/graph/directed-graph.ts +14 -5
  37. package/src/data-structures/graph/undirected-graph.ts +23 -6
  38. package/src/data-structures/hash/coordinate-map.ts +13 -1
  39. package/src/data-structures/hash/coordinate-set.ts +13 -1
  40. package/src/data-structures/heap/heap.ts +31 -0
  41. package/src/data-structures/linked-list/doubly-linked-list.ts +68 -11
  42. package/src/data-structures/linked-list/singly-linked-list.ts +312 -334
  43. package/src/data-structures/priority-queue/priority-queue.ts +15 -2
  44. package/src/data-structures/queue/deque.ts +38 -8
  45. package/src/data-structures/types/abstract-graph.ts +3 -3
  46. package/src/utils/types/utils.ts +165 -167
  47. package/src/utils/utils.ts +209 -480
  48. package/tests/unit/data-structures/graph/directed-graph.test.ts +431 -8
@@ -6,81 +6,88 @@
6
6
  * @license MIT License
7
7
  */
8
8
 
9
- /**
10
- * The class which represents one link or node in a linked list
11
- * ```ts
12
- * const node = new SinglyLinkedListNode(1, null, null, null);
13
- * ```
14
- */
15
- export class SinglyLinkedListNode<NodeData = any> {
16
- constructor(
17
- /** Data stored on the node */
18
- public val: NodeData,
19
- /** The previous node in the list */
20
- public prev: SinglyLinkedListNode<NodeData> | null,
21
- /** The next link in the list */
22
- public next: SinglyLinkedListNode<NodeData> | null,
23
- /** The list this node belongs to */
24
- public list: SinglyLinkedList<NodeData> | null,
25
- ) {
9
+
10
+ /* The SinglyLinkedListNode class represents a node in a singly linked list and provides methods for inserting, removing,
11
+ and accessing nodes. */
12
+ export class SinglyLinkedListNode<NodeVal = any> {
13
+ protected _val: NodeVal;
14
+ get val(): NodeVal {
15
+ return this._val;
26
16
  }
27
17
 
28
- /**
29
- * Alias to .val
30
- * ```ts
31
- * new LinkedList(1, 2, 3).head.value; // 1
32
- * ```
33
- */
34
- public get value() {
35
- return this.val;
18
+ set val(value: NodeVal) {
19
+ this._val = value;
36
20
  }
37
21
 
38
- /**
39
- * Get the index of this node
40
- * ```ts
41
- * new LinkedList(1, 2, 3).head.index; // 0
42
- * ```
43
- */
44
- public get index() {
22
+ protected _prev: SinglyLinkedListNode<NodeVal> | null;
23
+ get prev(): SinglyLinkedListNode<NodeVal> | null {
24
+ return this._prev;
25
+ }
26
+
27
+ set prev(value: SinglyLinkedListNode<NodeVal> | null) {
28
+ this._prev = value;
29
+ }
30
+
31
+ protected _next: SinglyLinkedListNode<NodeVal> | null
32
+ get next(): SinglyLinkedListNode<NodeVal> | null {
33
+ return this._next;
34
+ }
35
+
36
+ set next(value: SinglyLinkedListNode<NodeVal> | null) {
37
+ this._next = value;
38
+ }
39
+
40
+ protected _list: SinglyLinkedList<NodeVal> | null
41
+ get list(): SinglyLinkedList<NodeVal> | null {
42
+ return this._list;
43
+ }
44
+
45
+ set list(value: SinglyLinkedList<NodeVal> | null) {
46
+ this._list = value;
47
+ }
48
+
49
+ constructor(val: NodeVal, prev?: SinglyLinkedListNode<NodeVal> | null, next?: SinglyLinkedListNode<NodeVal> | null, list?: SinglyLinkedList<NodeVal> | null) {
50
+ this._val = val;
51
+ this._prev = prev || null;
52
+ this._next = next || null;
53
+ this._list = list || null;
54
+ }
55
+
56
+ get index() {
45
57
  if (!this.list) {
46
58
  return undefined;
47
59
  }
48
- return this.list.findIndex((value) => value === this.value);
60
+ return this.list.findIndex((value) => value === this.val);
49
61
  }
50
62
 
51
63
  /**
52
- * Insert a new node before this one
53
- * ```ts
54
- * new LinkedList(2, 3).head.insertBefore(1); // 1 <=> 2 <=> 3
55
- * ```
56
- * @param val Data to save in the node
64
+ * The `insertBefore` function inserts a new node with the given value before the current node in a singly linked list.
65
+ * @param {NodeVal} val - The parameter "val" is of type "NodeVal". It represents the value of the node that you want
66
+ * to insert before the current node.
67
+ * @returns The method is returning a SinglyLinkedList<NodeVal>.
57
68
  */
58
- public insertBefore(val: NodeData): SinglyLinkedList<NodeData> {
69
+ insertBefore(val: NodeVal): SinglyLinkedList<NodeVal> {
59
70
  return this.list !== null
60
71
  ? this.list.insertBefore(this, val)
61
72
  : new SinglyLinkedList(val, this.val);
62
73
  }
63
74
 
64
75
  /**
65
- * Insert new val after this node
66
- * ```ts
67
- * new LinkedList(1, 2).tail.insertAfter(3); // 1 <=> 2 <=> 3
68
- * ```
69
- * @param val Data to be saved in the node
76
+ * The function inserts a new node with the given value after the current node in a singly linked list.
77
+ * @param {NodeVal} val - The parameter `val` is the value of the node that you want to insert after the current node.
78
+ * @returns The method is returning a SinglyLinkedList<NodeVal>.
70
79
  */
71
- public insertAfter(val: NodeData): SinglyLinkedList<NodeData> {
80
+ insertAfter(val: NodeVal): SinglyLinkedList<NodeVal> {
72
81
  return this.list !== null
73
82
  ? this.list.insertAfter(this, val)
74
83
  : new SinglyLinkedList(this.val, val);
75
84
  }
76
85
 
77
86
  /**
78
- * Remove this node
79
- * ```ts
80
- * new LinkedList(1, 2, 3, 4).tail.remove(); // 1 <=> 2 <=> 3
81
- * ```
87
+ * The `remove()` function removes a node from a singly linked list.
88
+ * @returns The remove() method is returning a SinglyLinkedListNode<NodeVal> object.
82
89
  */
83
- public remove(): SinglyLinkedListNode<NodeData> {
90
+ remove(): SinglyLinkedListNode<NodeVal> {
84
91
  if (this.list === null) {
85
92
  throw new ReferenceError('Node does not belong to any list');
86
93
  }
@@ -88,77 +95,82 @@ export class SinglyLinkedListNode<NodeData = any> {
88
95
  }
89
96
  }
90
97
 
98
+ export class SinglyLinkedList<NodeVal = any> {
91
99
 
92
- /**
93
- * A doubly linked list
94
- * ```ts
95
- * const list = new LinkedList(1, 2, 3);
96
- * const listFromArray = LinkedList.from([1, 2, 3]);
97
- * ```
98
- */
99
- export class SinglyLinkedList<NodeData = any> {
100
+ protected _head: SinglyLinkedListNode<NodeVal> | null;
101
+ get head(): SinglyLinkedListNode<NodeVal> | null {
102
+ return this._head;
103
+ }
104
+ set head(value: SinglyLinkedListNode<NodeVal> | null) {
105
+ this._head = value;
106
+ }
100
107
 
101
- /** The head of the list, the first node */
102
- public head: SinglyLinkedListNode<NodeData> | null;
103
- /** The tail of the list, the last node */
104
- public tail: SinglyLinkedListNode<NodeData> | null;
105
- /** Internal size reference */
106
- private size: number;
107
108
 
108
- constructor(...args: NodeData[]) {
109
- this.head = null;
110
- this.tail = null;
111
- this.size = 0;
109
+ protected _tail: SinglyLinkedListNode<NodeVal> | null;
110
+ get tail(): SinglyLinkedListNode<NodeVal> | null {
111
+ return this._tail;
112
+ }
113
+ set tail(value: SinglyLinkedListNode<NodeVal> | null) {
114
+ this._tail = value;
115
+ }
112
116
 
113
- for (let i = 0; i < arguments.length; i++) {
114
- this.append(args[i]);
115
- }
117
+ protected _size: number;
118
+ get size(): number {
119
+ return this._size;
120
+ }
121
+ set size(value: number) {
122
+ this._size = value;
116
123
  }
117
124
 
118
125
  /**
119
- * The length of the list
126
+ * The constructor initializes a linked list with the given arguments as nodes.
127
+ * @param {NodeVal[]} args - args is a rest parameter that allows the constructor to accept an arbitrary number of
128
+ * arguments of type NodeVal.
120
129
  */
121
- public get length(): number {
122
- return this.size;
130
+ constructor(...args: NodeVal[]) {
131
+ this._head = null;
132
+ this._tail = null;
133
+ this._size = 0;
134
+
135
+ for (let i = 0; i < arguments.length; i++) {
136
+ this.append(args[i]);
137
+ }
123
138
  }
124
139
 
125
140
  /**
126
- * Convert any iterable to a new linked list
127
- * ```javascript
128
- * const array = [1, 2, 3];
129
- * const list = LinkedList.from(array);
130
- * ```
131
- * @param iterable Any iterable datatype like Array or Map
141
+ * The `from` function in TypeScript creates a new SinglyLinkedList instance from an iterable object.
142
+ * @param iterable - The `iterable` parameter is an object that can be iterated over, such as an array or a string. It
143
+ * contains a collection of elements of type `T`.
144
+ * @returns The method is returning a new instance of the SinglyLinkedList class.
132
145
  */
133
- public static from<T>(iterable: Iterable<T>): SinglyLinkedList<T> {
146
+ static from<T>(iterable: Iterable<T>): SinglyLinkedList<T> {
134
147
  return new SinglyLinkedList(...iterable);
135
148
  }
136
149
 
137
150
  /**
138
- * Get the node val at a specified index, zero based
139
- * ```ts
140
- * new LinkedList(1, 2, 3).get(0); // 1
141
- * ```
142
- * @param index to retrieve val at
151
+ * The `get` function returns the value of a node at a given index in a data structure.
152
+ * @param {number} index - The index parameter is a number that represents the position of the node in the data
153
+ * structure.
154
+ * @returns The method is returning the value of the node at the specified index if the node exists, otherwise it
155
+ * returns undefined.
143
156
  */
144
- public get(index: number): NodeData | undefined {
157
+ get(index: number): NodeVal | undefined {
145
158
  const node = this.getNode(index);
146
159
  return node !== undefined ? node.val : undefined;
147
160
  }
148
161
 
149
162
  /**
150
- * Get the node at index, zero based
151
- * ```ts
152
- * new LinkedList(1, 2, 3).getNode(0);
153
- * // { prev: null, val: 1, next: SinglyLinkedListNode }
154
- * ```
163
+ * The function `getNode` returns the node at a given index in a singly linked list.
164
+ * @param {number} index - The `index` parameter is a number that represents the position of the node we want to
165
+ * retrieve from the linked list.
166
+ * @returns a SinglyLinkedListNode<NodeVal> object or undefined.
155
167
  */
156
- public getNode(index: number): SinglyLinkedListNode<NodeData> | undefined {
157
- if (this.head === null || index < 0 || index >= this.length) {
168
+ getNode(index: number): SinglyLinkedListNode<NodeVal> | undefined {
169
+ if (this.head === null || index < 0 || index >= this.size) {
158
170
  return undefined;
159
171
  }
160
- const asc = index < this.length / 2;
161
- const stopAt = asc ? index : this.length - index - 1;
172
+ const asc = index < this.size / 2;
173
+ const stopAt = asc ? index : this.size - index - 1;
162
174
  const nextNode = asc ? 'next' : 'prev';
163
175
  let currentNode = asc ? this.head : this.tail;
164
176
  // TODO after no-non-null-assertion not ensure the logic
@@ -171,26 +183,28 @@ export class SinglyLinkedList<NodeData = any> {
171
183
  }
172
184
 
173
185
  /**
174
- * Return the first node and its index in the list that
175
- * satisfies the testing function
176
- * ```ts
177
- * new LinkedList(1, 2, 3).findNodeIndex(val => val === 1);
178
- * // { node: SinglyLinkedListNode, index: 0 }
179
- * ```
180
- * @param f A function to be applied to the val of each node
186
+ * The function `findNodeIndex` searches for a node in a singly linked list that satisfies a given condition and
187
+ * returns its index and the node itself.
188
+ * @param callbackFn - The callbackFn parameter is a function that takes three arguments: data, index, and list. It is
189
+ * used to determine whether a node in the singly linked list matches a certain condition. The function should return a
190
+ * boolean value indicating whether the condition is met for the given node.
191
+ * @returns The function `findNodeIndex` returns an object with two properties: `node` and `index`. The `node` property
192
+ * contains the node that matches the condition specified in the `callbackFn` function, and the `index` property
193
+ * contains the index of that node in the linked list. If no node matches the condition, the function returns
194
+ * `undefined`.
181
195
  */
182
- public findNodeIndex(f: (
183
- data: NodeData,
196
+ findNodeIndex(callbackFn: (
197
+ data: NodeVal,
184
198
  index: number,
185
- list: SinglyLinkedList<NodeData>,
199
+ list: SinglyLinkedList<NodeVal>,
186
200
  ) => boolean): ({
187
- node: SinglyLinkedListNode<NodeData>,
201
+ node: SinglyLinkedListNode<NodeVal>,
188
202
  index: number,
189
203
  }) | undefined {
190
204
  let currentIndex = 0;
191
205
  let currentNode = this.head;
192
206
  while (currentNode) {
193
- if (f(currentNode.val, currentIndex, this)) {
207
+ if (callbackFn(currentNode.val, currentIndex, this)) {
194
208
  return {
195
209
  index: currentIndex,
196
210
  node: currentNode,
@@ -203,67 +217,56 @@ export class SinglyLinkedList<NodeData = any> {
203
217
  }
204
218
 
205
219
  /**
206
- * Returns the first node in the list that
207
- * satisfies the provided testing function. Otherwise undefined is returned.
208
- * ```ts
209
- * new LinkedList(1, 2, 3).findNode(val => val === 1);
210
- * // { prev: null, val: 1, next: SinglyLinkedListNode }
211
- * ```
212
- * @param f Function to test val against
220
+ * The findNode function searches for a node in a singly linked list based on a given callback function.
221
+ * @param callbackFn - A callback function that takes three parameters: data, index, and list. It returns a boolean
222
+ * value indicating whether the current node matches the desired criteria.
223
+ * @returns The function `findNode` returns a `SinglyLinkedListNode<NodeVal>` if a node satisfying the condition
224
+ * specified by the `callbackFn` is found in the linked list. If no such node is found, it returns `undefined`.
213
225
  */
214
- public findNode(f: (
215
- data: NodeData,
226
+ findNode(callbackFn: (
227
+ data: NodeVal,
216
228
  index: number,
217
- list: SinglyLinkedList<NodeData>,
218
- ) => boolean): SinglyLinkedListNode<NodeData> | undefined {
219
- const nodeIndex = this.findNodeIndex(f);
229
+ list: SinglyLinkedList<NodeVal>,
230
+ ) => boolean): SinglyLinkedListNode<NodeVal> | undefined {
231
+ const nodeIndex = this.findNodeIndex(callbackFn);
220
232
  return nodeIndex !== undefined ? nodeIndex.node : undefined;
221
233
  }
222
234
 
223
235
  /**
224
- * Returns the value of the first element in the list that
225
- * satisfies the provided testing function. Otherwise undefined is returned.
226
- * ```ts
227
- * new LinkedList(1, 2, 3).find(val => val === 1); // 1
228
- * ```
229
- * @param f Function to test val against
236
+ * The `find` function in TypeScript searches for a node in a singly linked list based on a given callback function and
237
+ * returns the value of the found node.
238
+ * @param callbackFn - A callback function that takes three parameters: data, index, and list. It returns a boolean
239
+ * value indicating whether the condition is met for a particular node in the linked list.
240
+ * @returns The method `find` returns the `NodeVal` value of the first node in the linked list that satisfies the
241
+ * condition specified by the `callbackFn` function. If no node satisfies the condition, it returns `undefined`.
230
242
  */
231
- public find(f: (
232
- data: NodeData,
243
+ find(callbackFn: (
244
+ data: NodeVal,
233
245
  index: number,
234
- list: SinglyLinkedList<NodeData>,
235
- ) => boolean): NodeData | undefined {
236
- const nodeIndex = this.findNodeIndex(f);
246
+ list: SinglyLinkedList<NodeVal>,
247
+ ) => boolean): NodeVal | undefined {
248
+ const nodeIndex = this.findNodeIndex(callbackFn);
237
249
  return nodeIndex !== undefined ? nodeIndex.node.val : undefined;
238
250
  }
239
251
 
240
252
  /**
241
- * Returns the index of the first node in the list that
242
- * satisfies the provided testing function. Ohterwise -1 is returned.
243
- * ```ts
244
- * new LinkedList(1, 2, 3).findIndex(val => val === 3); // 2
245
- * ```
246
- * @param f Function to test val against
253
+ * The findIndex function returns the index of the first node in a singly linked list that satisfies a given condition,
254
+ * or -1 if no such node is found.
255
+ * @param callbackFn - A callback function that takes three parameters: data, index, and list. It returns a boolean
256
+ * value indicating whether the condition is met for a particular node in the singly linked list.
257
+ * @returns The method `findIndex` returns a number.
247
258
  */
248
- public findIndex(f: (
249
- data: NodeData,
259
+ findIndex(callbackFn: (
260
+ data: NodeVal,
250
261
  index: number,
251
- list: SinglyLinkedList<NodeData>,
262
+ list: SinglyLinkedList<NodeVal>,
252
263
  ) => boolean): number {
253
- const nodeIndex = this.findNodeIndex(f);
264
+ const nodeIndex = this.findNodeIndex(callbackFn);
254
265
  return nodeIndex !== undefined ? nodeIndex.index : -1;
255
266
  }
256
267
 
257
- /**
258
- * Append one or any number of nodes to the end of the list.
259
- * This modifies the list in place and returns the list itself
260
- * to make this method chainable.
261
- * ```ts
262
- * new LinkedList(1).append(2).append(3, 4); // 1 <=> 2 <=> 3 <=> 4
263
- * ```
264
- * @param args Data to be stored in the node, takes any number of arguments
265
- */
266
- public append(...args: NodeData[]): SinglyLinkedList<NodeData> {
268
+ /* The above code is a comment in TypeScript. It is using the triple hash symbol ( */
269
+ append(...args: NodeVal[]): SinglyLinkedList<NodeVal> {
267
270
  for (const val of args) {
268
271
  const node = new SinglyLinkedListNode(val, this.tail, null, this);
269
272
  if (this.head === null) {
@@ -279,26 +282,23 @@ export class SinglyLinkedList<NodeData = any> {
279
282
  }
280
283
 
281
284
  /**
282
- * Synonym for append
283
- * ```ts
284
- * new LinkedList(1).push(2).push(3, 4); // 1 <=> 2 <=> 3 <=> 4
285
- * ```
286
- * @param args Data to be stored, takes any number of arguments
285
+ * The push function appends multiple NodeVal objects to a data structure and returns the new size of the data
286
+ * structure.
287
+ * @param {NodeVal[]} args - args is a rest parameter of type NodeVal[]. It allows the function to accept any number
288
+ * of arguments of type NodeVal.
289
+ * @returns The size of the data structure after the nodes are appended.
287
290
  */
288
- public push(...args: NodeData[]): number {
291
+ push(...args: NodeVal[]): number {
289
292
  this.append(...args);
290
- return this.length;
293
+ return this.size;
291
294
  }
292
295
 
293
296
  /**
294
- * Prepend any number of val arguments to the list. The
295
- * argument list is prepended as a block to reduce confusion:
296
- * ```javascript
297
- * new LinkedList(3, 4).prepend(0, 1, 2); // [0, 1, 2, 3, 4]
298
- * ```
299
- * @param args Data to be stored in the node, accepts any number of arguments
297
+ * The `prepend` function adds new nodes to the beginning of a singly linked list.
298
+ * @param {NodeVal[]} args - An array of NodeVal objects.
299
+ * @returns The `prepend` method is returning the updated `SinglyLinkedList` object.
300
300
  */
301
- public prepend(...args: NodeData[]): SinglyLinkedList<NodeData> {
301
+ prepend(...args: NodeVal[]): SinglyLinkedList<NodeVal> {
302
302
  const reverseArgs = Array.from(args).reverse();
303
303
  for (const val of reverseArgs) {
304
304
  const node = new SinglyLinkedListNode(val, null, this.head, this);
@@ -315,16 +315,14 @@ export class SinglyLinkedList<NodeData = any> {
315
315
  }
316
316
 
317
317
  /**
318
- * Insert a new node at a given index position. If index is
319
- * out of bounds, the node is appended, if index is negative
320
- * or 0, it will be prepended.
321
- * ```ts
322
- * new LinkedList(1, 3).insertAt(1, 2); // 1 <=> 2 <=> 3
323
- * ```
324
- * @param index The index to insert the new node at
325
- * @param val Data to be stored on the new node
318
+ * The `insertAt` function inserts a value at a specified index in a singly linked list.
319
+ * @param {number} index - The index parameter is a number that represents the position at which the new node should be
320
+ * inserted in the linked list.
321
+ * @param {NodeVal} val - The `val` parameter represents the value of the node that you want to insert into the linked
322
+ * list.
323
+ * @returns The method `insertAt` returns the updated `SinglyLinkedList` object.
326
324
  */
327
- public insertAt(index: number, val: NodeData): SinglyLinkedList<NodeData> {
325
+ insertAt(index: number, val: NodeVal): SinglyLinkedList<NodeVal> {
328
326
  if (this.head === null) {
329
327
  return this.append(val);
330
328
  }
@@ -343,15 +341,13 @@ export class SinglyLinkedList<NodeData = any> {
343
341
  }
344
342
 
345
343
  /**
346
- * Remove the specified node from the list and return the removed
347
- * node afterwards.
348
- * ```ts
349
- * const list = new LinkedList(1, 2, 3);
350
- * list.removeNode(list.tail); // { prev: null, val: 3, next: null, list: null }
351
- * ```
352
- * @param node The node to be removed
344
+ * The removeNode function removes a node from a singly linked list and updates the head, tail, and size properties
345
+ * accordingly.
346
+ * @param node - The `node` parameter is of type `SinglyLinkedListNode<NodeVal>`, which represents a node in a singly
347
+ * linked list.
348
+ * @returns the removed node.
353
349
  */
354
- public removeNode(node: SinglyLinkedListNode<NodeData>): SinglyLinkedListNode<NodeData> {
350
+ removeNode(node: SinglyLinkedListNode<NodeVal>): SinglyLinkedListNode<NodeVal> {
355
351
  if (node.list !== this) {
356
352
  throw new ReferenceError('Node does not belong to this list');
357
353
  }
@@ -380,30 +376,29 @@ export class SinglyLinkedList<NodeData = any> {
380
376
  }
381
377
 
382
378
  /**
383
- * Remove the node at the specified index
384
- * ```ts
385
- * new LinkedList(1, 2, 3).removeAt(2); // { prev: null, val: 3, next: null, list: null }
386
- * ```
387
- * @param index Index at which to remove
379
+ * The `removeAt` function removes a node at a specified index from a singly linked list.
380
+ * @param {number} index - The index parameter is a number that represents the position of the node to be removed in
381
+ * the singly linked list.
382
+ * @returns The method `removeAt` returns a `SinglyLinkedListNode<NodeVal>` if the node at the specified index is
383
+ * found and removed successfully. If the node is not found, it returns `undefined`.
388
384
  */
389
- public removeAt(index: number): SinglyLinkedListNode<NodeData> | undefined {
385
+ removeAt(index: number): SinglyLinkedListNode<NodeVal> | undefined {
390
386
  const node = this.getNode(index);
391
387
  return node !== undefined ? this.removeNode(node) : undefined;
392
388
  }
393
389
 
394
390
  /**
395
- * Insert a new node before the reference node
396
- * ```ts
397
- * const list = new LinkedList(1, 3);
398
- * list.insertBefore(list.tail, 2); // 1 <=> 2 <=> 3
399
- * ```
400
- * @param referenceNode The node reference
401
- * @param val Data to save in the node
391
+ * The `insertBefore` function inserts a new node with a given value before a specified reference node in a singly
392
+ * linked list.
393
+ * @param referenceNode - The referenceNode parameter is the node in the linked list before which the new node will be
394
+ * inserted.
395
+ * @param {NodeVal} val - The value of the new node that will be inserted before the reference node.
396
+ * @returns The method is returning the updated SinglyLinkedList object.
402
397
  */
403
- public insertBefore(
404
- referenceNode: SinglyLinkedListNode<NodeData>,
405
- val: NodeData,
406
- ): SinglyLinkedList<NodeData> {
398
+ insertBefore(
399
+ referenceNode: SinglyLinkedListNode<NodeVal>,
400
+ val: NodeVal,
401
+ ): SinglyLinkedList<NodeVal> {
407
402
  const node = new SinglyLinkedListNode(val, referenceNode.prev, referenceNode, this);
408
403
  if (referenceNode.prev === null) {
409
404
  this.head = node;
@@ -417,23 +412,24 @@ export class SinglyLinkedList<NodeData = any> {
417
412
  }
418
413
 
419
414
  /**
420
- * Sorts the linked list using the provided compare function
421
- * @param compare A function used to compare the val of two nodes. It should return
422
- * a boolean. True will insert a before b, false will insert b before a.
423
- * (a, b) => a < b or (1, 2) => 1 < 2 === true, 2 will be inserted after 1,
424
- * the sort order will be ascending.
415
+ * The `sort` function uses the quicksort algorithm to sort the elements of a singly linked list based on a provided
416
+ * comparison function.
417
+ * @param start - The `start` parameter is the starting node of the sublist that needs to be sorted.
418
+ * @param end - The `end` parameter is a reference to the last node in the linked list. It is used as the pivot element
419
+ * for the quicksort algorithm.
420
+ * @returns The `sort` method is returning the sorted `SinglyLinkedList` object.
425
421
  */
426
- public sort(compare: (a: NodeData, b: NodeData) => boolean): SinglyLinkedList<NodeData> {
422
+ sort(compare: (a: NodeVal, b: NodeVal) => boolean): SinglyLinkedList<NodeVal> {
427
423
  if (this.head === null || this.tail === null) {
428
424
  return this;
429
425
  }
430
- if (this.length < 2) {
426
+ if (this.size < 2) {
431
427
  return this;
432
428
  }
433
429
 
434
430
  const quicksort = (
435
- start: SinglyLinkedListNode<NodeData>,
436
- end: SinglyLinkedListNode<NodeData>,
431
+ start: SinglyLinkedListNode<NodeVal>,
432
+ end: SinglyLinkedListNode<NodeVal>,
437
433
  ) => {
438
434
  if (start === end) {
439
435
  return;
@@ -476,18 +472,16 @@ export class SinglyLinkedList<NodeData = any> {
476
472
  }
477
473
 
478
474
  /**
479
- * Insert a new node after this one
480
- * ```ts
481
- * const list = new LinkedList(2, 3);
482
- * list.insertAfter(list.head, 1); // 1 <=> 2 <=> 3
483
- * ```
484
- * @param referenceNode The reference node
485
- * @param val Data to be saved in the node
475
+ * The `insertAfter` function inserts a new node with a given value after a specified reference node in a singly linked
476
+ * list.
477
+ * @param referenceNode - The referenceNode parameter is the node after which the new node will be inserted.
478
+ * @param {NodeVal} val - The value of the new node that will be inserted after the reference node.
479
+ * @returns The `insertAfter` method is returning the updated `SinglyLinkedList` object.
486
480
  */
487
- public insertAfter(
488
- referenceNode: SinglyLinkedListNode<NodeData>,
489
- val: NodeData,
490
- ): SinglyLinkedList<NodeData> {
481
+ insertAfter(
482
+ referenceNode: SinglyLinkedListNode<NodeVal>,
483
+ val: NodeVal,
484
+ ): SinglyLinkedList<NodeVal> {
491
485
  const node = new SinglyLinkedListNode(val, referenceNode, referenceNode.next, this);
492
486
  if (referenceNode.next === null) {
493
487
  this.tail = node;
@@ -501,39 +495,27 @@ export class SinglyLinkedList<NodeData = any> {
501
495
  }
502
496
 
503
497
  /**
504
- * Remove the first node from the list and return the val of the removed node
505
- * or undefined
506
- * ```ts
507
- * new LinkedList(1, 2, 3).shift(); // 1
508
- * ```
498
+ * The `shift()` function removes and returns the first element from a linked list.
499
+ * @returns The `shift()` method is returning a value of type `NodeVal` or `undefined`.
509
500
  */
510
- public shift(): NodeData | undefined {
501
+ shift(): NodeVal | undefined {
511
502
  return this.removeFromAnyEnd(this.head);
512
503
  }
513
504
 
514
505
  /**
515
- * Remove the last node from the list and return the val of the removed node
516
- * or undefined if the list was empty
517
- * ```ts
518
- * new LinkedList(1, 2, 3).pop(); // 3
519
- * ```
506
+ * The `pop()` function removes and returns the last element from a linked list.
507
+ * @returns The `pop()` method is returning a value of type `NodeVal` or `undefined`.
520
508
  */
521
- public pop(): NodeData | undefined {
509
+ pop(): NodeVal | undefined {
522
510
  return this.removeFromAnyEnd(this.tail);
523
511
  }
524
512
 
525
513
  /**
526
- * Merge the current list with another. Both lists will be
527
- * equal after merging.
528
- * ```ts
529
- * const list = new LinkedList(1, 2);
530
- * const otherList = new LinkedList(3);
531
- * list.merge(otherList);
532
- * (list === otherList); // true
533
- * ```
534
- * @param list The list to be merged
514
+ * The merge function merges two singly linked lists by updating the next and prev pointers, as well as the head, tail,
515
+ * and size properties.
516
+ * @param list - The parameter "list" is a SinglyLinkedList object that contains nodes with data of type NodeVal.
535
517
  */
536
- public merge(list: SinglyLinkedList<NodeData>): void {
518
+ merge(list: SinglyLinkedList<NodeVal>): void {
537
519
  if (this.tail !== null) {
538
520
  this.tail.next = list.head;
539
521
  }
@@ -549,13 +531,10 @@ export class SinglyLinkedList<NodeData = any> {
549
531
  }
550
532
 
551
533
  /**
552
- * Removes all nodes from a list
553
- *
554
- * ```ts
555
- * list.clear();
556
- * ```
534
+ * The clear() function resets the linked list by setting the head and tail to null and the size to 0.
535
+ * @returns The "this" object is being returned.
557
536
  */
558
- public clear() {
537
+ clear() {
559
538
  this.head = null;
560
539
  this.tail = null;
561
540
  this.size = 0;
@@ -563,19 +542,16 @@ export class SinglyLinkedList<NodeData = any> {
563
542
  }
564
543
 
565
544
  /**
566
- * The slice() method returns a shallow copy of a
567
- * portion of a list into a new list object selected
568
- * from start to end (end not included).
569
- * The original list will not be modified.
570
- * ```ts
571
- * const list = new LinkedList(1, 2, 3, 4, 5);
572
- * const newList = list.slice(0, 3); // 1 <=> 2 <=> 3
573
- * ```
574
- * @param start Start index
575
- * @param end End index, optional
545
+ * The `slice` function returns a new SinglyLinkedList containing a portion of the original list, starting from the
546
+ * specified index and ending at the optional end index.
547
+ * @param {number} start - The `start` parameter is a number that represents the index at which to start slicing the
548
+ * linked list.
549
+ * @param {number} [end] - The `end` parameter is an optional number that specifies the index at which to end the
550
+ * slicing. If no value is provided for `end`, or if the provided value is less than the `start` index, the slicing
551
+ * will continue until the end of the list.
552
+ * @returns a new SinglyLinkedList containing the sliced elements from the original list.
576
553
  */
577
- // eslint-disable-next-line @typescript-eslint/ban-types
578
- public slice(start: number, end?: number): SinglyLinkedList<NodeData | {}> {
554
+ slice(start: number, end?: number): SinglyLinkedList<NodeVal | {}> {
579
555
  const list = new SinglyLinkedList();
580
556
  let finish = end;
581
557
 
@@ -583,10 +559,10 @@ export class SinglyLinkedList<NodeData = any> {
583
559
  return list;
584
560
  }
585
561
  if (finish === undefined || finish < start) {
586
- finish = this.length;
562
+ finish = this.size;
587
563
  }
588
564
 
589
- let head: SinglyLinkedListNode<NodeData> | null | undefined = this.getNode(start);
565
+ let head: SinglyLinkedListNode<NodeVal> | null | undefined = this.getNode(start);
590
566
  for (let i = 0; i < finish - start && head !== null && head !== undefined; i++) {
591
567
  list.append(head.val);
592
568
  head = head.next;
@@ -595,13 +571,10 @@ export class SinglyLinkedList<NodeData = any> {
595
571
  }
596
572
 
597
573
  /**
598
- * The reverse() function reverses the list in place and returns the list
599
- * itself.
600
- * ```ts
601
- * new LinkedList(1, 2, 3).reverse(); // 3 <=> 2 <=> 1
602
- * ```
574
+ * The reverse() function reverses the order of nodes in a singly linked list.
575
+ * @returns The reverse() method is returning the reversed SinglyLinkedList.
603
576
  */
604
- public reverse(): SinglyLinkedList<NodeData> {
577
+ reverse(): SinglyLinkedList<NodeVal> {
605
578
  let currentNode = this.head;
606
579
  while (currentNode) {
607
580
  const next = currentNode.next;
@@ -616,67 +589,67 @@ export class SinglyLinkedList<NodeData = any> {
616
589
  }
617
590
 
618
591
  /**
619
- * The forEach() method executes a provided function once for each list node.
620
- * ```ts
621
- * new LinkedList(1, 2, 3).forEach(val => log(val)); // 1 2 3
622
- * ```
623
- * @param f Function to execute for each element, taking up to three arguments.
624
- * @param reverse Indicates if the list should be walked in reverse order, default is false
592
+ * The `forEach` function iterates over a singly linked list and applies a callback function to each node, either in
593
+ * forward or reverse order.
594
+ * @param callbackFn - A callback function that will be called for each element in the linked list. It takes three
595
+ * parameters:
596
+ * @param [reverse=false] - A boolean value indicating whether to iterate over the linked list in reverse order. If set
597
+ * to true, the iteration will start from the tail of the linked list and move towards the head. If set to false
598
+ * (default), the iteration will start from the head and move towards the tail.
625
599
  */
626
- public forEach(f: (
600
+ forEach(callbackFn: (
627
601
  data: any,
628
602
  index: number,
629
- list: SinglyLinkedList<NodeData>,
603
+ list: SinglyLinkedList<NodeVal>,
630
604
  ) => any, reverse = false): void {
631
- let currentIndex = reverse ? this.length - 1 : 0;
605
+ let currentIndex = reverse ? this.size - 1 : 0;
632
606
  let currentNode = reverse ? this.tail : this.head;
633
607
  const modifier = reverse ? -1 : 1;
634
608
  const nextNode = reverse ? 'prev' : 'next';
635
609
  while (currentNode) {
636
- f(currentNode.val, currentIndex, this);
610
+ callbackFn(currentNode.val, currentIndex, this);
637
611
  currentNode = currentNode[nextNode];
638
612
  currentIndex += modifier;
639
613
  }
640
614
  }
641
615
 
642
616
  /**
643
- * The map() method creates a new list with the results of
644
- * calling a provided function on every node in the calling list.
645
- * ```ts
646
- * new LinkedList(1, 2, 3).map(val => val + 10); // 11 <=> 12 <=> 13
647
- * ```
648
- * @param f Function that produces an node of the new list, taking up to three arguments
649
- * @param reverse Indicates if the list should be mapped in reverse order, default is false
617
+ * The map function takes a callback function and applies it to each element in the linked list, returning a new linked
618
+ * list with the results.
619
+ * @param callbackFn - A callback function that will be applied to each element in the linked list. It takes three
620
+ * parameters:
621
+ * @param [reverse=false] - The `reverse` parameter is a boolean value that determines whether the mapping should be
622
+ * done in reverse order or not. If `reverse` is set to `true`, the mapping will be done in reverse order. If `reverse`
623
+ * is set to `false` or not provided, the mapping will be
624
+ * @returns The `map` function is returning a new `SinglyLinkedList` object.
650
625
  */
651
- // eslint-disable-next-line @typescript-eslint/ban-types
652
- public map(f: (
626
+ map(callbackFn: (
653
627
  data: any,
654
628
  index: number,
655
- list: SinglyLinkedList<NodeData>,
656
- ) => any, reverse = false): SinglyLinkedList<NodeData | {}> {
629
+ list: SinglyLinkedList<NodeVal>,
630
+ ) => any, reverse = false): SinglyLinkedList<NodeVal | {}> {
657
631
  const list = new SinglyLinkedList();
658
- this.forEach((val, index) => list.append(f(val, index, this)), reverse);
632
+ this.forEach((val, index) => list.append(callbackFn(val, index, this)), reverse);
659
633
  return list;
660
634
  }
661
635
 
662
636
  /**
663
- * The filter() method creates a new list with all nodes
664
- * that pass the test implemented by the provided function.
665
- * ```ts
666
- * new LinkedList(1, 2, 3, 4, 5).filter(val => val < 4); // 1 <=> 2 <=> 3
667
- * ```
668
- * @param f Function to test each node val in the list. Return true to keep the node
669
- * @param reverse Indicates if the list should be filtered in reverse order, default is false
637
+ * The `filter` function filters the elements of a singly linked list based on a given callback function.
638
+ * @param callbackFn - A callback function that takes three parameters: data, index, and list. It should return a
639
+ * boolean value indicating whether the current element should be included in the filtered list or not.
640
+ * @param [reverse=false] - The `reverse` parameter is a boolean value that determines whether the filtered list should
641
+ * be reversed or not. If `reverse` is set to `true`, the filtered list will be in reverse order. If `reverse` is set
642
+ * to `false` or not provided, the filtered list will be in
643
+ * @returns The `filter` method is returning a new `SinglyLinkedList` object.
670
644
  */
671
- // eslint-disable-next-line @typescript-eslint/ban-types
672
- public filter(f: (
673
- data: NodeData,
645
+ filter(callbackFn: (
646
+ data: NodeVal,
674
647
  index: number,
675
- list: SinglyLinkedList<NodeData>,
676
- ) => boolean, reverse = false): SinglyLinkedList<NodeData | {}> {
648
+ list: SinglyLinkedList<NodeVal>,
649
+ ) => boolean, reverse = false): SinglyLinkedList<NodeVal | {}> {
677
650
  const list = new SinglyLinkedList();
678
651
  this.forEach((val, index) => {
679
- if (f(val, index, this)) {
652
+ if (callbackFn(val, index, this)) {
680
653
  list.append(val);
681
654
  }
682
655
  }, reverse);
@@ -684,25 +657,30 @@ export class SinglyLinkedList<NodeData = any> {
684
657
  }
685
658
 
686
659
  /**
687
- * Reduce over each node in the list
688
- * ```ts
689
- * new LinkedList(1, 2, 3).reduce(n => n += 1, 0); // 3
690
- * ```
691
- * @param f A reducer function
692
- * @param start An initial value
693
- * @returns The final state of the accumulator
660
+ * The `reduce` function iterates over a singly linked list and applies a callback function to each element,
661
+ * accumulating a single value.
662
+ * @param callbackFn - A callback function that will be called for each element in the linked list. It takes four
663
+ * parameters:
664
+ * @param {any} [start] - The `start` parameter is an optional initial value for the accumulator. If provided, the
665
+ * `reduce` function will start accumulating from this value. If not provided, the `reduce` function will use the value
666
+ * of the first element in the linked list as the initial value.
667
+ * @param [reverse=false] - A boolean value indicating whether to iterate over the linked list in reverse order. If set
668
+ * to true, the iteration will start from the tail of the linked list and move towards the head. If set to false
669
+ * (default), the iteration will start from the head and move towards the tail.
670
+ * @returns The `reduce` method returns the accumulated value after applying the callback function to each element in
671
+ * the linked list.
694
672
  */
695
- public reduce(
696
- f: (
673
+ reduce(
674
+ callbackFn: (
697
675
  accumulator: any,
698
- currentNode: NodeData,
676
+ currentNode: NodeVal,
699
677
  index: number,
700
- list: SinglyLinkedList<NodeData>,
678
+ list: SinglyLinkedList<NodeVal>,
701
679
  ) => any,
702
680
  start?: any,
703
681
  reverse = false,
704
682
  ): any {
705
- let currentIndex = reverse ? this.length - 1 : 0;
683
+ let currentIndex = reverse ? this.size - 1 : 0;
706
684
  const modifier = reverse ? -1 : 1;
707
685
  const nextNode = reverse ? 'prev' : 'next';
708
686
  let currentElement = reverse ? this.tail : this.head;
@@ -718,7 +696,7 @@ export class SinglyLinkedList<NodeData = any> {
718
696
  }
719
697
 
720
698
  while (currentElement) {
721
- result = f(result, currentElement.val, currentIndex, this);
699
+ result = callbackFn(result, currentElement.val, currentIndex, this);
722
700
  currentIndex += modifier;
723
701
  currentElement = currentElement[nextNode];
724
702
  }
@@ -727,34 +705,29 @@ export class SinglyLinkedList<NodeData = any> {
727
705
  }
728
706
 
729
707
  /**
730
- * Convert the linked list to an array
731
- * ```ts
732
- * new LinkedList(1, 2, 3).toArray(); // [1, 2, 3]
733
- * ```
708
+ * The toArray() function converts a NodeVal object into an array of NodeVal objects.
709
+ * @returns An array of NodeVal objects.
734
710
  */
735
- public toArray(): NodeData[] {
711
+ toArray(): NodeVal[] {
736
712
  return [...this];
737
713
  }
738
714
 
739
715
  /**
740
- * Convert a linked list to string
741
- * ```ts
742
- * new LinkedList('one', 'two', 'three').toString(' <=> ') === 'one <=> two <=> three';
743
- * ```
744
- * @param separator Optional string to be placed in between val nodes, default is one space
716
+ * The `toString` function takes an optional separator and returns a string representation of an array, with each
717
+ * element separated by the specified separator.
718
+ * @param [separator= ] - The separator parameter is a string that specifies the character(s) to be used as a separator
719
+ * between each element in the array when converting it to a string. By default, the separator is set to a space
720
+ * character (' ').
721
+ * @returns The toString method is being returned as a string.
745
722
  */
746
- public toString(separator = ' '): string {
723
+ toString(separator = ' '): string {
747
724
  return this.reduce((s, val) => `${s}${separator}${val}`);
748
725
  }
749
726
 
750
727
  /**
751
- * The iterator implementation
752
- * ```ts
753
- * const list = new LinkedList(1, 2, 3);
754
- * for (const val of list) { log(val); } // 1 2 3
755
- * ```
728
+ * The function is an iterator that returns the values of each node in a linked list.
756
729
  */
757
- public* [Symbol.iterator](): IterableIterator<NodeData> {
730
+ public* [Symbol.iterator](): IterableIterator<NodeVal> {
758
731
  let element = this.head;
759
732
 
760
733
  while (element !== null) {
@@ -763,8 +736,13 @@ export class SinglyLinkedList<NodeData = any> {
763
736
  }
764
737
  }
765
738
 
766
- /** Private helper function to reduce duplication of pop() and shift() methods */
767
- private removeFromAnyEnd(node: SinglyLinkedListNode<NodeData> | null) {
739
+ /**
740
+ * The function removes a node from either end of a singly linked list and returns its value.
741
+ * @param {SinglyLinkedListNode<NodeVal> | null} node - The `node` parameter is a reference to a node in a singly
742
+ * linked list. It can be either a `SinglyLinkedListNode` object or `null`.
743
+ * @returns The value of the removed node if the node is not null, otherwise undefined.
744
+ */
745
+ protected removeFromAnyEnd(node: SinglyLinkedListNode<NodeVal> | null) {
768
746
  return node !== null ? this.removeNode(node).val : undefined;
769
747
  }
770
748
  }