avl-tree-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.
- package/dist/data-structures/base/iterable-element-base.d.ts +14 -40
- package/dist/data-structures/base/iterable-element-base.js +14 -11
- package/dist/data-structures/base/linear-base.d.ts +277 -0
- package/dist/data-structures/base/linear-base.js +552 -0
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +12 -8
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +50 -37
- package/dist/data-structures/binary-tree/avl-tree.d.ts +64 -0
- package/dist/data-structures/binary-tree/avl-tree.js +64 -0
- package/dist/data-structures/binary-tree/binary-tree.js +5 -5
- package/dist/data-structures/binary-tree/bst.js +11 -11
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +175 -14
- package/dist/data-structures/binary-tree/tree-multi-map.js +210 -40
- package/dist/data-structures/graph/abstract-graph.js +16 -16
- package/dist/data-structures/hash/hash-map.d.ts +46 -0
- package/dist/data-structures/hash/hash-map.js +46 -0
- package/dist/data-structures/heap/heap.d.ts +3 -11
- package/dist/data-structures/heap/heap.js +0 -10
- package/dist/data-structures/heap/max-heap.d.ts +2 -2
- package/dist/data-structures/heap/min-heap.d.ts +2 -2
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +65 -94
- package/dist/data-structures/linked-list/doubly-linked-list.js +131 -146
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +145 -75
- package/dist/data-structures/linked-list/singly-linked-list.js +283 -169
- package/dist/data-structures/priority-queue/max-priority-queue.d.ts +2 -2
- package/dist/data-structures/priority-queue/min-priority-queue.d.ts +2 -2
- package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -2
- package/dist/data-structures/queue/deque.d.ts +130 -91
- package/dist/data-structures/queue/deque.js +269 -169
- package/dist/data-structures/queue/queue.d.ts +131 -40
- package/dist/data-structures/queue/queue.js +181 -50
- package/dist/data-structures/stack/stack.d.ts +124 -11
- package/dist/data-structures/stack/stack.js +121 -10
- package/dist/data-structures/trie/trie.d.ts +4 -3
- package/dist/data-structures/trie/trie.js +3 -0
- package/dist/types/data-structures/base/base.d.ts +9 -4
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +2 -2
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +2 -2
- package/dist/types/data-structures/queue/deque.d.ts +2 -3
- package/dist/types/data-structures/queue/queue.d.ts +2 -2
- package/package.json +2 -2
- package/src/data-structures/base/iterable-element-base.ts +29 -20
- package/src/data-structures/base/linear-base.ts +649 -0
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +51 -36
- package/src/data-structures/binary-tree/avl-tree.ts +64 -0
- package/src/data-structures/binary-tree/binary-tree.ts +5 -5
- package/src/data-structures/binary-tree/bst.ts +9 -9
- package/src/data-structures/binary-tree/tree-multi-map.ts +214 -40
- package/src/data-structures/graph/abstract-graph.ts +16 -16
- package/src/data-structures/hash/hash-map.ts +46 -0
- package/src/data-structures/heap/heap.ts +3 -14
- package/src/data-structures/heap/max-heap.ts +2 -2
- package/src/data-structures/heap/min-heap.ts +2 -2
- package/src/data-structures/linked-list/doubly-linked-list.ts +144 -160
- package/src/data-structures/linked-list/singly-linked-list.ts +307 -185
- package/src/data-structures/priority-queue/max-priority-queue.ts +2 -5
- package/src/data-structures/priority-queue/min-priority-queue.ts +2 -5
- package/src/data-structures/priority-queue/priority-queue.ts +2 -2
- package/src/data-structures/queue/deque.ts +286 -183
- package/src/data-structures/queue/queue.ts +196 -63
- package/src/data-structures/stack/stack.ts +124 -18
- package/src/data-structures/trie/trie.ts +7 -3
- package/src/types/data-structures/base/base.ts +17 -8
- package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +1 -1
- package/src/types/data-structures/binary-tree/tree-multi-map.ts +1 -1
- package/src/types/data-structures/linked-list/doubly-linked-list.ts +2 -2
- package/src/types/data-structures/linked-list/singly-linked-list.ts +2 -2
- package/src/types/data-structures/queue/deque.ts +2 -3
- package/src/types/data-structures/queue/queue.ts +2 -2
|
@@ -1,97 +1,124 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SinglyLinkedList = exports.SinglyLinkedListNode = void 0;
|
|
4
|
-
const
|
|
5
|
-
class SinglyLinkedListNode {
|
|
4
|
+
const linear_base_1 = require("../base/linear-base");
|
|
5
|
+
class SinglyLinkedListNode extends linear_base_1.LinkedListNode {
|
|
6
6
|
/**
|
|
7
7
|
* The constructor function initializes an instance of a class with a given value and sets the next property to undefined.
|
|
8
8
|
* @param {E} value - The "value" parameter is of type E, which means it can be any data type. It represents the value that
|
|
9
9
|
* will be stored in the node of a linked list.
|
|
10
10
|
*/
|
|
11
11
|
constructor(value) {
|
|
12
|
+
super(value);
|
|
12
13
|
this._value = value;
|
|
13
14
|
this._next = undefined;
|
|
14
15
|
}
|
|
15
|
-
/**
|
|
16
|
-
* The function returns the value of a protected variable.
|
|
17
|
-
* @returns The value of the variable `_value` is being returned.
|
|
18
|
-
*/
|
|
19
|
-
get value() {
|
|
20
|
-
return this._value;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* The above function sets the value of a variable.
|
|
24
|
-
* @param {E} value - The parameter "value" is of type E, which means it can be any type.
|
|
25
|
-
*/
|
|
26
|
-
set value(value) {
|
|
27
|
-
this._value = value;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* The `next` function returns the next node in a singly linked list.
|
|
31
|
-
* @returns The `next` property is being returned. It can be either a `SinglyLinkedListNode<E>`
|
|
32
|
-
* object or `undefined`.
|
|
33
|
-
*/
|
|
34
16
|
get next() {
|
|
35
17
|
return this._next;
|
|
36
18
|
}
|
|
37
|
-
/**
|
|
38
|
-
* The "next" property of a SinglyLinkedListNode is set to the provided value.
|
|
39
|
-
* @param {SinglyLinkedListNode<E> | undefined} value - The `value` parameter is of type
|
|
40
|
-
* `SinglyLinkedListNode<E> | undefined`. This means that it can accept either a
|
|
41
|
-
* `SinglyLinkedListNode` object or `undefined` as its value.
|
|
42
|
-
*/
|
|
43
19
|
set next(value) {
|
|
44
20
|
this._next = value;
|
|
45
21
|
}
|
|
46
22
|
}
|
|
47
23
|
exports.SinglyLinkedListNode = SinglyLinkedListNode;
|
|
48
24
|
/**
|
|
25
|
+
* 1. Node Structure: Each node contains three parts: a data field, a pointer (or reference) to the previous node, and a pointer to the next node. This structure allows traversal of the linked list in both directions.
|
|
26
|
+
* 2. Bidirectional Traversal: Unlike doubly linked lists, singly linked lists can be easily traversed forwards but not backwards.
|
|
27
|
+
* 3. No Centralized Index: Unlike arrays, elements in a linked list are not stored contiguously, so there is no centralized index. Accessing elements in a linked list typically requires traversing from the head or tail node.
|
|
28
|
+
* 4. High Efficiency in Insertion and Deletion: Adding or removing elements in a linked list does not require moving other elements, making these operations more efficient than in arrays.
|
|
29
|
+
* Caution: Although our linked list classes provide methods such as at, setAt, addAt, and indexOf that are based on array indices, their time complexity, like that of the native Array.lastIndexOf, is 𝑂(𝑛). If you need to use these methods frequently, you might want to consider other data structures, such as Deque or Queue (designed for random access). Similarly, since the native Array.shift method has a time complexity of 𝑂(𝑛), using an array to simulate a queue can be inefficient. In such cases, you should use Queue or Deque, as these data structures leverage deferred array rearrangement, effectively reducing the average time complexity to 𝑂(1).
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* // implementation of a basic text editor
|
|
33
|
+
* class TextEditor {
|
|
34
|
+
* private content: SinglyLinkedList<string>;
|
|
35
|
+
* private cursorIndex: number;
|
|
36
|
+
* private undoStack: Stack<{ operation: string; data?: any }>;
|
|
37
|
+
*
|
|
38
|
+
* constructor() {
|
|
39
|
+
* this.content = new SinglyLinkedList<string>();
|
|
40
|
+
* this.cursorIndex = 0; // Cursor starts at the beginning
|
|
41
|
+
* this.undoStack = new Stack<{ operation: string; data?: any }>(); // Stack to keep track of operations for undo
|
|
42
|
+
* }
|
|
43
|
+
*
|
|
44
|
+
* insert(char: string) {
|
|
45
|
+
* this.content.addAt(this.cursorIndex, char);
|
|
46
|
+
* this.cursorIndex++;
|
|
47
|
+
* this.undoStack.push({ operation: 'insert', data: { index: this.cursorIndex - 1 } });
|
|
48
|
+
* }
|
|
49
|
+
*
|
|
50
|
+
* delete() {
|
|
51
|
+
* if (this.cursorIndex === 0) return; // Nothing to delete
|
|
52
|
+
* const deleted = this.content.deleteAt(this.cursorIndex - 1);
|
|
53
|
+
* this.cursorIndex--;
|
|
54
|
+
* this.undoStack.push({ operation: 'delete', data: { index: this.cursorIndex, char: deleted } });
|
|
55
|
+
* }
|
|
56
|
+
*
|
|
57
|
+
* moveCursor(index: number) {
|
|
58
|
+
* this.cursorIndex = Math.max(0, Math.min(index, this.content.length));
|
|
59
|
+
* }
|
|
60
|
+
*
|
|
61
|
+
* undo() {
|
|
62
|
+
* if (this.undoStack.size === 0) return; // No operations to undo
|
|
63
|
+
* const lastAction = this.undoStack.pop();
|
|
64
|
+
*
|
|
65
|
+
* if (lastAction!.operation === 'insert') {
|
|
66
|
+
* this.content.deleteAt(lastAction!.data.index);
|
|
67
|
+
* this.cursorIndex = lastAction!.data.index;
|
|
68
|
+
* } else if (lastAction!.operation === 'delete') {
|
|
69
|
+
* this.content.addAt(lastAction!.data.index, lastAction!.data.char);
|
|
70
|
+
* this.cursorIndex = lastAction!.data.index + 1;
|
|
71
|
+
* }
|
|
72
|
+
* }
|
|
49
73
|
*
|
|
74
|
+
* getText(): string {
|
|
75
|
+
* return [...this.content].join('');
|
|
76
|
+
* }
|
|
77
|
+
* }
|
|
78
|
+
*
|
|
79
|
+
* // Example Usage
|
|
80
|
+
* const editor = new TextEditor();
|
|
81
|
+
* editor.insert('H');
|
|
82
|
+
* editor.insert('e');
|
|
83
|
+
* editor.insert('l');
|
|
84
|
+
* editor.insert('l');
|
|
85
|
+
* editor.insert('o');
|
|
86
|
+
* console.log(editor.getText()); // 'Hello' // Output: "Hello"
|
|
87
|
+
*
|
|
88
|
+
* editor.delete();
|
|
89
|
+
* console.log(editor.getText()); // 'Hell' // Output: "Hell"
|
|
90
|
+
*
|
|
91
|
+
* editor.undo();
|
|
92
|
+
* console.log(editor.getText()); // 'Hello' // Output: "Hello"
|
|
93
|
+
*
|
|
94
|
+
* editor.moveCursor(1);
|
|
95
|
+
* editor.insert('a');
|
|
96
|
+
* console.log(editor.getText()); // 'Haello'
|
|
50
97
|
*/
|
|
51
|
-
class SinglyLinkedList extends
|
|
98
|
+
class SinglyLinkedList extends linear_base_1.LinearLinkedBase {
|
|
52
99
|
constructor(elements = [], options) {
|
|
53
100
|
super(options);
|
|
54
|
-
this.
|
|
101
|
+
this._length = 0;
|
|
102
|
+
if (options) {
|
|
103
|
+
}
|
|
55
104
|
this.pushMany(elements);
|
|
56
105
|
}
|
|
57
|
-
/**
|
|
58
|
-
* The `head` function returns the first node of a singly linked list.
|
|
59
|
-
* @returns The method is returning either a SinglyLinkedListNode object or undefined.
|
|
60
|
-
*/
|
|
61
106
|
get head() {
|
|
62
107
|
return this._head;
|
|
63
108
|
}
|
|
64
|
-
/**
|
|
65
|
-
* The `tail` function returns the last node of a singly linked list.
|
|
66
|
-
* @returns The method is returning either a SinglyLinkedListNode object or undefined.
|
|
67
|
-
*/
|
|
68
109
|
get tail() {
|
|
69
110
|
return this._tail;
|
|
70
111
|
}
|
|
71
|
-
/**
|
|
72
|
-
* The above function returns the value of the first element in a linked list, or undefined if the
|
|
73
|
-
* list is empty.
|
|
74
|
-
* @returns The value of the first node in the linked list, or undefined if the linked list is empty.
|
|
75
|
-
*/
|
|
76
112
|
get first() {
|
|
77
113
|
var _a;
|
|
78
114
|
return (_a = this.head) === null || _a === void 0 ? void 0 : _a.value;
|
|
79
115
|
}
|
|
80
|
-
/**
|
|
81
|
-
* The function returns the value of the last element in a linked list, or undefined if the list is
|
|
82
|
-
* empty.
|
|
83
|
-
* @returns The value of the last node in the linked list, or undefined if the linked list is empty.
|
|
84
|
-
*/
|
|
85
116
|
get last() {
|
|
86
117
|
var _a;
|
|
87
118
|
return (_a = this.tail) === null || _a === void 0 ? void 0 : _a.value;
|
|
88
119
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
* @returns The size of the object, which is a number.
|
|
92
|
-
*/
|
|
93
|
-
get size() {
|
|
94
|
-
return this._size;
|
|
120
|
+
get length() {
|
|
121
|
+
return this._length;
|
|
95
122
|
}
|
|
96
123
|
/**
|
|
97
124
|
* Time Complexity: O(n)
|
|
@@ -128,7 +155,9 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
128
155
|
this.tail.next = newNode;
|
|
129
156
|
this._tail = newNode;
|
|
130
157
|
}
|
|
131
|
-
this.
|
|
158
|
+
this._length++;
|
|
159
|
+
if (this._maxLen > 0 && this.length > this._maxLen)
|
|
160
|
+
this.shift();
|
|
132
161
|
return true;
|
|
133
162
|
}
|
|
134
163
|
/**
|
|
@@ -146,7 +175,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
146
175
|
const value = this.head.value;
|
|
147
176
|
this._head = undefined;
|
|
148
177
|
this._tail = undefined;
|
|
149
|
-
this.
|
|
178
|
+
this._length--;
|
|
150
179
|
return value;
|
|
151
180
|
}
|
|
152
181
|
let current = this.head;
|
|
@@ -156,7 +185,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
156
185
|
const value = this.tail.value;
|
|
157
186
|
current.next = undefined;
|
|
158
187
|
this._tail = current;
|
|
159
|
-
this.
|
|
188
|
+
this._length--;
|
|
160
189
|
return value;
|
|
161
190
|
}
|
|
162
191
|
/**
|
|
@@ -171,7 +200,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
171
200
|
return undefined;
|
|
172
201
|
const removedNode = this.head;
|
|
173
202
|
this._head = this.head.next;
|
|
174
|
-
this.
|
|
203
|
+
this._length--;
|
|
175
204
|
return removedNode.value;
|
|
176
205
|
}
|
|
177
206
|
/**
|
|
@@ -195,7 +224,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
195
224
|
newNode.next = this.head;
|
|
196
225
|
this._head = newNode;
|
|
197
226
|
}
|
|
198
|
-
this.
|
|
227
|
+
this._length++;
|
|
199
228
|
return true;
|
|
200
229
|
}
|
|
201
230
|
/**
|
|
@@ -278,7 +307,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
278
307
|
* `undefined` if the index is out of bounds.
|
|
279
308
|
*/
|
|
280
309
|
at(index) {
|
|
281
|
-
if (index < 0 || index >= this.
|
|
310
|
+
if (index < 0 || index >= this._length)
|
|
282
311
|
return undefined;
|
|
283
312
|
let current = this.head;
|
|
284
313
|
for (let i = 0; i < index; i++) {
|
|
@@ -330,21 +359,25 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
330
359
|
* bounds.
|
|
331
360
|
*/
|
|
332
361
|
deleteAt(index) {
|
|
333
|
-
if (index < 0 || index >= this.
|
|
334
|
-
return
|
|
362
|
+
if (index < 0 || index >= this._length)
|
|
363
|
+
return;
|
|
364
|
+
let deleted;
|
|
335
365
|
if (index === 0) {
|
|
366
|
+
deleted = this.first;
|
|
336
367
|
this.shift();
|
|
337
|
-
return
|
|
368
|
+
return deleted;
|
|
338
369
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
370
|
+
const targetNode = this.getNodeAt(index);
|
|
371
|
+
const prevNode = this._getPrevNode(targetNode);
|
|
372
|
+
if (prevNode && targetNode) {
|
|
373
|
+
deleted = targetNode.value;
|
|
374
|
+
prevNode.next = targetNode.next;
|
|
375
|
+
if (targetNode === this.tail)
|
|
376
|
+
this._tail = prevNode;
|
|
377
|
+
this._length--;
|
|
378
|
+
return deleted;
|
|
342
379
|
}
|
|
343
|
-
|
|
344
|
-
const removedNode = prevNode.next;
|
|
345
|
-
prevNode.next = removedNode.next;
|
|
346
|
-
this._size--;
|
|
347
|
-
return true;
|
|
380
|
+
return;
|
|
348
381
|
}
|
|
349
382
|
/**
|
|
350
383
|
* Time Complexity: O(n)
|
|
@@ -357,37 +390,25 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
357
390
|
* successfully deleted from the linked list, and `false` if the value or node is not found in the linked list.
|
|
358
391
|
*/
|
|
359
392
|
delete(elementOrNode) {
|
|
360
|
-
if (elementOrNode === undefined)
|
|
393
|
+
if (elementOrNode === undefined || !this.head)
|
|
361
394
|
return false;
|
|
362
|
-
|
|
363
|
-
if (
|
|
364
|
-
|
|
395
|
+
const node = this.isNode(elementOrNode) ? elementOrNode : this.getNode(elementOrNode);
|
|
396
|
+
if (!node)
|
|
397
|
+
return false;
|
|
398
|
+
const prevNode = this._getPrevNode(node);
|
|
399
|
+
if (!prevNode) {
|
|
400
|
+
// The node is the head
|
|
401
|
+
this._head = node.next;
|
|
402
|
+
if (node === this.tail)
|
|
403
|
+
this._tail = undefined;
|
|
365
404
|
}
|
|
366
405
|
else {
|
|
367
|
-
|
|
406
|
+
prevNode.next = node.next;
|
|
407
|
+
if (node === this.tail)
|
|
408
|
+
this._tail = prevNode;
|
|
368
409
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
if (current.value === value) {
|
|
372
|
-
if (prev === undefined) {
|
|
373
|
-
this._head = current.next;
|
|
374
|
-
if (current === this.tail) {
|
|
375
|
-
this._tail = undefined;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
else {
|
|
379
|
-
prev.next = current.next;
|
|
380
|
-
if (current === this.tail) {
|
|
381
|
-
this._tail = prev;
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
this._size--;
|
|
385
|
-
return true;
|
|
386
|
-
}
|
|
387
|
-
prev = current;
|
|
388
|
-
current = current.next;
|
|
389
|
-
}
|
|
390
|
-
return false;
|
|
410
|
+
this._length--;
|
|
411
|
+
return true;
|
|
391
412
|
}
|
|
392
413
|
/**
|
|
393
414
|
* Time Complexity: O(n)
|
|
@@ -405,13 +426,13 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
405
426
|
* successfully added at the specified index, and `false` if the index is out of bounds.
|
|
406
427
|
*/
|
|
407
428
|
addAt(index, newElementOrNode) {
|
|
408
|
-
if (index < 0 || index > this.
|
|
429
|
+
if (index < 0 || index > this._length)
|
|
409
430
|
return false;
|
|
410
431
|
if (index === 0) {
|
|
411
432
|
this.unshift(newElementOrNode);
|
|
412
433
|
return true;
|
|
413
434
|
}
|
|
414
|
-
if (index === this.
|
|
435
|
+
if (index === this._length) {
|
|
415
436
|
this.push(newElementOrNode);
|
|
416
437
|
return true;
|
|
417
438
|
}
|
|
@@ -419,9 +440,31 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
419
440
|
const prevNode = this.getNodeAt(index - 1);
|
|
420
441
|
newNode.next = prevNode.next;
|
|
421
442
|
prevNode.next = newNode;
|
|
422
|
-
this.
|
|
443
|
+
this._length++;
|
|
423
444
|
return true;
|
|
424
445
|
}
|
|
446
|
+
/**
|
|
447
|
+
* Time Complexity: O(n)
|
|
448
|
+
* Space Complexity: O(1)
|
|
449
|
+
*
|
|
450
|
+
* The function setAt(index, value) updates the value at a specified index in a data structure if the
|
|
451
|
+
* index exists.
|
|
452
|
+
* @param {number} index - The `index` parameter in the `setAt` method refers to the position in the
|
|
453
|
+
* data structure where you want to set a new value.
|
|
454
|
+
* @param {E} value - The `value` parameter in the `setAt` method represents the new value that you
|
|
455
|
+
* want to set at the specified index in the data structure.
|
|
456
|
+
* @returns The `setAt` method returns a boolean value - `true` if the value at the specified index
|
|
457
|
+
* is successfully updated, and `false` if the index is out of bounds (i.e., the node at that index
|
|
458
|
+
* does not exist).
|
|
459
|
+
*/
|
|
460
|
+
setAt(index, value) {
|
|
461
|
+
const node = this.getNodeAt(index);
|
|
462
|
+
if (node) {
|
|
463
|
+
node.value = value;
|
|
464
|
+
return true;
|
|
465
|
+
}
|
|
466
|
+
return false;
|
|
467
|
+
}
|
|
425
468
|
/**
|
|
426
469
|
* Time Complexity: O(1)
|
|
427
470
|
* Space Complexity: O(1)
|
|
@@ -431,7 +474,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
431
474
|
* @returns A boolean value indicating whether the length of the object is equal to 0.
|
|
432
475
|
*/
|
|
433
476
|
isEmpty() {
|
|
434
|
-
return this.
|
|
477
|
+
return this._length === 0;
|
|
435
478
|
}
|
|
436
479
|
/**
|
|
437
480
|
* Time Complexity: O(1)
|
|
@@ -442,23 +485,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
442
485
|
clear() {
|
|
443
486
|
this._head = undefined;
|
|
444
487
|
this._tail = undefined;
|
|
445
|
-
this.
|
|
446
|
-
}
|
|
447
|
-
/**
|
|
448
|
-
* Time Complexity: O(n)
|
|
449
|
-
* Space Complexity: O(n)
|
|
450
|
-
*
|
|
451
|
-
* The `toArray` function converts a linked list into an array.
|
|
452
|
-
* @returns The `toArray()` method is returning an array of type `E[]`.
|
|
453
|
-
*/
|
|
454
|
-
toArray() {
|
|
455
|
-
const array = [];
|
|
456
|
-
let current = this.head;
|
|
457
|
-
while (current) {
|
|
458
|
-
array.push(current.value);
|
|
459
|
-
current = current.next;
|
|
460
|
-
}
|
|
461
|
-
return array;
|
|
488
|
+
this._length = 0;
|
|
462
489
|
}
|
|
463
490
|
/**
|
|
464
491
|
* Time Complexity: O(n)
|
|
@@ -482,32 +509,6 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
482
509
|
[this._head, this._tail] = [this.tail, this.head];
|
|
483
510
|
return this;
|
|
484
511
|
}
|
|
485
|
-
/**
|
|
486
|
-
* Time Complexity: O(n)
|
|
487
|
-
* Space Complexity: O(1)
|
|
488
|
-
*
|
|
489
|
-
* The `indexOf` function in TypeScript searches for a specific element or node in a singly linked
|
|
490
|
-
* list and returns its index if found.
|
|
491
|
-
* @param {E | SinglyLinkedListNode<E> | ((node: SinglyLinkedListNode<E>) => boolean)} elementNodeOrPredicate
|
|
492
|
-
* elementNodeOrPredicate - The `elementNodeOrPredicate` parameter in the `indexOf` method can be one
|
|
493
|
-
* of the following types:
|
|
494
|
-
* @returns The `indexOf` method returns the index of the first occurrence of the element that
|
|
495
|
-
* matches the provided predicate in the singly linked list. If no matching element is found, it
|
|
496
|
-
* returns -1.
|
|
497
|
-
*/
|
|
498
|
-
indexOf(elementNodeOrPredicate) {
|
|
499
|
-
const predicate = this._ensurePredicate(elementNodeOrPredicate);
|
|
500
|
-
let index = 0;
|
|
501
|
-
let current = this.head;
|
|
502
|
-
while (current) {
|
|
503
|
-
if (predicate(current)) {
|
|
504
|
-
return index;
|
|
505
|
-
}
|
|
506
|
-
index++;
|
|
507
|
-
current = current.next;
|
|
508
|
-
}
|
|
509
|
-
return -1;
|
|
510
|
-
}
|
|
511
512
|
/**
|
|
512
513
|
* Time Complexity: O(n)
|
|
513
514
|
* Space Complexity: O(1)
|
|
@@ -524,6 +525,8 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
524
525
|
getNode(elementNodeOrPredicate) {
|
|
525
526
|
if (elementNodeOrPredicate === undefined)
|
|
526
527
|
return;
|
|
528
|
+
if (this.isNode(elementNodeOrPredicate))
|
|
529
|
+
return elementNodeOrPredicate;
|
|
527
530
|
const predicate = this._ensurePredicate(elementNodeOrPredicate);
|
|
528
531
|
let current = this.head;
|
|
529
532
|
while (current) {
|
|
@@ -551,31 +554,21 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
551
554
|
* unsuccessful.
|
|
552
555
|
*/
|
|
553
556
|
addBefore(existingElementOrNode, newElementOrNode) {
|
|
554
|
-
|
|
557
|
+
const existingNode = this.getNode(existingElementOrNode);
|
|
558
|
+
if (!existingNode)
|
|
555
559
|
return false;
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
560
|
+
const prevNode = this._getPrevNode(existingNode);
|
|
561
|
+
const newNode = this._ensureNode(newElementOrNode);
|
|
562
|
+
if (!prevNode) {
|
|
563
|
+
// Add at the head
|
|
564
|
+
this.unshift(newNode);
|
|
559
565
|
}
|
|
560
566
|
else {
|
|
561
|
-
|
|
567
|
+
prevNode.next = newNode;
|
|
568
|
+
newNode.next = existingNode;
|
|
569
|
+
this._length++;
|
|
562
570
|
}
|
|
563
|
-
|
|
564
|
-
this.unshift(newElementOrNode);
|
|
565
|
-
return true;
|
|
566
|
-
}
|
|
567
|
-
let current = this.head;
|
|
568
|
-
while (current.next) {
|
|
569
|
-
if (current.next.value === existingValue) {
|
|
570
|
-
const newNode = this._ensureNode(newElementOrNode);
|
|
571
|
-
newNode.next = current.next;
|
|
572
|
-
current.next = newNode;
|
|
573
|
-
this._size++;
|
|
574
|
-
return true;
|
|
575
|
-
}
|
|
576
|
-
current = current.next;
|
|
577
|
-
}
|
|
578
|
-
return false;
|
|
571
|
+
return true;
|
|
579
572
|
}
|
|
580
573
|
/**
|
|
581
574
|
* Time Complexity: O(n)
|
|
@@ -602,11 +595,74 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
602
595
|
if (existingNode === this.tail) {
|
|
603
596
|
this._tail = newNode;
|
|
604
597
|
}
|
|
605
|
-
this.
|
|
598
|
+
this._length++;
|
|
606
599
|
return true;
|
|
607
600
|
}
|
|
608
601
|
return false;
|
|
609
602
|
}
|
|
603
|
+
/**
|
|
604
|
+
* Time Complexity: O(n)
|
|
605
|
+
* Space Complexity: O(1)
|
|
606
|
+
*
|
|
607
|
+
* The function `splice` in TypeScript overrides the default behavior to remove and insert elements
|
|
608
|
+
* in a singly linked list while handling boundary cases.
|
|
609
|
+
* @param {number} start - The `start` parameter in the `splice` method indicates the index at which
|
|
610
|
+
* to start modifying the list. It specifies the position where elements will be added or removed.
|
|
611
|
+
* @param {number} [deleteCount=0] - The `deleteCount` parameter in the `splice` method specifies the
|
|
612
|
+
* number of elements to remove from the array starting at the specified `start` index. If
|
|
613
|
+
* `deleteCount` is not provided, it defaults to 0, meaning no elements will be removed but new
|
|
614
|
+
* elements can still be inserted at
|
|
615
|
+
* @param {E[]} items - The `items` parameter in the `splice` method represents the elements to be
|
|
616
|
+
* inserted into the list at the specified `start` index. These elements will be inserted in place of
|
|
617
|
+
* the elements that are removed from the list. The `splice` method allows you to add new elements to
|
|
618
|
+
* the list while
|
|
619
|
+
* @returns The `splice` method is returning a `SinglyLinkedList` containing the elements that were
|
|
620
|
+
* removed from the original list during the splice operation.
|
|
621
|
+
*/
|
|
622
|
+
splice(start, deleteCount = 0, ...items) {
|
|
623
|
+
const removedList = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
|
|
624
|
+
// If `start` is out of range, perform boundary processing
|
|
625
|
+
start = Math.max(0, Math.min(start, this.length));
|
|
626
|
+
deleteCount = Math.max(0, deleteCount);
|
|
627
|
+
// Find the predecessor node of `start`
|
|
628
|
+
const prevNode = start === 0 ? undefined : this.getNodeAt(start - 1);
|
|
629
|
+
const startNode = prevNode ? prevNode.next : this.head;
|
|
630
|
+
let current = startNode;
|
|
631
|
+
for (let i = 0; i < deleteCount && current; i++) {
|
|
632
|
+
removedList.push(current.value);
|
|
633
|
+
current = current.next;
|
|
634
|
+
}
|
|
635
|
+
const nextNode = current;
|
|
636
|
+
let lastInsertedNode = undefined;
|
|
637
|
+
for (const item of items) {
|
|
638
|
+
const newNode = this._ensureNode(item);
|
|
639
|
+
if (!lastInsertedNode) {
|
|
640
|
+
if (prevNode) {
|
|
641
|
+
prevNode.next = newNode;
|
|
642
|
+
}
|
|
643
|
+
else {
|
|
644
|
+
this._head = newNode;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
else {
|
|
648
|
+
lastInsertedNode.next = newNode;
|
|
649
|
+
}
|
|
650
|
+
lastInsertedNode = newNode;
|
|
651
|
+
}
|
|
652
|
+
// Connect new node to `nextNode`
|
|
653
|
+
if (lastInsertedNode) {
|
|
654
|
+
lastInsertedNode.next = nextNode;
|
|
655
|
+
}
|
|
656
|
+
else if (prevNode) {
|
|
657
|
+
prevNode.next = nextNode;
|
|
658
|
+
}
|
|
659
|
+
// Update tail node and length
|
|
660
|
+
if (!nextNode) {
|
|
661
|
+
this._tail = lastInsertedNode || prevNode;
|
|
662
|
+
}
|
|
663
|
+
this._length += items.length - removedList.length;
|
|
664
|
+
return removedList;
|
|
665
|
+
}
|
|
610
666
|
/**
|
|
611
667
|
* Time Complexity: O(n)
|
|
612
668
|
* Space Complexity: O(1)
|
|
@@ -640,7 +696,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
640
696
|
* is a clone of the original list.
|
|
641
697
|
*/
|
|
642
698
|
clone() {
|
|
643
|
-
return new SinglyLinkedList(this, { toElementFn: this.toElementFn });
|
|
699
|
+
return new SinglyLinkedList(this, { toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
644
700
|
}
|
|
645
701
|
/**
|
|
646
702
|
* Time Complexity: O(n)
|
|
@@ -660,7 +716,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
660
716
|
* elements that pass the filter condition specified by the `callback` function.
|
|
661
717
|
*/
|
|
662
718
|
filter(callback, thisArg) {
|
|
663
|
-
const filteredList =
|
|
719
|
+
const filteredList = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
664
720
|
let index = 0;
|
|
665
721
|
for (const current of this) {
|
|
666
722
|
if (callback.call(thisArg, current, index, this)) {
|
|
@@ -691,7 +747,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
691
747
|
* @returns a new instance of the `SinglyLinkedList` class with the mapped elements.
|
|
692
748
|
*/
|
|
693
749
|
map(callback, toElementFn, thisArg) {
|
|
694
|
-
const mappedList = new SinglyLinkedList([], { toElementFn });
|
|
750
|
+
const mappedList = new SinglyLinkedList([], { toElementFn, maxLen: this._maxLen });
|
|
695
751
|
let index = 0;
|
|
696
752
|
for (const current of this) {
|
|
697
753
|
mappedList.push(callback.call(thisArg, current, index, this));
|
|
@@ -699,6 +755,19 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
699
755
|
}
|
|
700
756
|
return mappedList;
|
|
701
757
|
}
|
|
758
|
+
/**
|
|
759
|
+
* The function `_createInstance` returns a new instance of `SinglyLinkedList` with the specified
|
|
760
|
+
* options.
|
|
761
|
+
* @param [options] - The `options` parameter in the `_createInstance` method is of type
|
|
762
|
+
* `SinglyLinkedListOptions<E, R>`, which is used to configure the behavior of the `SinglyLinkedList`
|
|
763
|
+
* instance being created. It is an optional parameter, meaning it can be omitted when calling the
|
|
764
|
+
* method.
|
|
765
|
+
* @returns An instance of the `SinglyLinkedList` class with an empty array and the provided options
|
|
766
|
+
* is being returned.
|
|
767
|
+
*/
|
|
768
|
+
_createInstance(options) {
|
|
769
|
+
return new SinglyLinkedList([], options);
|
|
770
|
+
}
|
|
702
771
|
/**
|
|
703
772
|
* The function `_getIterator` returns an iterable iterator that yields the values of a linked list.
|
|
704
773
|
*/
|
|
@@ -709,6 +778,33 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
709
778
|
current = current.next;
|
|
710
779
|
}
|
|
711
780
|
}
|
|
781
|
+
/**
|
|
782
|
+
* The function returns an iterator that iterates over the elements of a collection in reverse order.
|
|
783
|
+
*/
|
|
784
|
+
*_getReverseIterator() {
|
|
785
|
+
const reversedArr = [...this].reverse();
|
|
786
|
+
for (const item of reversedArr) {
|
|
787
|
+
yield item;
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* The function `_getNodeIterator` returns an iterator that iterates over the nodes of a singly
|
|
792
|
+
* linked list.
|
|
793
|
+
*/
|
|
794
|
+
*_getNodeIterator() {
|
|
795
|
+
let current = this.head;
|
|
796
|
+
while (current) {
|
|
797
|
+
yield current;
|
|
798
|
+
current = current.next;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
// protected *_getReverseNodeIterator(): IterableIterator<SinglyLinkedListNode<E>> {
|
|
802
|
+
// const reversedArr = [...this._getNodeIterator()].reverse();
|
|
803
|
+
//
|
|
804
|
+
// for (const item of reversedArr) {
|
|
805
|
+
// yield item;
|
|
806
|
+
// }
|
|
807
|
+
// }
|
|
712
808
|
/**
|
|
713
809
|
* The _isPredicate function in TypeScript checks if the input is a function that takes a
|
|
714
810
|
* SinglyLinkedListNode as an argument and returns a boolean.
|
|
@@ -751,5 +847,23 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
751
847
|
return elementNodeOrPredicate;
|
|
752
848
|
return (node) => node.value === elementNodeOrPredicate;
|
|
753
849
|
}
|
|
850
|
+
/**
|
|
851
|
+
* The function `_getPrevNode` returns the node before a given node in a singly linked list.
|
|
852
|
+
* @param node - The `node` parameter in the `_getPrevNode` method is a reference to a node in a
|
|
853
|
+
* singly linked list. The method is used to find the node that comes before the given node in the
|
|
854
|
+
* linked list.
|
|
855
|
+
* @returns The `_getPrevNode` method returns either the previous node of the input node in a singly
|
|
856
|
+
* linked list or `undefined` if the input node is the head of the list or if the input node is not
|
|
857
|
+
* found in the list.
|
|
858
|
+
*/
|
|
859
|
+
_getPrevNode(node) {
|
|
860
|
+
if (!this.head || this.head === node)
|
|
861
|
+
return undefined;
|
|
862
|
+
let current = this.head;
|
|
863
|
+
while (current.next && current.next !== node) {
|
|
864
|
+
current = current.next;
|
|
865
|
+
}
|
|
866
|
+
return current.next === node ? current : undefined;
|
|
867
|
+
}
|
|
754
868
|
}
|
|
755
869
|
exports.SinglyLinkedList = SinglyLinkedList;
|
|
@@ -45,7 +45,7 @@ export declare class MaxPriorityQueue<E = any, R = any> extends PriorityQueue<E,
|
|
|
45
45
|
* @returns The `filter` method is returning a new `MaxPriorityQueue` object that contains the elements that pass
|
|
46
46
|
* the filter condition specified by the `callback` function.
|
|
47
47
|
*/
|
|
48
|
-
filter(callback: ElementCallback<E, R, boolean
|
|
48
|
+
filter(callback: ElementCallback<E, R, boolean>, thisArg?: any): MaxPriorityQueue<E, R>;
|
|
49
49
|
/**
|
|
50
50
|
* Time Complexity: O(n log n)
|
|
51
51
|
* Space Complexity: O(n)
|
|
@@ -67,5 +67,5 @@ export declare class MaxPriorityQueue<E = any, R = any> extends PriorityQueue<E,
|
|
|
67
67
|
* value of
|
|
68
68
|
* @returns a new instance of the `MaxPriorityQueue` class with the mapped elements.
|
|
69
69
|
*/
|
|
70
|
-
map<EM, RM>(callback: ElementCallback<E, R, EM
|
|
70
|
+
map<EM, RM>(callback: ElementCallback<E, R, EM>, comparator: Comparator<EM>, toElementFn?: (rawElement: RM) => EM, thisArg?: any): MaxPriorityQueue<EM, RM>;
|
|
71
71
|
}
|