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 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
- ![](https://github.com/zrwusa/assets/blob/master/images/data-structure-typed/methods-8bit/min-heap.png?raw=true)
37
- Max Heap
38
- ![](https://github.com/zrwusa/assets/blob/master/images/data-structure-typed/methods-8bit/max-heap.png?raw=true)
39
-
40
33
  ### snippet
41
34
 
42
- #### heap sort TS
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
- const heap = new Heap<number>(arr, {comparator: (a, b) => a - b});
52
- const sorted: number[] = [];
53
- while (!heap.isEmpty()) {
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
- const heap = new Heap<number>([], {comparator: (a, b) => b - a}); // Max heap
70
- arr.forEach((num) => {
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
- return heap.toArray();
75
- }
59
+ });
60
+ return heap.toArray();
61
+ }
76
62
 
77
- const numbers = [10, 30, 20, 5, 15, 25];
78
- console.log('Top K:', topKElements(numbers, 3)); // [15, 10, 5]
63
+ const numbers = [10, 30, 20, 5, 15, 25];
64
+ console.log(topKElements(numbers, 3)); // [15, 10, 5]
79
65
  ```
80
66
 
81
- #### real-time median TS
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
- private low: MaxHeap<number>; // Max heap, stores the smaller half
87
- private high: MinHeap<number>; // Min heap, stores the larger half
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
- constructor() {
112
+ constructor() {
90
113
  this.low = new MaxHeap<number>([]);
91
114
  this.high = new MinHeap<number>([]);
92
- }
115
+ }
93
116
 
94
- addNum(num: number): void {
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
- findMedian(): number {
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
- #### load balance TS
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
- const serverHeap = new Heap<{ id: number; load: number }>([], { comparator: (a, b) => a.load - b.load }); // min heap
127
- const serverLoads = new Array(servers).fill(0);
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
- for (let i = 0; i < servers; i++) {
151
+ for (let i = 0; i < servers; i++) {
130
152
  serverHeap.add({ id: i, load: 0 });
131
- }
153
+ }
132
154
 
133
- requests.forEach(req => {
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
- return serverLoads;
141
- }
162
+ return serverLoads;
163
+ }
142
164
 
143
- const requests = [5, 2, 8, 3, 7];
144
- const serversLoads = loadBalance(requests, 3);
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
- const minNumHeap = new MinHeap<number>([1, 6, 2, 0, 5]);
151
- minNumHeap.add(9);
152
- minNumHeap.has(1) // true
153
- minNumHeap.has(2) // true
154
- minNumHeap.poll() // 0
155
- minNumHeap.poll() // 1
156
- minNumHeap.peek() // 2
157
- minNumHeap.has(1); // false
158
- minNumHeap.has(2); // true
159
-
160
- const arrFromHeap = minNumHeap.toArray();
161
- arrFromHeap.length // 4
162
- arrFromHeap[0] // 2
163
- arrFromHeap[1] // 5
164
- arrFromHeap[2] // 9
165
- arrFromHeap[3] // 6
166
- minNumHeap.sort() // [2, 5, 6, 9]
167
-
168
- const maxHeap = new MaxHeap<{ keyA: string }>([], {comparator: (a, b) => b.keyA - a.keyA});
169
- const obj1 = {keyA: 'a1'}, obj6 = {keyA: 'a6'}, obj5 = {keyA: 'a5'}, obj2 = {keyA: 'a2'},
170
- obj0 = {keyA: 'a0'}, obj9 = {keyA: 'a9'};
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
- #### conventional operation JS
199
-
200
- ```javascript
201
- const {MinHeap, MaxHeap} = require('data-structure-typed');
202
- // /* or if you prefer */ const {MinHeap, MaxHeap} = require('heap-typed');
203
-
204
- const minNumHeap = new MinHeap([1, 6, 2, 0, 5]);
205
- minNumHeap.add(9);
206
- minNumHeap.has(1) // true
207
- minNumHeap.has(2) // true
208
- minNumHeap.poll() // 0
209
- minNumHeap.poll() // 1
210
- minNumHeap.peek() // 2
211
- minNumHeap.has(1); // false
212
- minNumHeap.has(2); // true
213
-
214
- const arrFromHeap = minNumHeap.toArray();
215
- arrFromHeap.length // 4
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