data-structure-typed 2.4.4 → 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/CHANGELOG.md +22 -1
- package/README.md +34 -1
- package/dist/cjs/index.cjs +10639 -2151
- package/dist/cjs-legacy/index.cjs +10694 -2195
- package/dist/esm/index.mjs +10639 -2150
- package/dist/esm-legacy/index.mjs +10694 -2194
- package/dist/types/common/error.d.ts +23 -0
- package/dist/types/common/index.d.ts +1 -0
- 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 +439 -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 +217 -31
- 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/abstract-graph.d.ts +44 -0
- package/dist/types/data-structures/graph/directed-graph.d.ts +220 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +218 -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 +313 -66
- 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/types/types/data-structures/queue/deque.d.ts +6 -0
- package/dist/umd/data-structure-typed.js +10725 -2221
- package/dist/umd/data-structure-typed.min.js +4 -2
- package/package.json +5 -4
- package/src/common/error.ts +60 -0
- package/src/common/index.ts +2 -0
- package/src/data-structures/base/iterable-element-base.ts +2 -2
- package/src/data-structures/binary-tree/avl-tree.ts +146 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +317 -247
- package/src/data-structures/binary-tree/binary-tree.ts +567 -121
- package/src/data-structures/binary-tree/bst.ts +370 -37
- package/src/data-structures/binary-tree/red-black-tree.ts +328 -96
- package/src/data-structures/binary-tree/segment-tree.ts +378 -248
- package/src/data-structures/binary-tree/tree-map.ts +1411 -13
- package/src/data-structures/binary-tree/tree-multi-map.ts +1218 -215
- package/src/data-structures/binary-tree/tree-multi-set.ts +959 -69
- package/src/data-structures/binary-tree/tree-set.ts +1257 -15
- package/src/data-structures/graph/abstract-graph.ts +106 -1
- package/src/data-structures/graph/directed-graph.ts +233 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +308 -59
- package/src/data-structures/hash/hash-map.ts +254 -79
- package/src/data-structures/heap/heap.ts +305 -102
- package/src/data-structures/heap/max-heap.ts +48 -3
- package/src/data-structures/heap/min-heap.ts +59 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +303 -44
- package/src/data-structures/linked-list/singly-linked-list.ts +293 -65
- package/src/data-structures/linked-list/skip-linked-list.ts +707 -90
- package/src/data-structures/matrix/matrix.ts +433 -22
- package/src/data-structures/priority-queue/max-priority-queue.ts +59 -3
- 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 +358 -68
- package/src/data-structures/queue/queue.ts +223 -42
- package/src/data-structures/stack/stack.ts +184 -32
- package/src/data-structures/trie/trie.ts +227 -44
- 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/src/types/data-structures/queue/deque.ts +7 -0
- package/src/utils/utils.ts +4 -2
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import type { Comparator, DFSOrderPattern, ElementCallback, HeapOptions } from '../../types';
|
|
10
10
|
import { IterableElementBase } from '../base';
|
|
11
|
+
import { ERR } from '../../common';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Binary heap with pluggable comparator; supports fast insertion and removal of the top element.
|
|
@@ -25,105 +26,6 @@ import { IterableElementBase } from '../base';
|
|
|
25
26
|
* 7. Efficient Sorting Algorithms: For example, heap sort. Heap sort uses the properties of a heap to sort elements.
|
|
26
27
|
* 8. Graph Algorithms: Such as Dijkstra's shortest path algorithm and Prime's minimum-spanning tree algorithm, which use heaps to improve performance.
|
|
27
28
|
* @example
|
|
28
|
-
* // basic Heap creation and add operation
|
|
29
|
-
* // Create a min heap (default)
|
|
30
|
-
* const minHeap = new Heap([5, 3, 7, 1, 9, 2]);
|
|
31
|
-
*
|
|
32
|
-
* // Verify size
|
|
33
|
-
* console.log(minHeap.size); // 6;
|
|
34
|
-
*
|
|
35
|
-
* // Add new element
|
|
36
|
-
* minHeap.add(4);
|
|
37
|
-
* console.log(minHeap.size); // 7;
|
|
38
|
-
*
|
|
39
|
-
* // Min heap property: smallest element at root
|
|
40
|
-
* const min = minHeap.peek();
|
|
41
|
-
* console.log(min); // 1;
|
|
42
|
-
* @example
|
|
43
|
-
* // Heap with custom comparator (MaxHeap behavior)
|
|
44
|
-
* interface Task {
|
|
45
|
-
* id: number;
|
|
46
|
-
* priority: number;
|
|
47
|
-
* name: string;
|
|
48
|
-
* }
|
|
49
|
-
*
|
|
50
|
-
* // Custom comparator for max heap behavior (higher priority first)
|
|
51
|
-
* const tasks: Task[] = [
|
|
52
|
-
* { id: 1, priority: 5, name: 'Email' },
|
|
53
|
-
* { id: 2, priority: 3, name: 'Chat' },
|
|
54
|
-
* { id: 3, priority: 8, name: 'Alert' }
|
|
55
|
-
* ];
|
|
56
|
-
*
|
|
57
|
-
* const maxHeap = new Heap(tasks, {
|
|
58
|
-
* comparator: (a: Task, b: Task) => b.priority - a.priority
|
|
59
|
-
* });
|
|
60
|
-
*
|
|
61
|
-
* console.log(maxHeap.size); // 3;
|
|
62
|
-
*
|
|
63
|
-
* // Peek returns highest priority task
|
|
64
|
-
* const topTask = maxHeap.peek();
|
|
65
|
-
* console.log(topTask?.priority); // 8;
|
|
66
|
-
* console.log(topTask?.name); // 'Alert';
|
|
67
|
-
* @example
|
|
68
|
-
* // Heap for event processing with priority
|
|
69
|
-
* interface Event {
|
|
70
|
-
* id: number;
|
|
71
|
-
* type: 'critical' | 'warning' | 'info';
|
|
72
|
-
* timestamp: number;
|
|
73
|
-
* message: string;
|
|
74
|
-
* }
|
|
75
|
-
*
|
|
76
|
-
* // Custom priority: critical > warning > info
|
|
77
|
-
* const priorityMap = { critical: 3, warning: 2, info: 1 };
|
|
78
|
-
*
|
|
79
|
-
* const eventHeap = new Heap<Event>([], {
|
|
80
|
-
* comparator: (a: Event, b: Event) => {
|
|
81
|
-
* const priorityA = priorityMap[a.type];
|
|
82
|
-
* const priorityB = priorityMap[b.type];
|
|
83
|
-
* return priorityB - priorityA; // Higher priority first
|
|
84
|
-
* }
|
|
85
|
-
* });
|
|
86
|
-
*
|
|
87
|
-
* // Add events in random order
|
|
88
|
-
* eventHeap.add({ id: 1, type: 'info', timestamp: 100, message: 'User logged in' });
|
|
89
|
-
* eventHeap.add({ id: 2, type: 'critical', timestamp: 101, message: 'Server down' });
|
|
90
|
-
* eventHeap.add({ id: 3, type: 'warning', timestamp: 102, message: 'High memory' });
|
|
91
|
-
* eventHeap.add({ id: 4, type: 'info', timestamp: 103, message: 'Cache cleared' });
|
|
92
|
-
* eventHeap.add({ id: 5, type: 'critical', timestamp: 104, message: 'Database error' });
|
|
93
|
-
*
|
|
94
|
-
* console.log(eventHeap.size); // 5;
|
|
95
|
-
*
|
|
96
|
-
* // Process events by priority (critical first)
|
|
97
|
-
* const processedOrder: Event[] = [];
|
|
98
|
-
* while (eventHeap.size > 0) {
|
|
99
|
-
* const event = eventHeap.poll();
|
|
100
|
-
* if (event) {
|
|
101
|
-
* processedOrder.push(event);
|
|
102
|
-
* }
|
|
103
|
-
* }
|
|
104
|
-
*
|
|
105
|
-
* // Verify critical events came first
|
|
106
|
-
* console.log(processedOrder[0].type); // 'critical';
|
|
107
|
-
* console.log(processedOrder[1].type); // 'critical';
|
|
108
|
-
* console.log(processedOrder[2].type); // 'warning';
|
|
109
|
-
* console.log(processedOrder[3].type); // 'info';
|
|
110
|
-
* console.log(processedOrder[4].type); // 'info';
|
|
111
|
-
*
|
|
112
|
-
* // Verify O(log n) operations
|
|
113
|
-
* const newHeap = new Heap<number>([5, 3, 7, 1]);
|
|
114
|
-
*
|
|
115
|
-
* // Add - O(log n)
|
|
116
|
-
* newHeap.add(2);
|
|
117
|
-
* console.log(newHeap.size); // 5;
|
|
118
|
-
*
|
|
119
|
-
* // Poll - O(log n)
|
|
120
|
-
* const removed = newHeap.poll();
|
|
121
|
-
* console.log(removed); // 1;
|
|
122
|
-
*
|
|
123
|
-
* // Peek - O(1)
|
|
124
|
-
* const top = newHeap.peek();
|
|
125
|
-
* console.log(top); // 2;
|
|
126
|
-
* @example
|
|
127
29
|
* // Use Heap to solve top k problems
|
|
128
30
|
* function topKElements(arr: number[], k: number): number[] {
|
|
129
31
|
* const heap = new Heap<number>([], { comparator: (a, b) => b - a }); // Max heap
|
|
@@ -238,6 +140,12 @@ import { IterableElementBase } from '../base';
|
|
|
238
140
|
* ['Task5', 4]
|
|
239
141
|
* ]);
|
|
240
142
|
* console.log(scheduleTasks(tasks, 2)); // expectedMap;
|
|
143
|
+
* @example
|
|
144
|
+
* // Get all elements as array
|
|
145
|
+
* const heap = new Heap<number>([5, 1, 3, 2, 4]);
|
|
146
|
+
* const arr = heap.toArray();
|
|
147
|
+
* console.log(arr.length); // 5;
|
|
148
|
+
* console.log(arr.sort()); // [1, 2, 3, 4, 5];
|
|
241
149
|
*/
|
|
242
150
|
export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
243
151
|
protected _equals: (a: E, b: E) => boolean = Object.is;
|
|
@@ -277,6 +185,27 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
|
277
185
|
* Get the number of elements.
|
|
278
186
|
* @remarks Time O(1), Space O(1)
|
|
279
187
|
* @returns Heap size.
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
* @example
|
|
201
|
+
* // Track heap capacity
|
|
202
|
+
* const heap = new Heap<number>();
|
|
203
|
+
* console.log(heap.size); // 0;
|
|
204
|
+
* heap.add(10);
|
|
205
|
+
* heap.add(20);
|
|
206
|
+
* console.log(heap.size); // 2;
|
|
207
|
+
* heap.poll();
|
|
208
|
+
* console.log(heap.size); // 1;
|
|
280
209
|
*/
|
|
281
210
|
|
|
282
211
|
get size(): number {
|
|
@@ -331,6 +260,33 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
|
331
260
|
* @remarks Time O(1) amortized, Space O(1)
|
|
332
261
|
* @param element - Element to insert.
|
|
333
262
|
* @returns True.
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
* @example
|
|
276
|
+
* // basic Heap creation and add operation
|
|
277
|
+
* // Create a min heap (default)
|
|
278
|
+
* const minHeap = new Heap([5, 3, 7, 1, 9, 2]);
|
|
279
|
+
*
|
|
280
|
+
* // Verify size
|
|
281
|
+
* console.log(minHeap.size); // 6;
|
|
282
|
+
*
|
|
283
|
+
* // Add new element
|
|
284
|
+
* minHeap.add(4);
|
|
285
|
+
* console.log(minHeap.size); // 7;
|
|
286
|
+
*
|
|
287
|
+
* // Min heap property: smallest element at root
|
|
288
|
+
* const min = minHeap.peek();
|
|
289
|
+
* console.log(min); // 1;
|
|
334
290
|
*/
|
|
335
291
|
|
|
336
292
|
add(element: E): boolean {
|
|
@@ -343,6 +299,21 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
|
343
299
|
* @remarks Time O(N log N), Space O(1)
|
|
344
300
|
* @param elements - Iterable of elements or raw values.
|
|
345
301
|
* @returns Array of per-element success flags.
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
* @example
|
|
312
|
+
* // Add multiple elements
|
|
313
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
314
|
+
* heap.addMany([5, 3, 7, 1]);
|
|
315
|
+
* console.log(heap.peek()); // 1;
|
|
316
|
+
* console.log(heap.size); // 4;
|
|
346
317
|
*/
|
|
347
318
|
|
|
348
319
|
addMany(elements: Iterable<E | R>): boolean[] {
|
|
@@ -363,6 +334,43 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
|
363
334
|
* Remove and return the top element.
|
|
364
335
|
* @remarks Time O(log N), Space O(1)
|
|
365
336
|
* @returns Top element or undefined.
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
* @example
|
|
350
|
+
* // Heap with custom comparator (MaxHeap behavior)
|
|
351
|
+
* interface Task {
|
|
352
|
+
* id: number;
|
|
353
|
+
* priority: number;
|
|
354
|
+
* name: string;
|
|
355
|
+
* }
|
|
356
|
+
*
|
|
357
|
+
* // Custom comparator for max heap behavior (higher priority first)
|
|
358
|
+
* const tasks: Task[] = [
|
|
359
|
+
* { id: 1, priority: 5, name: 'Email' },
|
|
360
|
+
* { id: 2, priority: 3, name: 'Chat' },
|
|
361
|
+
* { id: 3, priority: 8, name: 'Alert' }
|
|
362
|
+
* ];
|
|
363
|
+
*
|
|
364
|
+
* const maxHeap = new Heap(tasks, {
|
|
365
|
+
* comparator: (a: Task, b: Task) => b.priority - a.priority
|
|
366
|
+
* });
|
|
367
|
+
*
|
|
368
|
+
* console.log(maxHeap.size); // 3;
|
|
369
|
+
*
|
|
370
|
+
* // Peek returns highest priority task
|
|
371
|
+
* const topTask = maxHeap.peek();
|
|
372
|
+
* console.log(topTask?.priority); // 8;
|
|
373
|
+
* console.log(topTask?.name); // 'Alert';
|
|
366
374
|
*/
|
|
367
375
|
|
|
368
376
|
poll(): E | undefined {
|
|
@@ -380,6 +388,77 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
|
380
388
|
* Get the current top element without removing it.
|
|
381
389
|
* @remarks Time O(1), Space O(1)
|
|
382
390
|
* @returns Top element or undefined.
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
* @example
|
|
404
|
+
* // Heap for event processing with priority
|
|
405
|
+
* interface Event {
|
|
406
|
+
* id: number;
|
|
407
|
+
* type: 'critical' | 'warning' | 'info';
|
|
408
|
+
* timestamp: number;
|
|
409
|
+
* message: string;
|
|
410
|
+
* }
|
|
411
|
+
*
|
|
412
|
+
* // Custom priority: critical > warning > info
|
|
413
|
+
* const priorityMap = { critical: 3, warning: 2, info: 1 };
|
|
414
|
+
*
|
|
415
|
+
* const eventHeap = new Heap<Event>([], {
|
|
416
|
+
* comparator: (a: Event, b: Event) => {
|
|
417
|
+
* const priorityA = priorityMap[a.type];
|
|
418
|
+
* const priorityB = priorityMap[b.type];
|
|
419
|
+
* return priorityB - priorityA; // Higher priority first
|
|
420
|
+
* }
|
|
421
|
+
* });
|
|
422
|
+
*
|
|
423
|
+
* // Add events in random order
|
|
424
|
+
* eventHeap.add({ id: 1, type: 'info', timestamp: 100, message: 'User logged in' });
|
|
425
|
+
* eventHeap.add({ id: 2, type: 'critical', timestamp: 101, message: 'Server down' });
|
|
426
|
+
* eventHeap.add({ id: 3, type: 'warning', timestamp: 102, message: 'High memory' });
|
|
427
|
+
* eventHeap.add({ id: 4, type: 'info', timestamp: 103, message: 'Cache cleared' });
|
|
428
|
+
* eventHeap.add({ id: 5, type: 'critical', timestamp: 104, message: 'Database error' });
|
|
429
|
+
*
|
|
430
|
+
* console.log(eventHeap.size); // 5;
|
|
431
|
+
*
|
|
432
|
+
* // Process events by priority (critical first)
|
|
433
|
+
* const processedOrder: Event[] = [];
|
|
434
|
+
* while (eventHeap.size > 0) {
|
|
435
|
+
* const event = eventHeap.poll();
|
|
436
|
+
* if (event) {
|
|
437
|
+
* processedOrder.push(event);
|
|
438
|
+
* }
|
|
439
|
+
* }
|
|
440
|
+
*
|
|
441
|
+
* // Verify critical events came first
|
|
442
|
+
* console.log(processedOrder[0].type); // 'critical';
|
|
443
|
+
* console.log(processedOrder[1].type); // 'critical';
|
|
444
|
+
* console.log(processedOrder[2].type); // 'warning';
|
|
445
|
+
* console.log(processedOrder[3].type); // 'info';
|
|
446
|
+
* console.log(processedOrder[4].type); // 'info';
|
|
447
|
+
*
|
|
448
|
+
* // Verify O(log n) operations
|
|
449
|
+
* const newHeap = new Heap<number>([5, 3, 7, 1]);
|
|
450
|
+
*
|
|
451
|
+
* // Add - O(log n)
|
|
452
|
+
* newHeap.add(2);
|
|
453
|
+
* console.log(newHeap.size); // 5;
|
|
454
|
+
*
|
|
455
|
+
* // Poll - O(log n)
|
|
456
|
+
* const removed = newHeap.poll();
|
|
457
|
+
* console.log(removed); // 1;
|
|
458
|
+
*
|
|
459
|
+
* // Peek - O(1)
|
|
460
|
+
* const top = newHeap.peek();
|
|
461
|
+
* console.log(top); // 2;
|
|
383
462
|
*/
|
|
384
463
|
|
|
385
464
|
peek(): E | undefined {
|
|
@@ -390,6 +469,22 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
|
390
469
|
* Check whether the heap is empty.
|
|
391
470
|
* @remarks Time O(1), Space O(1)
|
|
392
471
|
* @returns True if size is 0.
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
* @example
|
|
483
|
+
* // Check if heap is empty
|
|
484
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
485
|
+
* console.log(heap.isEmpty()); // true;
|
|
486
|
+
* heap.add(1);
|
|
487
|
+
* console.log(heap.isEmpty()); // false;
|
|
393
488
|
*/
|
|
394
489
|
|
|
395
490
|
isEmpty(): boolean {
|
|
@@ -400,6 +495,21 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
|
400
495
|
* Remove all elements.
|
|
401
496
|
* @remarks Time O(1), Space O(1)
|
|
402
497
|
* @returns void
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
* @example
|
|
509
|
+
* // Remove all elements
|
|
510
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
511
|
+
* heap.clear();
|
|
512
|
+
* console.log(heap.isEmpty()); // true;
|
|
403
513
|
*/
|
|
404
514
|
|
|
405
515
|
clear(): void {
|
|
@@ -423,6 +533,14 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
|
423
533
|
* @remarks Time O(N), Space O(1)
|
|
424
534
|
* @param element - Element to search for.
|
|
425
535
|
* @returns True if found.
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
* @example
|
|
540
|
+
* // Check element existence
|
|
541
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
542
|
+
* console.log(heap.has(1)); // true;
|
|
543
|
+
* console.log(heap.has(99)); // false;
|
|
426
544
|
*/
|
|
427
545
|
|
|
428
546
|
override has(element: E): boolean {
|
|
@@ -435,6 +553,20 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
|
435
553
|
* @remarks Time O(N), Space O(1)
|
|
436
554
|
* @param element - Element to delete.
|
|
437
555
|
* @returns True if an element was removed.
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
* @example
|
|
566
|
+
* // Remove specific element
|
|
567
|
+
* const heap = new Heap<number>([3, 1, 4, 1, 5], { comparator: (a, b) => a - b });
|
|
568
|
+
* heap.delete(4);
|
|
569
|
+
* console.log(heap.toArray().includes(4)); // false;
|
|
438
570
|
*/
|
|
439
571
|
|
|
440
572
|
delete(element: E): boolean {
|
|
@@ -503,6 +635,14 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
|
503
635
|
* @remarks Time O(N), Space O(H)
|
|
504
636
|
* @param [order] - Traversal order: 'PRE' | 'IN' | 'POST'.
|
|
505
637
|
* @returns Array of visited elements.
|
|
638
|
+
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
* @example
|
|
642
|
+
* // Depth-first traversal
|
|
643
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
644
|
+
* const result = heap.dfs('IN');
|
|
645
|
+
* console.log(result.length); // 3;
|
|
506
646
|
*/
|
|
507
647
|
|
|
508
648
|
dfs(order: DFSOrderPattern = 'PRE'): E[] {
|
|
@@ -548,6 +688,23 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
|
548
688
|
* Return all elements in ascending order by repeatedly polling.
|
|
549
689
|
* @remarks Time O(N log N), Space O(N)
|
|
550
690
|
* @returns Sorted array of elements.
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
* @example
|
|
704
|
+
* // Sort elements using heap
|
|
705
|
+
* const heap = new Heap<number>([5, 1, 3, 2, 4]);
|
|
706
|
+
* const sorted = heap.sort();
|
|
707
|
+
* console.log(sorted); // [1, 2, 3, 4, 5];
|
|
551
708
|
*/
|
|
552
709
|
|
|
553
710
|
sort(): E[] {
|
|
@@ -565,6 +722,23 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
|
565
722
|
* Deep clone this heap.
|
|
566
723
|
* @remarks Time O(N), Space O(N)
|
|
567
724
|
* @returns A new heap with the same elements.
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
* @example
|
|
736
|
+
* // Create independent copy
|
|
737
|
+
* const heap = new Heap<number>([3, 1, 4], { comparator: (a, b) => a - b });
|
|
738
|
+
* const copy = heap.clone();
|
|
739
|
+
* copy.poll();
|
|
740
|
+
* console.log(heap.size); // 3;
|
|
741
|
+
* console.log(copy.size); // 2;
|
|
568
742
|
*/
|
|
569
743
|
|
|
570
744
|
clone(): this {
|
|
@@ -579,6 +753,21 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
|
579
753
|
* @param callback - Predicate (element, index, heap) → boolean to keep element.
|
|
580
754
|
* @param [thisArg] - Value for `this` inside the callback.
|
|
581
755
|
* @returns A new heap with the kept elements.
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
* @example
|
|
767
|
+
* // Filter elements
|
|
768
|
+
* const heap = new Heap<number>([1, 2, 3, 4, 5], { comparator: (a, b) => a - b });
|
|
769
|
+
* const evens = heap.filter(x => x % 2 === 0);
|
|
770
|
+
* console.log(evens.size); // 2;
|
|
582
771
|
*/
|
|
583
772
|
|
|
584
773
|
filter(callback: ElementCallback<E, R, boolean>, thisArg?: unknown): this {
|
|
@@ -603,6 +792,20 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
|
603
792
|
* @param options - Options for the output heap, including comparator for EM.
|
|
604
793
|
* @param [thisArg] - Value for `this` inside the callback.
|
|
605
794
|
* @returns A new heap with mapped elements.
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
|
|
804
|
+
* @example
|
|
805
|
+
* // Transform elements
|
|
806
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
807
|
+
* const doubled = heap.map(x => x * 2, { comparator: (a, b) => a - b });
|
|
808
|
+
* console.log(doubled.peek()); // 2;
|
|
606
809
|
*/
|
|
607
810
|
|
|
608
811
|
map<EM, RM>(
|
|
@@ -611,7 +814,7 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
|
611
814
|
thisArg?: unknown
|
|
612
815
|
): Heap<EM, RM> {
|
|
613
816
|
const { comparator, toElementFn, ...rest } = options ?? {};
|
|
614
|
-
if (!comparator) throw new TypeError('Heap.map
|
|
817
|
+
if (!comparator) throw new TypeError(ERR.comparatorRequired('Heap.map'));
|
|
615
818
|
const out = this._createLike<EM, RM>([], { ...rest, comparator, toElementFn });
|
|
616
819
|
let i = 0;
|
|
617
820
|
for (const x of this) {
|
|
@@ -641,7 +844,7 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
|
641
844
|
|
|
642
845
|
protected readonly _DEFAULT_COMPARATOR: Comparator<E> = (a: E, b: E): number => {
|
|
643
846
|
if (typeof a === 'object' || typeof b === 'object') {
|
|
644
|
-
throw TypeError(
|
|
847
|
+
throw new TypeError(ERR.comparatorRequired('Heap'));
|
|
645
848
|
}
|
|
646
849
|
if (a > b) return 1;
|
|
647
850
|
if (a < b) return -1;
|
|
@@ -783,7 +986,7 @@ export class FibonacciHeap<E> {
|
|
|
783
986
|
constructor(comparator?: Comparator<E>) {
|
|
784
987
|
this.clear();
|
|
785
988
|
this._comparator = comparator || this._defaultComparator;
|
|
786
|
-
if (typeof this.comparator !== 'function') throw new
|
|
989
|
+
if (typeof this.comparator !== 'function') throw new TypeError(ERR.notAFunction('comparator', 'FibonacciHeap'));
|
|
787
990
|
}
|
|
788
991
|
|
|
789
992
|
protected _root?: FibonacciHeapNode<E>;
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { HeapOptions } from '../../types';
|
|
8
8
|
import { Heap } from './heap';
|
|
9
|
+
import { ERR } from '../../common';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* @template E
|
|
@@ -22,6 +23,52 @@ import { Heap } from './heap';
|
|
|
22
23
|
* 7. Efficient Sorting Algorithms: For example, heap sort. Heap sort uses the properties of a heap to sort elements.
|
|
23
24
|
* 8. Graph Algorithms: Such as Dijkstra's shortest path algorithm and Prim's minimum-spanning tree algorithm, which use heaps to improve performance.
|
|
24
25
|
* @example
|
|
26
|
+
* // Find the K largest elements
|
|
27
|
+
* const data = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5];
|
|
28
|
+
* const heap = new MaxHeap(data);
|
|
29
|
+
*
|
|
30
|
+
* // Extract top 3 elements
|
|
31
|
+
* const top3 = [];
|
|
32
|
+
* for (let i = 0; i < 3; i++) {
|
|
33
|
+
* top3.push(heap.poll());
|
|
34
|
+
* }
|
|
35
|
+
* console.log(top3); // [9, 6, 5];
|
|
36
|
+
* @example
|
|
37
|
+
* // Priority-based task processing
|
|
38
|
+
* interface Task {
|
|
39
|
+
* name: string;
|
|
40
|
+
* priority: number;
|
|
41
|
+
* }
|
|
42
|
+
*
|
|
43
|
+
* const heap = new MaxHeap<Task>([], {
|
|
44
|
+
* comparator: (a, b) => b.priority - a.priority
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* heap.add({ name: 'Low priority', priority: 1 });
|
|
48
|
+
* heap.add({ name: 'Critical fix', priority: 10 });
|
|
49
|
+
* heap.add({ name: 'Medium task', priority: 5 });
|
|
50
|
+
*
|
|
51
|
+
* // Highest priority first
|
|
52
|
+
* console.log(heap.poll()?.name); // 'Critical fix';
|
|
53
|
+
* console.log(heap.poll()?.name); // 'Medium task';
|
|
54
|
+
* console.log(heap.poll()?.name); // 'Low priority';
|
|
55
|
+
* @example
|
|
56
|
+
* // Real-time top score tracking
|
|
57
|
+
* const scores = new MaxHeap<number>();
|
|
58
|
+
*
|
|
59
|
+
* // Stream of scores coming in
|
|
60
|
+
* for (const score of [72, 85, 91, 68, 95, 78, 88]) {
|
|
61
|
+
* scores.add(score);
|
|
62
|
+
* }
|
|
63
|
+
*
|
|
64
|
+
* // Current highest score without removing
|
|
65
|
+
* console.log(scores.peek()); // 95;
|
|
66
|
+
* console.log(scores.size); // 7;
|
|
67
|
+
*
|
|
68
|
+
* // Remove top 2 scores
|
|
69
|
+
* console.log(scores.poll()); // 95;
|
|
70
|
+
* console.log(scores.poll()); // 91;
|
|
71
|
+
* console.log(scores.peek()); // 88;
|
|
25
72
|
*/
|
|
26
73
|
export class MaxHeap<E = any, R = any> extends Heap<E, R> {
|
|
27
74
|
/**
|
|
@@ -33,9 +80,7 @@ export class MaxHeap<E = any, R = any> extends Heap<E, R> {
|
|
|
33
80
|
super(elements, {
|
|
34
81
|
comparator: (a: E, b: E): number => {
|
|
35
82
|
if (typeof a === 'object' || typeof b === 'object') {
|
|
36
|
-
throw TypeError(
|
|
37
|
-
`When comparing object types, a custom comparator must be defined in the constructor's options parameter.`
|
|
38
|
-
);
|
|
83
|
+
throw new TypeError(ERR.comparatorRequired('MaxHeap'));
|
|
39
84
|
}
|
|
40
85
|
if (a < b) return 1;
|
|
41
86
|
if (a > b) return -1;
|
|
@@ -23,6 +23,65 @@ import { Heap } from './heap';
|
|
|
23
23
|
* 7. Efficient Sorting Algorithms: For example, heap sort. MinHeap sort uses the properties of a heap to sort elements.
|
|
24
24
|
* 8. Graph Algorithms: Such as Dijkstra's shortest path algorithm and Prim's minimum spanning tree algorithm, which use heaps to improve performance.
|
|
25
25
|
* @example
|
|
26
|
+
* // Merge K sorted arrays
|
|
27
|
+
* const arrays = [
|
|
28
|
+
* [1, 4, 7],
|
|
29
|
+
* [2, 5, 8],
|
|
30
|
+
* [3, 6, 9]
|
|
31
|
+
* ];
|
|
32
|
+
*
|
|
33
|
+
* // Use min heap to merge: track (value, arrayIndex, elementIndex)
|
|
34
|
+
* const heap = new MinHeap<[number, number, number]>([], {
|
|
35
|
+
* comparator: (a, b) => a[0] - b[0]
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* // Initialize with first element of each array
|
|
39
|
+
* arrays.forEach((arr, i) => heap.add([arr[0], i, 0]));
|
|
40
|
+
*
|
|
41
|
+
* const merged: number[] = [];
|
|
42
|
+
* while (heap.size > 0) {
|
|
43
|
+
* const [val, arrIdx, elemIdx] = heap.poll()!;
|
|
44
|
+
* merged.push(val);
|
|
45
|
+
* if (elemIdx + 1 < arrays[arrIdx].length) {
|
|
46
|
+
* heap.add([arrays[arrIdx][elemIdx + 1], arrIdx, elemIdx + 1]);
|
|
47
|
+
* }
|
|
48
|
+
* }
|
|
49
|
+
*
|
|
50
|
+
* console.log(merged); // [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
51
|
+
* @example
|
|
52
|
+
* // Dijkstra-style shortest distance tracking
|
|
53
|
+
* // Simulating distance updates: (distance, nodeId)
|
|
54
|
+
* const heap = new MinHeap<[number, string]>([], {
|
|
55
|
+
* comparator: (a, b) => a[0] - b[0]
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* heap.add([0, 'start']);
|
|
59
|
+
* heap.add([10, 'A']);
|
|
60
|
+
* heap.add([5, 'B']);
|
|
61
|
+
* heap.add([3, 'C']);
|
|
62
|
+
*
|
|
63
|
+
* // Process nearest node first
|
|
64
|
+
* console.log(heap.poll()); // [0, 'start'];
|
|
65
|
+
* console.log(heap.poll()); // [3, 'C'];
|
|
66
|
+
* console.log(heap.poll()); // [5, 'B'];
|
|
67
|
+
* console.log(heap.poll()); // [10, 'A'];
|
|
68
|
+
* @example
|
|
69
|
+
* // Running median with min heap (upper half)
|
|
70
|
+
* const upperHalf = new MinHeap<number>();
|
|
71
|
+
*
|
|
72
|
+
* // Add larger numbers to min heap
|
|
73
|
+
* for (const n of [5, 8, 3, 9, 1]) {
|
|
74
|
+
* upperHalf.add(n);
|
|
75
|
+
* }
|
|
76
|
+
*
|
|
77
|
+
* // Smallest of the upper half is always accessible
|
|
78
|
+
* console.log(upperHalf.peek()); // 1;
|
|
79
|
+
* console.log(upperHalf.size); // 5;
|
|
80
|
+
*
|
|
81
|
+
* // Remove smallest repeatedly
|
|
82
|
+
* console.log(upperHalf.poll()); // 1;
|
|
83
|
+
* console.log(upperHalf.poll()); // 3;
|
|
84
|
+
* console.log(upperHalf.peek()); // 5;
|
|
26
85
|
*/
|
|
27
86
|
export class MinHeap<E = any, R = any> extends Heap<E, R> {
|
|
28
87
|
/**
|