heap-typed 1.53.4 → 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 +163 -76
- package/dist/data-structures/linked-list/doubly-linked-list.js +211 -104
- 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 +232 -105
- 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
|
|