linked-list-typed 1.53.2 → 1.53.4

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.
@@ -17,6 +17,171 @@ import { IterableElementBase } from '../base';
17
17
  * 6. Non-linear Search: While a heap allows rapid access to its largest or smallest element, it is less efficient for other operations, such as searching for a specific element, as it is not designed for these tasks.
18
18
  * 7. Efficient Sorting Algorithms: For example, heap sort. Heap sort uses the properties of a heap to sort elements.
19
19
  * 8. Graph Algorithms: Such as Dijkstra's shortest path algorithm and Prime's minimum-spanning tree algorithm, which use heaps to improve performance.
20
+ * @example
21
+ * // Use Heap to sort an array
22
+ * function heapSort(arr: number[]): number[] {
23
+ * const heap = new Heap<number>(arr, { comparator: (a, b) => a - b });
24
+ * const sorted: number[] = [];
25
+ * while (!heap.isEmpty()) {
26
+ * sorted.push(heap.poll()!); // Poll minimum element
27
+ * }
28
+ * return sorted;
29
+ * }
30
+ *
31
+ * const array = [5, 3, 8, 4, 1, 2];
32
+ * console.log(heapSort(array)); // [1, 2, 3, 4, 5, 8]
33
+ * @example
34
+ * // Use Heap to solve top k problems
35
+ * function topKElements(arr: number[], k: number): number[] {
36
+ * const heap = new Heap<number>([], { comparator: (a, b) => b - a }); // Max heap
37
+ * arr.forEach(num => {
38
+ * heap.add(num);
39
+ * if (heap.size > k) heap.poll(); // Keep the heap size at K
40
+ * });
41
+ * return heap.toArray();
42
+ * }
43
+ *
44
+ * const numbers = [10, 30, 20, 5, 15, 25];
45
+ * console.log(topKElements(numbers, 3)); // [15, 10, 5]
46
+ * @example
47
+ * // Use Heap to merge sorted sequences
48
+ * function mergeSortedSequences(sequences: number[][]): number[] {
49
+ * const heap = new Heap<{ value: number; seqIndex: number; itemIndex: number }>([], {
50
+ * comparator: (a, b) => a.value - b.value // Min heap
51
+ * });
52
+ *
53
+ * // Initialize heap
54
+ * sequences.forEach((seq, seqIndex) => {
55
+ * if (seq.length) {
56
+ * heap.add({ value: seq[0], seqIndex, itemIndex: 0 });
57
+ * }
58
+ * });
59
+ *
60
+ * const merged: number[] = [];
61
+ * while (!heap.isEmpty()) {
62
+ * const { value, seqIndex, itemIndex } = heap.poll()!;
63
+ * merged.push(value);
64
+ *
65
+ * if (itemIndex + 1 < sequences[seqIndex].length) {
66
+ * heap.add({
67
+ * value: sequences[seqIndex][itemIndex + 1],
68
+ * seqIndex,
69
+ * itemIndex: itemIndex + 1
70
+ * });
71
+ * }
72
+ * }
73
+ *
74
+ * return merged;
75
+ * }
76
+ *
77
+ * const sequences = [
78
+ * [1, 4, 7],
79
+ * [2, 5, 8],
80
+ * [3, 6, 9]
81
+ * ];
82
+ * console.log(mergeSortedSequences(sequences)); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
83
+ * @example
84
+ * // Use Heap to dynamically maintain the median
85
+ * class MedianFinder {
86
+ * private low: MaxHeap<number>; // Max heap, stores the smaller half
87
+ * private high: MinHeap<number>; // Min heap, stores the larger half
88
+ *
89
+ * constructor() {
90
+ * this.low = new MaxHeap<number>([]);
91
+ * this.high = new MinHeap<number>([]);
92
+ * }
93
+ *
94
+ * addNum(num: number): void {
95
+ * if (this.low.isEmpty() || num <= this.low.peek()!) this.low.add(num);
96
+ * else this.high.add(num);
97
+ *
98
+ * // Balance heaps
99
+ * if (this.low.size > this.high.size + 1) this.high.add(this.low.poll()!);
100
+ * else if (this.high.size > this.low.size) this.low.add(this.high.poll()!);
101
+ * }
102
+ *
103
+ * findMedian(): number {
104
+ * if (this.low.size === this.high.size) return (this.low.peek()! + this.high.peek()!) / 2;
105
+ * return this.low.peek()!;
106
+ * }
107
+ * }
108
+ *
109
+ * const medianFinder = new MedianFinder();
110
+ * medianFinder.addNum(10);
111
+ * console.log(medianFinder.findMedian()); // 10
112
+ * medianFinder.addNum(20);
113
+ * console.log(medianFinder.findMedian()); // 15
114
+ * medianFinder.addNum(30);
115
+ * console.log(medianFinder.findMedian()); // 20
116
+ * medianFinder.addNum(40);
117
+ * console.log(medianFinder.findMedian()); // 25
118
+ * medianFinder.addNum(50);
119
+ * console.log(medianFinder.findMedian()); // 30
120
+ * @example
121
+ * // Use Heap for load balancing
122
+ * function loadBalance(requests: number[], servers: number): number[] {
123
+ * const serverHeap = new Heap<{ id: number; load: number }>([], { comparator: (a, b) => a.load - b.load }); // min heap
124
+ * const serverLoads = new Array(servers).fill(0);
125
+ *
126
+ * for (let i = 0; i < servers; i++) {
127
+ * serverHeap.add({ id: i, load: 0 });
128
+ * }
129
+ *
130
+ * requests.forEach(req => {
131
+ * const server = serverHeap.poll()!;
132
+ * serverLoads[server.id] += req;
133
+ * server.load += req;
134
+ * serverHeap.add(server); // The server after updating the load is re-entered into the heap
135
+ * });
136
+ *
137
+ * return serverLoads;
138
+ * }
139
+ *
140
+ * const requests = [5, 2, 8, 3, 7];
141
+ * console.log(loadBalance(requests, 3)); // [12, 8, 5]
142
+ * @example
143
+ * // Use Heap to schedule tasks
144
+ * type Task = [string, number];
145
+ *
146
+ * function scheduleTasks(tasks: Task[], machines: number): Map<number, Task[]> {
147
+ * const machineHeap = new Heap<{ id: number; load: number }>([], { comparator: (a, b) => a.load - b.load }); // Min heap
148
+ * const allocation = new Map<number, Task[]>();
149
+ *
150
+ * // Initialize the load on each machine
151
+ * for (let i = 0; i < machines; i++) {
152
+ * machineHeap.add({ id: i, load: 0 });
153
+ * allocation.set(i, []);
154
+ * }
155
+ *
156
+ * // Assign tasks
157
+ * tasks.forEach(([task, load]) => {
158
+ * const machine = machineHeap.poll()!;
159
+ * allocation.get(machine.id)!.push([task, load]);
160
+ * machine.load += load;
161
+ * machineHeap.add(machine); // The machine after updating the load is re-entered into the heap
162
+ * });
163
+ *
164
+ * return allocation;
165
+ * }
166
+ *
167
+ * const tasks: Task[] = [
168
+ * ['Task1', 3],
169
+ * ['Task2', 1],
170
+ * ['Task3', 2],
171
+ * ['Task4', 5],
172
+ * ['Task5', 4]
173
+ * ];
174
+ * const expectedMap = new Map<number, Task[]>();
175
+ * expectedMap.set(0, [
176
+ * ['Task1', 3],
177
+ * ['Task4', 5]
178
+ * ]);
179
+ * expectedMap.set(1, [
180
+ * ['Task2', 1],
181
+ * ['Task3', 2],
182
+ * ['Task5', 4]
183
+ * ]);
184
+ * console.log(scheduleTasks(tasks, 2)); // expectedMap
20
185
  */
