heap-typed 1.53.5 → 1.53.6
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/README.md +132 -167
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +13 -11
- package/dist/data-structures/linked-list/doubly-linked-list.js +27 -26
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +144 -62
- package/dist/data-structures/linked-list/singly-linked-list.js +201 -97
- package/package.json +2 -2
- package/src/data-structures/linked-list/doubly-linked-list.ts +30 -26
- package/src/data-structures/linked-list/singly-linked-list.ts +219 -98
package/README.md
CHANGED
|
@@ -30,225 +30,190 @@ npm i heap-typed --save
|
|
|
30
30
|
yarn add heap-typed
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
### methods
|
|
34
|
-
|
|
35
|
-
Min Heap
|
|
36
|
-

|
|
37
|
-
Max Heap
|
|
38
|
-

|
|
39
|
-
|
|
40
33
|
### snippet
|
|
41
34
|
|
|
42
|
-
|
|
35
|
+
[//]: # (No deletion!!! Start of Example Replace Section)
|
|
43
36
|
|
|
37
|
+
### Use Heap to sort an array
|
|
44
38
|
```typescript
|
|
45
|
-
import {Heap, MaxHeap, MinHeap} from 'data-structure-typed';
|
|
46
|
-
|
|
47
|
-
// /* or if you prefer */ import {MinHeap, MaxHeap} from 'heap-typed';
|
|
48
|
-
|
|
49
|
-
// Use Heap to sort an array
|
|
50
39
|
function heapSort(arr: number[]): number[] {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
40
|
+
const heap = new Heap<number>(arr, { comparator: (a, b) => a - b });
|
|
41
|
+
const sorted: number[] = [];
|
|
42
|
+
while (!heap.isEmpty()) {
|
|
54
43
|
sorted.push(heap.poll()!); // Poll minimum element
|
|
44
|
+
}
|
|
45
|
+
return sorted;
|
|
55
46
|
}
|
|
56
|
-
return sorted;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
console.log('Heap sorted:', heapSort([5, 3, 8, 4, 1, 2])); // [1, 2, 3, 4, 5, 8];
|
|
60
47
|
|
|
48
|
+
const array = [5, 3, 8, 4, 1, 2];
|
|
49
|
+
console.log(heapSort(array)); // [1, 2, 3, 4, 5, 8]
|
|
61
50
|
```
|
|
62
51
|
|
|
63
|
-
|
|
64
|
-
#### top K problem TS
|
|
65
|
-
|
|
52
|
+
### Use Heap to solve top k problems
|
|
66
53
|
```typescript
|
|
67
|
-
// Use Heap to resolve top K problem
|
|
68
54
|
function topKElements(arr: number[], k: number): number[] {
|
|
69
|
-
|
|
70
|
-
|
|
55
|
+
const heap = new Heap<number>([], { comparator: (a, b) => b - a }); // Max heap
|
|
56
|
+
arr.forEach(num => {
|
|
71
57
|
heap.add(num);
|
|
72
58
|
if (heap.size > k) heap.poll(); // Keep the heap size at K
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
59
|
+
});
|
|
60
|
+
return heap.toArray();
|
|
61
|
+
}
|
|
76
62
|
|
|
77
|
-
const numbers = [10, 30, 20, 5, 15, 25];
|
|
78
|
-
console.log(
|
|
63
|
+
const numbers = [10, 30, 20, 5, 15, 25];
|
|
64
|
+
console.log(topKElements(numbers, 3)); // [15, 10, 5]
|
|
79
65
|
```
|
|
80
66
|
|
|
81
|
-
|
|
67
|
+
### Use Heap to merge sorted sequences
|
|
68
|
+
```typescript
|
|
69
|
+
function mergeSortedSequences(sequences: number[][]): number[] {
|
|
70
|
+
const heap = new Heap<{ value: number; seqIndex: number; itemIndex: number }>([], {
|
|
71
|
+
comparator: (a, b) => a.value - b.value // Min heap
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Initialize heap
|
|
75
|
+
sequences.forEach((seq, seqIndex) => {
|
|
76
|
+
if (seq.length) {
|
|
77
|
+
heap.add({ value: seq[0], seqIndex, itemIndex: 0 });
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const merged: number[] = [];
|
|
82
|
+
while (!heap.isEmpty()) {
|
|
83
|
+
const { value, seqIndex, itemIndex } = heap.poll()!;
|
|
84
|
+
merged.push(value);
|
|
85
|
+
|
|
86
|
+
if (itemIndex + 1 < sequences[seqIndex].length) {
|
|
87
|
+
heap.add({
|
|
88
|
+
value: sequences[seqIndex][itemIndex + 1],
|
|
89
|
+
seqIndex,
|
|
90
|
+
itemIndex: itemIndex + 1
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return merged;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const sequences = [
|
|
99
|
+
[1, 4, 7],
|
|
100
|
+
[2, 5, 8],
|
|
101
|
+
[3, 6, 9]
|
|
102
|
+
];
|
|
103
|
+
console.log(mergeSortedSequences(sequences)); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
104
|
+
```
|
|
82
105
|
|
|
106
|
+
### Use Heap to dynamically maintain the median
|
|
83
107
|
```typescript
|
|
84
|
-
// Use Heap to maintain median value for real-time retrieval
|
|
85
108
|
class MedianFinder {
|
|
86
|
-
|
|
87
|
-
|
|
109
|
+
private low: MaxHeap<number>; // Max heap, stores the smaller half
|
|
110
|
+
private high: MinHeap<number>; // Min heap, stores the larger half
|
|
88
111
|
|
|
89
|
-
|
|
112
|
+
constructor() {
|
|
90
113
|
this.low = new MaxHeap<number>([]);
|
|
91
114
|
this.high = new MinHeap<number>([]);
|
|
92
|
-
|
|
115
|
+
}
|
|
93
116
|
|
|
94
|
-
|
|
117
|
+
addNum(num: number): void {
|
|
95
118
|
if (this.low.isEmpty() || num <= this.low.peek()!) this.low.add(num);
|
|
96
119
|
else this.high.add(num);
|
|
97
120
|
|
|
98
121
|
// Balance heaps
|
|
99
122
|
if (this.low.size > this.high.size + 1) this.high.add(this.low.poll()!);
|
|
100
123
|
else if (this.high.size > this.low.size) this.low.add(this.high.poll()!);
|
|
101
|
-
|
|
124
|
+
}
|
|
102
125
|
|
|
103
|
-
|
|
126
|
+
findMedian(): number {
|
|
127
|
+
if (this.low.size === this.high.size) return (this.low.peek()! + this.high.peek()!) / 2;
|
|
104
128
|
return this.low.peek()!;
|
|
129
|
+
}
|
|
105
130
|
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const medianFinder = new MedianFinder();
|
|
109
|
-
medianFinder.addNum(10);
|
|
110
|
-
console.log('realtime median: ', medianFinder.findMedian()) // 10
|
|
111
|
-
medianFinder.addNum(20);
|
|
112
|
-
console.log('realtime median: ', medianFinder.findMedian()) // 10
|
|
113
|
-
medianFinder.addNum(30);
|
|
114
|
-
console.log('realtime median: ', medianFinder.findMedian()) // 20
|
|
115
|
-
medianFinder.addNum(40);
|
|
116
|
-
console.log('realtime median: ', medianFinder.findMedian()) // 20
|
|
117
|
-
medianFinder.addNum(50);
|
|
118
|
-
console.log('realtime median: ', medianFinder.findMedian()) // 30
|
|
119
|
-
```
|
|
120
131
|
|
|
121
|
-
|
|
132
|
+
const medianFinder = new MedianFinder();
|
|
133
|
+
medianFinder.addNum(10);
|
|
134
|
+
console.log(medianFinder.findMedian()); // 10
|
|
135
|
+
medianFinder.addNum(20);
|
|
136
|
+
console.log(medianFinder.findMedian()); // 15
|
|
137
|
+
medianFinder.addNum(30);
|
|
138
|
+
console.log(medianFinder.findMedian()); // 20
|
|
139
|
+
medianFinder.addNum(40);
|
|
140
|
+
console.log(medianFinder.findMedian()); // 25
|
|
141
|
+
medianFinder.addNum(50);
|
|
142
|
+
console.log(medianFinder.findMedian()); // 30
|
|
143
|
+
```
|
|
122
144
|
|
|
145
|
+
### Use Heap for load balancing
|
|
123
146
|
```typescript
|
|
124
|
-
// Use Heap for load balancing
|
|
125
147
|
function loadBalance(requests: number[], servers: number): number[] {
|
|
126
|
-
|
|
127
|
-
|
|
148
|
+
const serverHeap = new Heap<{ id: number; load: number }>([], { comparator: (a, b) => a.load - b.load }); // min heap
|
|
149
|
+
const serverLoads = new Array(servers).fill(0);
|
|
128
150
|
|
|
129
|
-
|
|
151
|
+
for (let i = 0; i < servers; i++) {
|
|
130
152
|
serverHeap.add({ id: i, load: 0 });
|
|
131
|
-
|
|
153
|
+
}
|
|
132
154
|
|
|
133
|
-
|
|
155
|
+
requests.forEach(req => {
|
|
134
156
|
const server = serverHeap.poll()!;
|
|
135
157
|
serverLoads[server.id] += req;
|
|
136
158
|
server.load += req;
|
|
137
159
|
serverHeap.add(server); // The server after updating the load is re-entered into the heap
|
|
138
|
-
|
|
160
|
+
});
|
|
139
161
|
|
|
140
|
-
|
|
141
|
-
}
|
|
162
|
+
return serverLoads;
|
|
163
|
+
}
|
|
142
164
|
|
|
143
|
-
const requests = [5, 2, 8, 3, 7];
|
|
144
|
-
|
|
145
|
-
console.log('server loads: ', serversLoads); // [12, 8, 5]
|
|
165
|
+
const requests = [5, 2, 8, 3, 7];
|
|
166
|
+
console.log(loadBalance(requests, 3)); // [12, 8, 5]
|
|
146
167
|
```
|
|
147
|
-
#### conventional operation TS
|
|
148
168
|
|
|
169
|
+
### Use Heap to schedule tasks
|
|
149
170
|
```typescript
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
maxHeap.add(obj1);
|
|
173
|
-
maxHeap.has(obj1) // true
|
|
174
|
-
maxHeap.has(obj9) // false
|
|
175
|
-
maxHeap.add(obj6);
|
|
176
|
-
maxHeap.has(obj6) // true
|
|
177
|
-
maxHeap.add(obj5);
|
|
178
|
-
maxHeap.add(obj2);
|
|
179
|
-
maxHeap.add(obj0);
|
|
180
|
-
maxHeap.add(obj9);
|
|
181
|
-
maxHeap.has(obj9) // true
|
|
182
|
-
|
|
183
|
-
const peek9 = maxHeap.peek();
|
|
184
|
-
console.log(peek9.keyA) // 'a9'
|
|
185
|
-
|
|
186
|
-
const heapToArr = maxHeap.toArray();
|
|
187
|
-
console.log(heapToArr.map(ele => ele?.keyA)); // ['a9', 'a2', 'a6', 'a1', 'a0', 'a5']
|
|
188
|
-
|
|
189
|
-
const values = ['a9', 'a6', 'a5', 'a2', 'a1', 'a0'];
|
|
190
|
-
let i = 0;
|
|
191
|
-
while (maxHeap.size > 0) {
|
|
192
|
-
const polled = maxHeap.poll();
|
|
193
|
-
console.log(polled.keyA) // values[i]
|
|
194
|
-
i++;
|
|
195
|
-
}
|
|
196
|
-
```
|
|
171
|
+
type Task = [string, number];
|
|
172
|
+
|
|
173
|
+
function scheduleTasks(tasks: Task[], machines: number): Map<number, Task[]> {
|
|
174
|
+
const machineHeap = new Heap<{ id: number; load: number }>([], { comparator: (a, b) => a.load - b.load }); // Min heap
|
|
175
|
+
const allocation = new Map<number, Task[]>();
|
|
176
|
+
|
|
177
|
+
// Initialize the load on each machine
|
|
178
|
+
for (let i = 0; i < machines; i++) {
|
|
179
|
+
machineHeap.add({ id: i, load: 0 });
|
|
180
|
+
allocation.set(i, []);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Assign tasks
|
|
184
|
+
tasks.forEach(([task, load]) => {
|
|
185
|
+
const machine = machineHeap.poll()!;
|
|
186
|
+
allocation.get(machine.id)!.push([task, load]);
|
|
187
|
+
machine.load += load;
|
|
188
|
+
machineHeap.add(machine); // The machine after updating the load is re-entered into the heap
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
return allocation;
|
|
192
|
+
}
|
|
197
193
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
arrFromHeap[0] // 2
|
|
217
|
-
arrFromHeap[1] // 5
|
|
218
|
-
arrFromHeap[2] // 9
|
|
219
|
-
arrFromHeap[3] // 6
|
|
220
|
-
minNumHeap.sort() // [2, 5, 6, 9]
|
|
221
|
-
|
|
222
|
-
const maxHeap = new MaxHeap([], {comparator: (a, b) => b.keyA - a.keyA});
|
|
223
|
-
const obj1 = {keyA: 'a1'}, obj6 = {keyA: 'a6'}, obj5 = {keyA: 'a5'}, obj2 = {keyA: 'a2'},
|
|
224
|
-
obj0 = {keyA: 'a0'}, obj9 = {keyA: 'a9'};
|
|
225
|
-
|
|
226
|
-
maxHeap.add(obj1);
|
|
227
|
-
maxHeap.has(obj1) // true
|
|
228
|
-
maxHeap.has(obj9) // false
|
|
229
|
-
maxHeap.add(obj6);
|
|
230
|
-
maxHeap.has(obj6) // true
|
|
231
|
-
maxHeap.add(obj5);
|
|
232
|
-
maxHeap.add(obj2);
|
|
233
|
-
maxHeap.add(obj0);
|
|
234
|
-
maxHeap.add(obj9);
|
|
235
|
-
maxHeap.has(obj9) // true
|
|
236
|
-
|
|
237
|
-
const peek9 = maxHeap.peek();
|
|
238
|
-
console.log(peek9.keyA) // 'a9'
|
|
239
|
-
|
|
240
|
-
const heapToArr = maxHeap.toArray();
|
|
241
|
-
console.log(heapToArr.map(ele => ele?.keyA)); // ['a9', 'a2', 'a6', 'a1', 'a0', 'a5']
|
|
242
|
-
|
|
243
|
-
const values = ['a9', 'a6', 'a5', 'a2', 'a1', 'a0'];
|
|
244
|
-
let i = 0;
|
|
245
|
-
while (maxHeap.size > 0) {
|
|
246
|
-
const polled = maxHeap.poll();
|
|
247
|
-
console.log(polled.keyA) // values[i]
|
|
248
|
-
i++;
|
|
249
|
-
}
|
|
194
|
+
const tasks: Task[] = [
|
|
195
|
+
['Task1', 3],
|
|
196
|
+
['Task2', 1],
|
|
197
|
+
['Task3', 2],
|
|
198
|
+
['Task4', 5],
|
|
199
|
+
['Task5', 4]
|
|
200
|
+
];
|
|
201
|
+
const expectedMap = new Map<number, Task[]>();
|
|
202
|
+
expectedMap.set(0, [
|
|
203
|
+
['Task1', 3],
|
|
204
|
+
['Task4', 5]
|
|
205
|
+
]);
|
|
206
|
+
expectedMap.set(1, [
|
|
207
|
+
['Task2', 1],
|
|
208
|
+
['Task3', 2],
|
|
209
|
+
['Task5', 4]
|
|
210
|
+
]);
|
|
211
|
+
console.log(scheduleTasks(tasks, 2)); // expectedMap
|
|
250
212
|
```
|
|
251
213
|
|
|
214
|
+
[//]: # (No deletion!!! End of Example Replace Section)
|
|
215
|
+
|
|
216
|
+
|
|
252
217
|
|
|
253
218
|
## API docs & Examples
|
|
254
219
|
|
|
@@ -709,22 +709,18 @@ export declare class DoublyLinkedList<E = any, R = any> extends IterableElementB
|
|
|
709
709
|
* Time Complexity: O(n)
|
|
710
710
|
* Space Complexity: O(1)
|
|
711
711
|
*
|
|
712
|
-
*
|
|
713
|
-
*
|
|
714
|
-
*
|
|
715
|
-
*
|
|
716
|
-
*
|
|
717
|
-
*
|
|
718
|
-
* list. If the element or node is found in the list, the method returns the index of that element or
|
|
719
|
-
* node. If the element or node is not found in the list, the method returns -1.
|
|
712
|
+
* This function finds the index of a specified element, node, or predicate in a doubly linked list.
|
|
713
|
+
* @param {E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)} elementNodeOrPredicate
|
|
714
|
+
* elementNodeOrPredicate - The `indexOf` method takes in a parameter `elementNodeOrPredicate`, which
|
|
715
|
+
* can be one of the following:
|
|
716
|
+
* @returns The `indexOf` method returns the index of the element in the doubly linked list that
|
|
717
|
+
* matches the provided element, node, or predicate. If no match is found, it returns -1.
|
|
720
718
|
*/
|
|
721
|
-
indexOf(
|
|
719
|
+
indexOf(elementNodeOrPredicate: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)): number;
|
|
722
720
|
/**
|
|
723
721
|
* Time Complexity: O(n)
|
|
724
722
|
* Space Complexity: O(1)
|
|
725
723
|
*
|
|
726
|
-
*/
|
|
727
|
-
/**
|
|
728
724
|
* This function retrieves an element from a doubly linked list based on a given element
|
|
729
725
|
* node or predicate.
|
|
730
726
|
* @param {E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)} elementNodeOrPredicate
|
|
@@ -820,6 +816,12 @@ export declare class DoublyLinkedList<E = any, R = any> extends IterableElementB
|
|
|
820
816
|
* @returns a new instance of the `DoublyLinkedList` class with elements of type `T` and `RR`.
|
|
821
817
|
*/
|
|
822
818
|
map<EM, RM>(callback: ElementCallback<E, R, EM, DoublyLinkedList<E, R>>, toElementFn?: (rawElement: RM) => EM, thisArg?: any): DoublyLinkedList<EM, RM>;
|
|
819
|
+
/**
|
|
820
|
+
* Time Complexity: O(n)
|
|
821
|
+
* Space Complexity: O(1)
|
|
822
|
+
*
|
|
823
|
+
*/
|
|
824
|
+
countOccurrences(elementOrNode: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)): number;
|
|
823
825
|
/**
|
|
824
826
|
* Time Complexity: O(n)
|
|
825
827
|
* Space Complexity: O(n)
|
|
@@ -784,13 +784,7 @@ class DoublyLinkedList extends base_1.IterableElementBase {
|
|
|
784
784
|
* node was not found.
|
|
785
785
|
*/
|
|
786
786
|
addBefore(existingElementOrNode, newElementOrNode) {
|
|
787
|
-
|
|
788
|
-
if (existingElementOrNode instanceof DoublyLinkedListNode) {
|
|
789
|
-
existingNode = existingElementOrNode;
|
|
790
|
-
}
|
|
791
|
-
else {
|
|
792
|
-
existingNode = this.getNode(existingElementOrNode);
|
|
793
|
-
}
|
|
787
|
+
const existingNode = this.getNode(existingElementOrNode);
|
|
794
788
|
if (existingNode) {
|
|
795
789
|
const newNode = this._ensureNode(newElementOrNode);
|
|
796
790
|
newNode.prev = existingNode.prev;
|
|
@@ -824,13 +818,7 @@ class DoublyLinkedList extends base_1.IterableElementBase {
|
|
|
824
818
|
* was not found in the linked list.
|
|
825
819
|
*/
|
|
826
820
|
addAfter(existingElementOrNode, newElementOrNode) {
|
|
827
|
-
|
|
828
|
-
if (existingElementOrNode instanceof DoublyLinkedListNode) {
|
|
829
|
-
existingNode = existingElementOrNode;
|
|
830
|
-
}
|
|
831
|
-
else {
|
|
832
|
-
existingNode = this.getNode(existingElementOrNode);
|
|
833
|
-
}
|
|
821
|
+
const existingNode = this.getNode(existingElementOrNode);
|
|
834
822
|
if (existingNode) {
|
|
835
823
|
const newNode = this._ensureNode(newElementOrNode);
|
|
836
824
|
newNode.next = existingNode.next;
|
|
@@ -936,17 +924,15 @@ class DoublyLinkedList extends base_1.IterableElementBase {
|
|
|
936
924
|
* Time Complexity: O(n)
|
|
937
925
|
* Space Complexity: O(1)
|
|
938
926
|
*
|
|
939
|
-
*
|
|
940
|
-
*
|
|
941
|
-
*
|
|
942
|
-
*
|
|
943
|
-
*
|
|
944
|
-
*
|
|
945
|
-
* list. If the element or node is found in the list, the method returns the index of that element or
|
|
946
|
-
* node. If the element or node is not found in the list, the method returns -1.
|
|
927
|
+
* This function finds the index of a specified element, node, or predicate in a doubly linked list.
|
|
928
|
+
* @param {E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)} elementNodeOrPredicate
|
|
929
|
+
* elementNodeOrPredicate - The `indexOf` method takes in a parameter `elementNodeOrPredicate`, which
|
|
930
|
+
* can be one of the following:
|
|
931
|
+
* @returns The `indexOf` method returns the index of the element in the doubly linked list that
|
|
932
|
+
* matches the provided element, node, or predicate. If no match is found, it returns -1.
|
|
947
933
|
*/
|
|
948
|
-
indexOf(
|
|
949
|
-
const predicate = this._ensurePredicate(
|
|
934
|
+
indexOf(elementNodeOrPredicate) {
|
|
935
|
+
const predicate = this._ensurePredicate(elementNodeOrPredicate);
|
|
950
936
|
let index = 0;
|
|
951
937
|
let current = this.head;
|
|
952
938
|
while (current) {
|
|
@@ -962,8 +948,6 @@ class DoublyLinkedList extends base_1.IterableElementBase {
|
|
|
962
948
|
* Time Complexity: O(n)
|
|
963
949
|
* Space Complexity: O(1)
|
|
964
950
|
*
|
|
965
|
-
*/
|
|
966
|
-
/**
|
|
967
951
|
* This function retrieves an element from a doubly linked list based on a given element
|
|
968
952
|
* node or predicate.
|
|
969
953
|
* @param {E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)} elementNodeOrPredicate
|
|
@@ -1122,6 +1106,23 @@ class DoublyLinkedList extends base_1.IterableElementBase {
|
|
|
1122
1106
|
}
|
|
1123
1107
|
return mappedList;
|
|
1124
1108
|
}
|
|
1109
|
+
/**
|
|
1110
|
+
* Time Complexity: O(n)
|
|
1111
|
+
* Space Complexity: O(1)
|
|
1112
|
+
*
|
|
1113
|
+
*/
|
|
1114
|
+
countOccurrences(elementOrNode) {
|
|
1115
|
+
const predicate = this._ensurePredicate(elementOrNode);
|
|
1116
|
+
let count = 0;
|
|
1117
|
+
let current = this.head;
|
|
1118
|
+
while (current) {
|
|
1119
|
+
if (predicate(current)) {
|
|
1120
|
+
count++;
|
|
1121
|
+
}
|
|
1122
|
+
current = current.next;
|
|
1123
|
+
}
|
|
1124
|
+
return count;
|
|
1125
|
+
}
|
|
1125
1126
|
/**
|
|
1126
1127
|
* Time Complexity: O(n)
|
|
1127
1128
|
* Space Complexity: O(n)
|