max-priority-queue-typed 2.4.5 → 2.5.0
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 +63 -0
- package/dist/cjs/index.cjs +400 -119
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +399 -118
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +400 -119
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +399 -118
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +429 -78
- package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +212 -32
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
- package/dist/types/data-structures/graph/directed-graph.d.ts +219 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +204 -59
- package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
- package/dist/types/data-structures/heap/heap.d.ts +287 -99
- package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
- package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
- package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
- package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
- package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
- package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
- package/dist/types/data-structures/queue/deque.d.ts +272 -65
- package/dist/types/data-structures/queue/queue.d.ts +211 -42
- package/dist/types/data-structures/stack/stack.d.ts +174 -32
- package/dist/types/data-structures/trie/trie.d.ts +213 -43
- package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
- package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
- package/dist/umd/max-priority-queue-typed.js +397 -116
- package/dist/umd/max-priority-queue-typed.js.map +1 -1
- package/dist/umd/max-priority-queue-typed.min.js +1 -1
- package/dist/umd/max-priority-queue-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/data-structures/base/iterable-element-base.ts +4 -5
- package/src/data-structures/binary-tree/avl-tree.ts +134 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +302 -247
- package/src/data-structures/binary-tree/binary-tree.ts +429 -79
- package/src/data-structures/binary-tree/bst.ts +335 -34
- package/src/data-structures/binary-tree/red-black-tree.ts +290 -97
- package/src/data-structures/binary-tree/segment-tree.ts +372 -248
- package/src/data-structures/binary-tree/tree-map.ts +1284 -6
- package/src/data-structures/binary-tree/tree-multi-map.ts +1094 -211
- package/src/data-structures/binary-tree/tree-multi-set.ts +858 -65
- package/src/data-structures/binary-tree/tree-set.ts +1136 -9
- package/src/data-structures/graph/directed-graph.ts +219 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +204 -59
- package/src/data-structures/hash/hash-map.ts +230 -77
- package/src/data-structures/heap/heap.ts +287 -99
- package/src/data-structures/heap/max-heap.ts +46 -0
- package/src/data-structures/heap/min-heap.ts +59 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +286 -44
- package/src/data-structures/linked-list/singly-linked-list.ts +278 -65
- package/src/data-structures/linked-list/skip-linked-list.ts +689 -90
- package/src/data-structures/matrix/matrix.ts +416 -12
- package/src/data-structures/priority-queue/max-priority-queue.ts +57 -0
- package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
- package/src/data-structures/priority-queue/priority-queue.ts +60 -0
- package/src/data-structures/queue/deque.ts +272 -65
- package/src/data-structures/queue/queue.ts +211 -42
- package/src/data-structures/stack/stack.ts +174 -32
- package/src/data-structures/trie/trie.ts +213 -43
- package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
- package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
package/README.md
CHANGED
|
@@ -34,6 +34,69 @@ yarn add max-priority-queue
|
|
|
34
34
|
|
|
35
35
|
[//]: # (No deletion!!! Start of Example Replace Section)
|
|
36
36
|
|
|
37
|
+
### Job scheduling by priority
|
|
38
|
+
```typescript
|
|
39
|
+
const jobs = new MaxPriorityQueue<number>();
|
|
40
|
+
|
|
41
|
+
jobs.add(3); // low priority
|
|
42
|
+
jobs.add(7); // high priority
|
|
43
|
+
jobs.add(5); // medium priority
|
|
44
|
+
jobs.add(10); // critical
|
|
45
|
+
|
|
46
|
+
// Highest priority job first
|
|
47
|
+
console.log(jobs.poll()); // 10;
|
|
48
|
+
console.log(jobs.poll()); // 7;
|
|
49
|
+
console.log(jobs.poll()); // 5;
|
|
50
|
+
console.log(jobs.poll()); // 3;
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Auction system with highest bid tracking
|
|
54
|
+
```typescript
|
|
55
|
+
interface Bid {
|
|
56
|
+
bidder: string;
|
|
57
|
+
amount: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const auction = new MaxPriorityQueue<Bid>([], {
|
|
61
|
+
comparator: (a, b) => b.amount - a.amount
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
auction.add({ bidder: 'Alice', amount: 100 });
|
|
65
|
+
auction.add({ bidder: 'Bob', amount: 250 });
|
|
66
|
+
auction.add({ bidder: 'Charlie', amount: 175 });
|
|
67
|
+
|
|
68
|
+
// Current highest bid
|
|
69
|
+
console.log(auction.peek()?.bidder); // 'Bob';
|
|
70
|
+
console.log(auction.peek()?.amount); // 250;
|
|
71
|
+
|
|
72
|
+
// Process winning bid
|
|
73
|
+
const winner = auction.poll()!;
|
|
74
|
+
console.log(winner.bidder); // 'Bob';
|
|
75
|
+
console.log(auction.peek()?.bidder); // 'Charlie';
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### CPU process scheduling
|
|
79
|
+
```typescript
|
|
80
|
+
const cpuQueue = new MaxPriorityQueue<[number, string]>([], {
|
|
81
|
+
comparator: (a, b) => b[0] - a[0]
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
cpuQueue.add([5, 'System process']);
|
|
85
|
+
cpuQueue.add([1, 'Background task']);
|
|
86
|
+
cpuQueue.add([8, 'User interaction']);
|
|
87
|
+
cpuQueue.add([3, 'Network sync']);
|
|
88
|
+
|
|
89
|
+
const order = [];
|
|
90
|
+
while (cpuQueue.size > 0) {
|
|
91
|
+
order.push(cpuQueue.poll()![1]);
|
|
92
|
+
}
|
|
93
|
+
console.log(order); // [
|
|
94
|
+
// 'User interaction',
|
|
95
|
+
// 'System process',
|
|
96
|
+
// 'Network sync',
|
|
97
|
+
// 'Background task'
|
|
98
|
+
// ];
|
|
99
|
+
```
|
|
37
100
|
|
|
38
101
|
[//]: # (No deletion!!! End of Example Replace Section)
|
|
39
102
|
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -3,55 +3,6 @@
|
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
5
5
|
|
|
6
|
-
// src/common/error.ts
|
|
7
|
-
var ERR = {
|
|
8
|
-
// Range / index
|
|
9
|
-
indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
|
|
10
|
-
invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
|
|
11
|
-
// Type / argument
|
|
12
|
-
invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
|
|
13
|
-
comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
|
|
14
|
-
invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
|
|
15
|
-
notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
|
|
16
|
-
invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
|
|
17
|
-
invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
|
|
18
|
-
invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
|
|
19
|
-
reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
|
|
20
|
-
callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
|
|
21
|
-
// State / operation
|
|
22
|
-
invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
|
|
23
|
-
// Matrix
|
|
24
|
-
matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
|
|
25
|
-
matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
|
|
26
|
-
matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
|
|
27
|
-
matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
|
|
28
|
-
matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
// src/common/index.ts
|
|
32
|
-
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
33
|
-
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
34
|
-
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
35
|
-
return DFSOperation2;
|
|
36
|
-
})(DFSOperation || {});
|
|
37
|
-
var Range = class {
|
|
38
|
-
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
39
|
-
this.low = low;
|
|
40
|
-
this.high = high;
|
|
41
|
-
this.includeLow = includeLow;
|
|
42
|
-
this.includeHigh = includeHigh;
|
|
43
|
-
}
|
|
44
|
-
static {
|
|
45
|
-
__name(this, "Range");
|
|
46
|
-
}
|
|
47
|
-
// Determine whether a key is within the range
|
|
48
|
-
isInRange(key, comparator) {
|
|
49
|
-
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
50
|
-
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
51
|
-
return lowCheck && highCheck;
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
|
|
55
6
|
// src/data-structures/base/iterable-element-base.ts
|
|
56
7
|
var IterableElementBase = class {
|
|
57
8
|
static {
|
|
@@ -70,7 +21,7 @@ var IterableElementBase = class {
|
|
|
70
21
|
if (options) {
|
|
71
22
|
const { toElementFn } = options;
|
|
72
23
|
if (typeof toElementFn === "function") this._toElementFn = toElementFn;
|
|
73
|
-
else if (toElementFn) throw new TypeError(
|
|
24
|
+
else if (toElementFn) throw new TypeError("toElementFn must be a function type");
|
|
74
25
|
}
|
|
75
26
|
}
|
|
76
27
|
/**
|
|
@@ -233,7 +184,7 @@ var IterableElementBase = class {
|
|
|
233
184
|
acc = initialValue;
|
|
234
185
|
} else {
|
|
235
186
|
const first = iter.next();
|
|
236
|
-
if (first.done) throw new TypeError(
|
|
187
|
+
if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
|
|
237
188
|
acc = first.value;
|
|
238
189
|
index = 1;
|
|
239
190
|
}
|
|
@@ -275,6 +226,55 @@ var IterableElementBase = class {
|
|
|
275
226
|
}
|
|
276
227
|
};
|
|
277
228
|
|
|
229
|
+
// src/common/error.ts
|
|
230
|
+
var ERR = {
|
|
231
|
+
// Range / index
|
|
232
|
+
indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
|
|
233
|
+
invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
|
|
234
|
+
// Type / argument
|
|
235
|
+
invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
|
|
236
|
+
comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
|
|
237
|
+
invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
|
|
238
|
+
notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
|
|
239
|
+
invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
|
|
240
|
+
invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
|
|
241
|
+
invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
|
|
242
|
+
reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
|
|
243
|
+
callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
|
|
244
|
+
// State / operation
|
|
245
|
+
invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
|
|
246
|
+
// Matrix
|
|
247
|
+
matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
|
|
248
|
+
matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
|
|
249
|
+
matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
|
|
250
|
+
matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
|
|
251
|
+
matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// src/common/index.ts
|
|
255
|
+
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
256
|
+
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
257
|
+
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
258
|
+
return DFSOperation2;
|
|
259
|
+
})(DFSOperation || {});
|
|
260
|
+
var Range = class {
|
|
261
|
+
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
262
|
+
this.low = low;
|
|
263
|
+
this.high = high;
|
|
264
|
+
this.includeLow = includeLow;
|
|
265
|
+
this.includeHigh = includeHigh;
|
|
266
|
+
}
|
|
267
|
+
static {
|
|
268
|
+
__name(this, "Range");
|
|
269
|
+
}
|
|
270
|
+
// Determine whether a key is within the range
|
|
271
|
+
isInRange(key, comparator) {
|
|
272
|
+
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
273
|
+
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
274
|
+
return lowCheck && highCheck;
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
278
278
|
// src/data-structures/heap/heap.ts
|
|
279
279
|
var Heap = class _Heap extends IterableElementBase {
|
|
280
280
|
static {
|
|
@@ -306,10 +306,30 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
306
306
|
return this._elements;
|
|
307
307
|
}
|
|
308
308
|
/**
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
309
|
+
* Get the number of elements.
|
|
310
|
+
* @remarks Time O(1), Space O(1)
|
|
311
|
+
* @returns Heap size.
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
* @example
|
|
324
|
+
* // Track heap capacity
|
|
325
|
+
* const heap = new Heap<number>();
|
|
326
|
+
* console.log(heap.size); // 0;
|
|
327
|
+
* heap.add(10);
|
|
328
|
+
* heap.add(20);
|
|
329
|
+
* console.log(heap.size); // 2;
|
|
330
|
+
* heap.poll();
|
|
331
|
+
* console.log(heap.size); // 1;
|
|
332
|
+
*/
|
|
313
333
|
get size() {
|
|
314
334
|
return this.elements.length;
|
|
315
335
|
}
|
|
@@ -347,21 +367,61 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
347
367
|
return new _Heap(elements, options);
|
|
348
368
|
}
|
|
349
369
|
/**
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
370
|
+
* Insert an element.
|
|
371
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
372
|
+
* @param element - Element to insert.
|
|
373
|
+
* @returns True.
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
* @example
|
|
386
|
+
* // basic Heap creation and add operation
|
|
387
|
+
* // Create a min heap (default)
|
|
388
|
+
* const minHeap = new Heap([5, 3, 7, 1, 9, 2]);
|
|
389
|
+
*
|
|
390
|
+
* // Verify size
|
|
391
|
+
* console.log(minHeap.size); // 6;
|
|
392
|
+
*
|
|
393
|
+
* // Add new element
|
|
394
|
+
* minHeap.add(4);
|
|
395
|
+
* console.log(minHeap.size); // 7;
|
|
396
|
+
*
|
|
397
|
+
* // Min heap property: smallest element at root
|
|
398
|
+
* const min = minHeap.peek();
|
|
399
|
+
* console.log(min); // 1;
|
|
400
|
+
*/
|
|
355
401
|
add(element) {
|
|
356
402
|
this._elements.push(element);
|
|
357
403
|
return this._bubbleUp(this.elements.length - 1);
|
|
358
404
|
}
|
|
359
405
|
/**
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
406
|
+
* Insert many elements from an iterable.
|
|
407
|
+
* @remarks Time O(N log N), Space O(1)
|
|
408
|
+
* @param elements - Iterable of elements or raw values.
|
|
409
|
+
* @returns Array of per-element success flags.
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
* @example
|
|
419
|
+
* // Add multiple elements
|
|
420
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
421
|
+
* heap.addMany([5, 3, 7, 1]);
|
|
422
|
+
* console.log(heap.peek()); // 1;
|
|
423
|
+
* console.log(heap.size); // 4;
|
|
424
|
+
*/
|
|
365
425
|
addMany(elements) {
|
|
366
426
|
const flags = [];
|
|
367
427
|
for (const el of elements) {
|
|
@@ -376,10 +436,46 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
376
436
|
return flags;
|
|
377
437
|
}
|
|
378
438
|
/**
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
439
|
+
* Remove and return the top element.
|
|
440
|
+
* @remarks Time O(log N), Space O(1)
|
|
441
|
+
* @returns Top element or undefined.
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
* @example
|
|
454
|
+
* // Heap with custom comparator (MaxHeap behavior)
|
|
455
|
+
* interface Task {
|
|
456
|
+
* id: number;
|
|
457
|
+
* priority: number;
|
|
458
|
+
* name: string;
|
|
459
|
+
* }
|
|
460
|
+
*
|
|
461
|
+
* // Custom comparator for max heap behavior (higher priority first)
|
|
462
|
+
* const tasks: Task[] = [
|
|
463
|
+
* { id: 1, priority: 5, name: 'Email' },
|
|
464
|
+
* { id: 2, priority: 3, name: 'Chat' },
|
|
465
|
+
* { id: 3, priority: 8, name: 'Alert' }
|
|
466
|
+
* ];
|
|
467
|
+
*
|
|
468
|
+
* const maxHeap = new Heap(tasks, {
|
|
469
|
+
* comparator: (a: Task, b: Task) => b.priority - a.priority
|
|
470
|
+
* });
|
|
471
|
+
*
|
|
472
|
+
* console.log(maxHeap.size); // 3;
|
|
473
|
+
*
|
|
474
|
+
* // Peek returns highest priority task
|
|
475
|
+
* const topTask = maxHeap.peek();
|
|
476
|
+
* console.log(topTask?.priority); // 8;
|
|
477
|
+
* console.log(topTask?.name); // 'Alert';
|
|
478
|
+
*/
|
|
383
479
|
poll() {
|
|
384
480
|
if (this.elements.length === 0) return;
|
|
385
481
|
const value = this.elements[0];
|
|
@@ -391,26 +487,125 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
391
487
|
return value;
|
|
392
488
|
}
|
|
393
489
|
/**
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
490
|
+
* Get the current top element without removing it.
|
|
491
|
+
* @remarks Time O(1), Space O(1)
|
|
492
|
+
* @returns Top element or undefined.
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
* @example
|
|
505
|
+
* // Heap for event processing with priority
|
|
506
|
+
* interface Event {
|
|
507
|
+
* id: number;
|
|
508
|
+
* type: 'critical' | 'warning' | 'info';
|
|
509
|
+
* timestamp: number;
|
|
510
|
+
* message: string;
|
|
511
|
+
* }
|
|
512
|
+
*
|
|
513
|
+
* // Custom priority: critical > warning > info
|
|
514
|
+
* const priorityMap = { critical: 3, warning: 2, info: 1 };
|
|
515
|
+
*
|
|
516
|
+
* const eventHeap = new Heap<Event>([], {
|
|
517
|
+
* comparator: (a: Event, b: Event) => {
|
|
518
|
+
* const priorityA = priorityMap[a.type];
|
|
519
|
+
* const priorityB = priorityMap[b.type];
|
|
520
|
+
* return priorityB - priorityA; // Higher priority first
|
|
521
|
+
* }
|
|
522
|
+
* });
|
|
523
|
+
*
|
|
524
|
+
* // Add events in random order
|
|
525
|
+
* eventHeap.add({ id: 1, type: 'info', timestamp: 100, message: 'User logged in' });
|
|
526
|
+
* eventHeap.add({ id: 2, type: 'critical', timestamp: 101, message: 'Server down' });
|
|
527
|
+
* eventHeap.add({ id: 3, type: 'warning', timestamp: 102, message: 'High memory' });
|
|
528
|
+
* eventHeap.add({ id: 4, type: 'info', timestamp: 103, message: 'Cache cleared' });
|
|
529
|
+
* eventHeap.add({ id: 5, type: 'critical', timestamp: 104, message: 'Database error' });
|
|
530
|
+
*
|
|
531
|
+
* console.log(eventHeap.size); // 5;
|
|
532
|
+
*
|
|
533
|
+
* // Process events by priority (critical first)
|
|
534
|
+
* const processedOrder: Event[] = [];
|
|
535
|
+
* while (eventHeap.size > 0) {
|
|
536
|
+
* const event = eventHeap.poll();
|
|
537
|
+
* if (event) {
|
|
538
|
+
* processedOrder.push(event);
|
|
539
|
+
* }
|
|
540
|
+
* }
|
|
541
|
+
*
|
|
542
|
+
* // Verify critical events came first
|
|
543
|
+
* console.log(processedOrder[0].type); // 'critical';
|
|
544
|
+
* console.log(processedOrder[1].type); // 'critical';
|
|
545
|
+
* console.log(processedOrder[2].type); // 'warning';
|
|
546
|
+
* console.log(processedOrder[3].type); // 'info';
|
|
547
|
+
* console.log(processedOrder[4].type); // 'info';
|
|
548
|
+
*
|
|
549
|
+
* // Verify O(log n) operations
|
|
550
|
+
* const newHeap = new Heap<number>([5, 3, 7, 1]);
|
|
551
|
+
*
|
|
552
|
+
* // Add - O(log n)
|
|
553
|
+
* newHeap.add(2);
|
|
554
|
+
* console.log(newHeap.size); // 5;
|
|
555
|
+
*
|
|
556
|
+
* // Poll - O(log n)
|
|
557
|
+
* const removed = newHeap.poll();
|
|
558
|
+
* console.log(removed); // 1;
|
|
559
|
+
*
|
|
560
|
+
* // Peek - O(1)
|
|
561
|
+
* const top = newHeap.peek();
|
|
562
|
+
* console.log(top); // 2;
|
|
563
|
+
*/
|
|
398
564
|
peek() {
|
|
399
565
|
return this.elements[0];
|
|
400
566
|
}
|
|
401
567
|
/**
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
568
|
+
* Check whether the heap is empty.
|
|
569
|
+
* @remarks Time O(1), Space O(1)
|
|
570
|
+
* @returns True if size is 0.
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
* @example
|
|
581
|
+
* // Check if heap is empty
|
|
582
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
583
|
+
* console.log(heap.isEmpty()); // true;
|
|
584
|
+
* heap.add(1);
|
|
585
|
+
* console.log(heap.isEmpty()); // false;
|
|
586
|
+
*/
|
|
406
587
|
isEmpty() {
|
|
407
588
|
return this.size === 0;
|
|
408
589
|
}
|
|
409
590
|
/**
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
591
|
+
* Remove all elements.
|
|
592
|
+
* @remarks Time O(1), Space O(1)
|
|
593
|
+
* @returns void
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
* @example
|
|
604
|
+
* // Remove all elements
|
|
605
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
606
|
+
* heap.clear();
|
|
607
|
+
* console.log(heap.isEmpty()); // true;
|
|
608
|
+
*/
|
|
414
609
|
clear() {
|
|
415
610
|
this._elements = [];
|
|
416
611
|
}
|
|
@@ -425,21 +620,41 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
425
620
|
return this.fix();
|
|
426
621
|
}
|
|
427
622
|
/**
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
623
|
+
* Check if an equal element exists in the heap.
|
|
624
|
+
* @remarks Time O(N), Space O(1)
|
|
625
|
+
* @param element - Element to search for.
|
|
626
|
+
* @returns True if found.
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
* @example
|
|
630
|
+
* // Check element existence
|
|
631
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
632
|
+
* console.log(heap.has(1)); // true;
|
|
633
|
+
* console.log(heap.has(99)); // false;
|
|
634
|
+
*/
|
|
433
635
|
has(element) {
|
|
434
636
|
for (const el of this.elements) if (this._equals(el, element)) return true;
|
|
435
637
|
return false;
|
|
436
638
|
}
|
|
437
639
|
/**
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
640
|
+
* Delete one occurrence of an element.
|
|
641
|
+
* @remarks Time O(N), Space O(1)
|
|
642
|
+
* @param element - Element to delete.
|
|
643
|
+
* @returns True if an element was removed.
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
* @example
|
|
653
|
+
* // Remove specific element
|
|
654
|
+
* const heap = new Heap<number>([3, 1, 4, 1, 5], { comparator: (a, b) => a - b });
|
|
655
|
+
* heap.delete(4);
|
|
656
|
+
* console.log(heap.toArray().includes(4)); // false;
|
|
657
|
+
*/
|
|
443
658
|
delete(element) {
|
|
444
659
|
let index = -1;
|
|
445
660
|
for (let i = 0; i < this.elements.length; i++) {
|
|
@@ -497,11 +712,18 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
497
712
|
return this;
|
|
498
713
|
}
|
|
499
714
|
/**
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
715
|
+
* Traverse the binary heap as a complete binary tree and collect elements.
|
|
716
|
+
* @remarks Time O(N), Space O(H)
|
|
717
|
+
* @param [order] - Traversal order: 'PRE' | 'IN' | 'POST'.
|
|
718
|
+
* @returns Array of visited elements.
|
|
719
|
+
|
|
720
|
+
|
|
721
|
+
* @example
|
|
722
|
+
* // Depth-first traversal
|
|
723
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
724
|
+
* const result = heap.dfs('IN');
|
|
725
|
+
* console.log(result.length); // 3;
|
|
726
|
+
*/
|
|
505
727
|
dfs(order = "PRE") {
|
|
506
728
|
const result = [];
|
|
507
729
|
const _dfs = /* @__PURE__ */ __name((index) => {
|
|
@@ -538,10 +760,26 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
538
760
|
return results;
|
|
539
761
|
}
|
|
540
762
|
/**
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
763
|
+
* Return all elements in ascending order by repeatedly polling.
|
|
764
|
+
* @remarks Time O(N log N), Space O(N)
|
|
765
|
+
* @returns Sorted array of elements.
|
|
766
|
+
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
* @example
|
|
778
|
+
* // Sort elements using heap
|
|
779
|
+
* const heap = new Heap<number>([5, 1, 3, 2, 4]);
|
|
780
|
+
* const sorted = heap.sort();
|
|
781
|
+
* console.log(sorted); // [1, 2, 3, 4, 5];
|
|
782
|
+
*/
|
|
545
783
|
sort() {
|
|
546
784
|
const visited = [];
|
|
547
785
|
const cloned = this._createInstance();
|
|
@@ -553,22 +791,52 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
553
791
|
return visited;
|
|
554
792
|
}
|
|
555
793
|
/**
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
794
|
+
* Deep clone this heap.
|
|
795
|
+
* @remarks Time O(N), Space O(N)
|
|
796
|
+
* @returns A new heap with the same elements.
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
* @example
|
|
807
|
+
* // Create independent copy
|
|
808
|
+
* const heap = new Heap<number>([3, 1, 4], { comparator: (a, b) => a - b });
|
|
809
|
+
* const copy = heap.clone();
|
|
810
|
+
* copy.poll();
|
|
811
|
+
* console.log(heap.size); // 3;
|
|
812
|
+
* console.log(copy.size); // 2;
|
|
813
|
+
*/
|
|
560
814
|
clone() {
|
|
561
815
|
const next = this._createInstance();
|
|
562
816
|
for (const x of this.elements) next.add(x);
|
|
563
817
|
return next;
|
|
564
818
|
}
|
|
565
819
|
/**
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
820
|
+
* Filter elements into a new heap of the same class.
|
|
821
|
+
* @remarks Time O(N log N), Space O(N)
|
|
822
|
+
* @param callback - Predicate (element, index, heap) → boolean to keep element.
|
|
823
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
824
|
+
* @returns A new heap with the kept elements.
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
* @example
|
|
835
|
+
* // Filter elements
|
|
836
|
+
* const heap = new Heap<number>([1, 2, 3, 4, 5], { comparator: (a, b) => a - b });
|
|
837
|
+
* const evens = heap.filter(x => x % 2 === 0);
|
|
838
|
+
* console.log(evens.size); // 2;
|
|
839
|
+
*/
|
|
572
840
|
filter(callback, thisArg) {
|
|
573
841
|
const out = this._createInstance();
|
|
574
842
|
let i = 0;
|
|
@@ -582,15 +850,28 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
582
850
|
return out;
|
|
583
851
|
}
|
|
584
852
|
/**
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
853
|
+
* Map elements into a new heap of possibly different element type.
|
|
854
|
+
* @remarks Time O(N log N), Space O(N)
|
|
855
|
+
* @template EM
|
|
856
|
+
* @template RM
|
|
857
|
+
* @param callback - Mapping function (element, index, heap) → newElement.
|
|
858
|
+
* @param options - Options for the output heap, including comparator for EM.
|
|
859
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
860
|
+
* @returns A new heap with mapped elements.
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
* @example
|
|
870
|
+
* // Transform elements
|
|
871
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
872
|
+
* const doubled = heap.map(x => x * 2, { comparator: (a, b) => a - b });
|
|
873
|
+
* console.log(doubled.peek()); // 2;
|
|
874
|
+
*/
|
|
594
875
|
map(callback, options, thisArg) {
|
|
595
876
|
const { comparator, toElementFn, ...rest } = options ?? {};
|
|
596
877
|
if (!comparator) throw new TypeError(ERR.comparatorRequired("Heap.map"));
|