21
186
  export declare class Heap<E = any, R = any> extends IterableElementBase<E, R, Heap<E, R>> {
22
187
  /**
@@ -19,6 +19,171 @@ const base_1 = require("../base");
19
19
  * 6. Non-linear Search: While a heap allows rapid access to its largest or smallest element, it is less efficient for other operations, such as searching for a specific element, as it is not designed for these tasks.
20
20
  * 7. Efficient Sorting Algorithms: For example, heap sort. Heap sort uses the properties of a heap to sort elements.
21
21
  * 8. Graph Algorithms: Such as Dijkstra's shortest path algorithm and Prime's minimum-spanning tree algorithm, which use heaps to improve performance.
22
+ * @example
23
+ * // Use Heap to sort an array
24
+ * function heapSort(arr: number[]): number[] {
25
+ * const heap = new Heap<number>(arr, { comparator: (a, b) => a - b });
26
+ * const sorted: number[] = [];
27
+ * while (!heap.isEmpty()) {
28
+ * sorted.push(heap.poll()!); // Poll minimum element
29
+ * }
30
+ * return sorted;
31
+ * }
32
+ *
33
+ * const array = [5, 3, 8, 4, 1, 2];
34
+ * console.log(heapSort(array)); // [1, 2, 3, 4, 5, 8]
35
+ * @example
36
+ * // Use Heap to solve top k problems
37
+ * function topKElements(arr: number[], k: number): number[] {
38
+ * const heap = new Heap<number>([], { comparator: (a, b) => b - a }); // Max heap
39
+ * arr.forEach(num => {
40
+ * heap.add(num);
41
+ * if (heap.size > k) heap.poll(); // Keep the heap size at K
42
+ * });
43
+ * return heap.toArray();
44
+ * }
45
+ *
46
+ * const numbers = [10, 30, 20, 5, 15, 25];
47
+ * console.log(topKElements(numbers, 3)); // [15, 10, 5]
48
+ * @example
49
+ * // Use Heap to merge sorted sequences
50
+ * function mergeSortedSequences(sequences: number[][]): number[] {
51
+ * const heap = new Heap<{ value: number; seqIndex: number; itemIndex: number }>([], {
52
+ * comparator: (a, b) => a.value - b.value // Min heap
53
+ * });
54
+ *
55
+ * // Initialize heap
56
+ * sequences.forEach((seq, seqIndex) => {
57
+ * if (seq.length) {
58
+ * heap.add({ value: seq[0], seqIndex, itemIndex: 0 });
59
+ * }
60
+ * });
61
+ *
62
+ * const merged: number[] = [];
63
+ * while (!heap.isEmpty()) {
64
+ * const { value, seqIndex, itemIndex } = heap.poll()!;
65
+ * merged.push(value);
66
+ *
67
+ * if (itemIndex + 1 < sequences[seqIndex].length) {
68
+ * heap.add({
69
+ * value: sequences[seqIndex][itemIndex + 1],
70
+ * seqIndex,
71
+ * itemIndex: itemIndex + 1
72
+ * });
73
+ * }
74
+ * }
75
+ *
76
+ * return merged;
77
+ * }
78
+ *
79
+ * const sequences = [
80
+ * [1, 4, 7],
81
+ * [2, 5, 8],
82
+ * [3, 6, 9]
83
+ * ];
84
+ * console.log(mergeSortedSequences(sequences)); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
85
+ * @example
86
+ * // Use Heap to dynamically maintain the median
87
+ * class MedianFinder {
88
+ * private low: MaxHeap<number>; // Max heap, stores the smaller half
89
+ * private high: MinHeap<number>; // Min heap, stores the larger half
90
+ *
91
+ * constructor() {
92
+ * this.low = new MaxHeap<number>([]);
93
+ * this.high = new MinHeap<number>([]);
94
+ * }
95
+ *
96
+ * addNum(num: number): void {
97
+ * if (this.low.isEmpty() || num <= this.low.peek()!) this.low.add(num);
98
+ * else this.high.add(num);
99
+ *
100
+ * // Balance heaps
101
+ * if (this.low.size > this.high.size + 1) this.high.add(this.low.poll()!);
102
+ * else if (this.high.size > this.low.size) this.low.add(this.high.poll()!);
103
+ * }
104
+ *
105
+ * findMedian(): number {
106
+ * if (this.low.size === this.high.size) return (this.low.peek()! + this.high.peek()!) / 2;
107
+ * return this.low.peek()!;
108
+ * }
109
+ * }
110
+ *
111
+ * const medianFinder = new MedianFinder();
112
+ * medianFinder.addNum(10);
113
+ * console.log(medianFinder.findMedian()); // 10
114
+ * medianFinder.addNum(20);
115
+ * console.log(medianFinder.findMedian()); // 15
116
+ * medianFinder.addNum(30);
117
+ * console.log(medianFinder.findMedian()); // 20
118
+ * medianFinder.addNum(40);
119
+ * console.log(medianFinder.findMedian()); // 25
120
+ * medianFinder.addNum(50);
121
+ * console.log(medianFinder.findMedian()); // 30
122
+ * @example
123
+ * // Use Heap for load balancing
124
+ * function loadBalance(requests: number[], servers: number): number[] {
125
+ * const serverHeap = new Heap<{ id: number; load: number }>([], { comparator: (a, b) => a.load - b.load }); // min heap
126
+ * const serverLoads = new Array(servers).fill(0);
127
+ *
128
+ * for (let i = 0; i < servers; i++) {
129
+ * serverHeap.add({ id: i, load: 0 });
130
+ * }
131
+ *
132
+ * requests.forEach(req => {
133
+ * const server = serverHeap.poll()!;
134
+ * serverLoads[server.id] += req;
135
+ * server.load += req;
136
+ * serverHeap.add(server); // The server after updating the load is re-entered into the heap
137
+ * });
138
+ *
139
+ * return serverLoads;
140
+ * }
141
+ *
142
+ * const requests = [5, 2, 8, 3, 7];
143
+ * console.log(loadBalance(requests, 3)); // [12, 8, 5]
144
+ * @example
145
+ * // Use Heap to schedule tasks
146
+ * type Task = [string, number];
147
+ *
148
+ * function scheduleTasks(tasks: Task[], machines: number): Map<number, Task[]> {
149
+ * const machineHeap = new Heap<{ id: number; load: number }>([], { comparator: (a, b) => a.load - b.load }); // Min heap
150
+ * const allocation = new Map<number, Task[]>();
151
+ *
152
+ * // Initialize the load on each machine
153
+ * for (let i = 0; i < machines; i++) {
154
+ * machineHeap.add({ id: i, load: 0 });
155
+ * allocation.set(i, []);
156
+ * }
157
+ *
158
+ * // Assign tasks
159
+ * tasks.forEach(([task, load]) => {
160
+ * const machine = machineHeap.poll()!;
161
+ * allocation.get(machine.id)!.push([task, load]);
162
+ * machine.load += load;
163
+ * machineHeap.add(machine); // The machine after updating the load is re-entered into the heap
164
+ * });
165
+ *
166
+ * return allocation;
167
+ * }
168
+ *
169
+ * const tasks: Task[] = [
170
+ * ['Task1', 3],
171
+ * ['Task2', 1],
172
+ * ['Task3', 2],
173
+ * ['Task4', 5],
174
+ * ['Task5', 4]
175
+ * ];
176
+ * const expectedMap = new Map<number, Task[]>();
177
+ * expectedMap.set(0, [
178
+ * ['Task1', 3],
179
+ * ['Task4', 5]
180
+ * ]);
181
+ * expectedMap.set(1, [
182
+ * ['Task2', 1],
183
+ * ['Task3', 2],
184
+ * ['Task5', 4]
185
+ * ]);
186
+ * console.log(scheduleTasks(tasks, 2)); // expectedMap
22
187
  */
23
188
  class Heap extends base_1.IterableElementBase {
24
189
  /**