heap-typed 1.38.0 → 1.38.1

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.
Files changed (38) hide show
  1. package/dist/data-structures/binary-tree/avl-tree.d.ts +9 -9
  2. package/dist/data-structures/binary-tree/avl-tree.js +22 -22
  3. package/dist/data-structures/binary-tree/binary-tree.d.ts +31 -31
  4. package/dist/data-structures/binary-tree/binary-tree.js +32 -32
  5. package/dist/data-structures/binary-tree/rb-tree.d.ts +1 -1
  6. package/dist/data-structures/binary-tree/tree-multiset.d.ts +9 -9
  7. package/dist/data-structures/binary-tree/tree-multiset.js +23 -23
  8. package/dist/data-structures/hash/hash-map.d.ts +25 -25
  9. package/dist/data-structures/hash/hash-map.js +59 -59
  10. package/dist/data-structures/hash/hash-table.d.ts +34 -34
  11. package/dist/data-structures/hash/hash-table.js +99 -99
  12. package/dist/data-structures/heap/heap.d.ts +66 -66
  13. package/dist/data-structures/heap/heap.js +167 -167
  14. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +1 -1
  15. package/dist/data-structures/linked-list/doubly-linked-list.js +3 -3
  16. package/dist/data-structures/linked-list/skip-linked-list.d.ts +17 -17
  17. package/dist/data-structures/linked-list/skip-linked-list.js +34 -34
  18. package/dist/data-structures/matrix/matrix2d.d.ts +7 -7
  19. package/dist/data-structures/matrix/matrix2d.js +9 -9
  20. package/dist/data-structures/trie/trie.d.ts +2 -2
  21. package/dist/data-structures/trie/trie.js +6 -6
  22. package/dist/index.d.ts +3 -3
  23. package/dist/index.js +3 -3
  24. package/package.json +1 -4
  25. package/src/data-structures/binary-tree/avl-tree.ts +27 -27
  26. package/src/data-structures/binary-tree/binary-tree.ts +55 -55
  27. package/src/data-structures/binary-tree/bst.ts +4 -0
  28. package/src/data-structures/binary-tree/rb-tree.ts +2 -2
  29. package/src/data-structures/binary-tree/tree-multiset.ts +29 -29
  30. package/src/data-structures/hash/hash-map.ts +81 -75
  31. package/src/data-structures/hash/hash-table.ts +112 -109
  32. package/src/data-structures/heap/heap.ts +182 -181
  33. package/src/data-structures/linked-list/doubly-linked-list.ts +4 -4
  34. package/src/data-structures/linked-list/skip-linked-list.ts +45 -38
  35. package/src/data-structures/matrix/matrix2d.ts +10 -10
  36. package/src/data-structures/trie/trie.ts +9 -9
  37. package/src/index.ts +3 -3
  38. package/src/types/helpers.ts +5 -1
@@ -21,21 +21,17 @@ export class HashTableNode<K, V> {
21
21
  import {HashFunction} from '../../types';
22
22
 
23
23
  export class HashTable<K, V> {
24
- get hashFn(): HashFunction<K> {
25
- return this._hashFn;
26
- }
27
-
28
- set hashFn(value: HashFunction<K>) {
29
- this._hashFn = value;
30
- }
24
+ private static readonly DEFAULT_CAPACITY = 16;
25
+ private static readonly LOAD_FACTOR = 0.75;
31
26
 
32
- get buckets(): Array<HashTableNode<K, V> | null> {
33
- return this._buckets;
27
+ constructor(capacity: number = HashTable.DEFAULT_CAPACITY, hashFn?: HashFunction<K>) {
28
+ this._hashFn = hashFn || this._defaultHashFn;
29
+ this._capacity = Math.max(capacity, HashTable.DEFAULT_CAPACITY);
30
+ this._size = 0;
31
+ this._buckets = new Array<HashTableNode<K, V> | null>(this._capacity).fill(null);
34
32
  }
35
33
 
36
- set buckets(value: Array<HashTableNode<K, V> | null>) {
37
- this._buckets = value;
38
- }
34
+ private _capacity: number;
39
35
 
40
36
  get capacity(): number {
41
37
  return this._capacity;
@@ -45,111 +41,30 @@ export class HashTable<K, V> {
45
41
  this._capacity = value;
46
42
  }
47
43
 
48
- private static readonly DEFAULT_CAPACITY = 16;
49
- private static readonly LOAD_FACTOR = 0.75;
50
-
51
- private _capacity: number;
52
44
  private _size: number;
53
- private _buckets: Array<HashTableNode<K, V> | null>;
54
- private _hashFn: HashFunction<K>;
55
45
 
56
- constructor(capacity: number = HashTable.DEFAULT_CAPACITY, hashFn?: HashFunction<K>) {
57
- this._hashFn = hashFn || this._defaultHashFn;
58
- this._capacity = Math.max(capacity, HashTable.DEFAULT_CAPACITY);
59
- this._size = 0;
60
- this._buckets = new Array<HashTableNode<K, V> | null>(this._capacity).fill(null);
46
+ get size(): number {
47
+ return this._size;
61
48
  }
62
49
 
63
- /**
64
- * The function `_defaultHashFn` calculates the hash value of a given key and returns the remainder when divided by the
65
- * capacity of the data structure.
66
- * @param {K} key - The `key` parameter is the input value that needs to be hashed. It can be of any type, but in this
67
- * code snippet, it is checked whether the key is a string or an object. If it is a string, the `_murmurStringHashFn`
68
- * function is used to
69
- * @returns the hash value of the key modulo the capacity of the data structure.
70
- */
71
- protected _defaultHashFn(key: K): number {
72
- // Can be replaced with other hash functions as needed
73
- const hashValue = typeof key === 'string' ? this._murmurStringHashFn(key) : this._objectHash(key);
74
- return hashValue % this._capacity;
75
- }
50
+ private _buckets: Array<HashTableNode<K, V> | null>;
76
51
 
77
- /**
78
- * The `_multiplicativeStringHashFn` function calculates a hash value for a given string key using the multiplicative
79
- * string hash function.
80
- * @param {K} key - The `key` parameter is the input value for which we want to calculate the hash. It can be of any
81
- * type, as it is generic (`K`). The function converts the `key` to a string using the `String()` function.
82
- * @returns a number, which is the result of the multiplicative string hash function applied to the input key.
83
- */
84
- protected _multiplicativeStringHashFn<K>(key: K): number {
85
- const keyString = String(key);
86
- let hash = 0;
87
- for (let i = 0; i < keyString.length; i++) {
88
- const charCode = keyString.charCodeAt(i);
89
- // Some constants for adjusting the hash function
90
- const A = 0.618033988749895;
91
- const M = 1 << 30; // 2^30
92
- hash = (hash * A + charCode) % M;
93
- }
94
- return Math.abs(hash); // Take absolute value to ensure non-negative numbers
52
+ get buckets(): Array<HashTableNode<K, V> | null> {
53
+ return this._buckets;
95
54
  }
96
55
 
97
- /**
98
- * The function `_murmurStringHashFn` calculates a hash value for a given string key using the MurmurHash algorithm.
99
- * @param {K} key - The `key` parameter is the input value for which you want to calculate the hash. It can be of any
100
- * type, but it will be converted to a string using the `String()` function before calculating the hash.
101
- * @returns a number, which is the hash value calculated for the given key.
102
- */
103
- protected _murmurStringHashFn<K>(key: K): number {
104
- const keyString = String(key);
105
- const seed = 0;
106
- let hash = seed;
107
-
108
- for (let i = 0; i < keyString.length; i++) {
109
- const char = keyString.charCodeAt(i);
110
- hash = (hash ^ char) * 0x5bd1e995;
111
- hash = (hash ^ (hash >>> 15)) * 0x27d4eb2d;
112
- hash = hash ^ (hash >>> 15);
113
- }
114
-
115
- return Math.abs(hash);
56
+ set buckets(value: Array<HashTableNode<K, V> | null>) {
57
+ this._buckets = value;
116
58
  }
117
59
 
118
- /**
119
- * The _hash function takes a key and returns a number.
120
- * @param {K} key - The parameter "key" is of type K, which represents the type of the key that will be hashed.
121
- * @returns The hash function is returning a number.
122
- */
123
- protected _hash(key: K): number {
124
- return this.hashFn(key);
125
- }
60
+ private _hashFn: HashFunction<K>;
126
61
 
127
- /**
128
- * The function calculates a hash value for a given string using the djb2 algorithm.
129
- * @param {string} key - The `key` parameter in the `stringHash` function is a string value that represents the input for
130
- * which we want to calculate the hash value.
131
- * @returns a number, which is the hash value of the input string.
132
- */
133
- protected _stringHash(key: string): number {
134
- let hash = 0;
135
- for (let i = 0; i < key.length; i++) {
136
- hash = (hash * 31 + key.charCodeAt(i)) & 0xffffffff;
137
- }
138
- return hash;
62
+ get hashFn(): HashFunction<K> {
63
+ return this._hashFn;
139
64
  }
140
65
 
141
- /**
142
- * The function `_objectHash` takes a key and returns a hash value, using a custom hash function for objects.
143
- * @param {K} key - The parameter "key" is of type "K", which means it can be any type. It could be a string, number,
144
- * boolean, object, or any other type of value. The purpose of the objectHash function is to generate a hash value for
145
- * the key, which can be used for
146
- * @returns a number, which is the hash value of the key.
147
- */
148
- protected _objectHash(key: K): number {
149
- // If the key is an object, you can write a custom hash function
150
- // For example, convert the object's properties to a string and use string hashing
151
- // This is just an example; you should write a specific object hash function as needed
152
- return this._stringHash(JSON.stringify(key));
66
+ set hashFn(value: HashFunction<K>) {
67
+ this._hashFn = value;
153
68
  }
154
69
 
155
70
  /**
@@ -240,6 +155,98 @@ export class HashTable<K, V> {
240
155
  }
241
156
  }
242
157
 
158
+ /**
159
+ * The function `_defaultHashFn` calculates the hash value of a given key and returns the remainder when divided by the
160
+ * capacity of the data structure.
161
+ * @param {K} key - The `key` parameter is the input value that needs to be hashed. It can be of any type, but in this
162
+ * code snippet, it is checked whether the key is a string or an object. If it is a string, the `_murmurStringHashFn`
163
+ * function is used to
164
+ * @returns the hash value of the key modulo the capacity of the data structure.
165
+ */
166
+ protected _defaultHashFn(key: K): number {
167
+ // Can be replaced with other hash functions as needed
168
+ const hashValue = typeof key === 'string' ? this._murmurStringHashFn(key) : this._objectHash(key);
169
+ return hashValue % this._capacity;
170
+ }
171
+
172
+ /**
173
+ * The `_multiplicativeStringHashFn` function calculates a hash value for a given string key using the multiplicative
174
+ * string hash function.
175
+ * @param {K} key - The `key` parameter is the input value for which we want to calculate the hash. It can be of any
176
+ * type, as it is generic (`K`). The function converts the `key` to a string using the `String()` function.
177
+ * @returns a number, which is the result of the multiplicative string hash function applied to the input key.
178
+ */
179
+ protected _multiplicativeStringHashFn<K>(key: K): number {
180
+ const keyString = String(key);
181
+ let hash = 0;
182
+ for (let i = 0; i < keyString.length; i++) {
183
+ const charCode = keyString.charCodeAt(i);
184
+ // Some constants for adjusting the hash function
185
+ const A = 0.618033988749895;
186
+ const M = 1 << 30; // 2^30
187
+ hash = (hash * A + charCode) % M;
188
+ }
189
+ return Math.abs(hash); // Take absolute value to ensure non-negative numbers
190
+ }
191
+
192
+ /**
193
+ * The function `_murmurStringHashFn` calculates a hash value for a given string key using the MurmurHash algorithm.
194
+ * @param {K} key - The `key` parameter is the input value for which you want to calculate the hash. It can be of any
195
+ * type, but it will be converted to a string using the `String()` function before calculating the hash.
196
+ * @returns a number, which is the hash value calculated for the given key.
197
+ */
198
+ protected _murmurStringHashFn<K>(key: K): number {
199
+ const keyString = String(key);
200
+ const seed = 0;
201
+ let hash = seed;
202
+
203
+ for (let i = 0; i < keyString.length; i++) {
204
+ const char = keyString.charCodeAt(i);
205
+ hash = (hash ^ char) * 0x5bd1e995;
206
+ hash = (hash ^ (hash >>> 15)) * 0x27d4eb2d;
207
+ hash = hash ^ (hash >>> 15);
208
+ }
209
+
210
+ return Math.abs(hash);
211
+ }
212
+
213
+ /**
214
+ * The _hash function takes a key and returns a number.
215
+ * @param {K} key - The parameter "key" is of type K, which represents the type of the key that will be hashed.
216
+ * @returns The hash function is returning a number.
217
+ */
218
+ protected _hash(key: K): number {
219
+ return this.hashFn(key);
220
+ }
221
+
222
+ /**
223
+ * The function calculates a hash value for a given string using the djb2 algorithm.
224
+ * @param {string} key - The `key` parameter in the `stringHash` function is a string value that represents the input for
225
+ * which we want to calculate the hash value.
226
+ * @returns a number, which is the hash value of the input string.
227
+ */
228
+ protected _stringHash(key: string): number {
229
+ let hash = 0;
230
+ for (let i = 0; i < key.length; i++) {
231
+ hash = (hash * 31 + key.charCodeAt(i)) & 0xffffffff;
232
+ }
233
+ return hash;
234
+ }
235
+
236
+ /**
237
+ * The function `_objectHash` takes a key and returns a hash value, using a custom hash function for objects.
238
+ * @param {K} key - The parameter "key" is of type "K", which means it can be any type. It could be a string, number,
239
+ * boolean, object, or any other type of value. The purpose of the objectHash function is to generate a hash value for
240
+ * the key, which can be used for
241
+ * @returns a number, which is the hash value of the key.
242
+ */
243
+ protected _objectHash(key: K): number {
244
+ // If the key is an object, you can write a custom hash function
245
+ // For example, convert the object's properties to a string and use string hashing
246
+ // This is just an example; you should write a specific object hash function as needed
247
+ return this._stringHash(JSON.stringify(key));
248
+ }
249
+
243
250
  /**
244
251
  * The `expand` function increases the capacity of a hash table by creating a new array of buckets with double the
245
252
  * capacity and rehashing all the existing key-value pairs into the new buckets.
@@ -270,8 +277,4 @@ export class HashTable<K, V> {
270
277
  this._buckets = newBuckets;
271
278
  this._capacity = newCapacity;
272
279
  }
273
-
274
- get size(): number {
275
- return this._size;
276
- }
277
280
  }
@@ -15,6 +15,34 @@ export class Heap<E> {
15
15
  this.comparator = comparator;
16
16
  }
17
17
 
18
+ /**
19
+ * Get the size (number of elements) of the heap.
20
+ */
21
+ get size(): number {
22
+ return this.nodes.length;
23
+ }
24
+
25
+ /**
26
+ * Get the last element in the heap, which is not necessarily a leaf node.
27
+ * @returns The last element or undefined if the heap is empty.
28
+ */
29
+ get leaf(): E | undefined {
30
+ return this.nodes[this.size - 1] ?? undefined;
31
+ }
32
+
33
+ /**
34
+ * Static method that creates a binary heap from an array of nodes and a comparison function.
35
+ * @param nodes
36
+ * @param comparator - Comparison function.
37
+ * @returns A new Heap instance.
38
+ */
39
+ static heapify<E>(nodes: E[], comparator: Comparator<E>): Heap<E> {
40
+ const binaryHeap = new Heap<E>(comparator);
41
+ binaryHeap.nodes = [...nodes];
42
+ binaryHeap.fix(); // Fix heap properties
43
+ return binaryHeap;
44
+ }
45
+
18
46
  /**
19
47
  * Insert an element into the heap and maintain the heap properties.
20
48
  * @param element - The element to be inserted.
@@ -59,57 +87,6 @@ export class Heap<E> {
59
87
  return this.poll();
60
88
  }
61
89
 
62
- /**
63
- * Float operation to maintain heap properties after adding an element.
64
- * @param index - The index of the newly added element.
65
- */
66
- protected bubbleUp(index: number): void {
67
- const element = this.nodes[index];
68
- while (index > 0) {
69
- const parentIndex = Math.floor((index - 1) / 2);
70
- const parent = this.nodes[parentIndex];
71
- if (this.comparator(element, parent) < 0) {
72
- this.nodes[index] = parent;
73
- this.nodes[parentIndex] = element;
74
- index = parentIndex;
75
- } else {
76
- break;
77
- }
78
- }
79
- }
80
-
81
- /**
82
- * Sinking operation to maintain heap properties after removing the top element.
83
- * @param index - The index from which to start sinking.
84
- */
85
- protected sinkDown(index: number): void {
86
- const leftChildIndex = 2 * index + 1;
87
- const rightChildIndex = 2 * index + 2;
88
- const length = this.nodes.length;
89
- let targetIndex = index;
90
-
91
- if (leftChildIndex < length && this.comparator(this.nodes[leftChildIndex], this.nodes[targetIndex]) < 0) {
92
- targetIndex = leftChildIndex;
93
- }
94
- if (rightChildIndex < length && this.comparator(this.nodes[rightChildIndex], this.nodes[targetIndex]) < 0) {
95
- targetIndex = rightChildIndex;
96
- }
97
-
98
- if (targetIndex !== index) {
99
- const temp = this.nodes[index];
100
- this.nodes[index] = this.nodes[targetIndex];
101
- this.nodes[targetIndex] = temp;
102
- this.sinkDown(targetIndex);
103
- }
104
- }
105
-
106
- /**
107
- * Fix the entire heap to maintain heap properties.
108
- */
109
- protected fix() {
110
- for (let i = Math.floor(this.size / 2); i >= 0; i--) this.sinkDown(i);
111
- }
112
-
113
90
  /**
114
91
  * Peek at the top element of the heap without removing it.
115
92
  * @returns The top element or undefined if the heap is empty.
@@ -121,21 +98,6 @@ export class Heap<E> {
121
98
  return this.nodes[0];
122
99
  }
123
100
 
124
- /**
125
- * Get the size (number of elements) of the heap.
126
- */
127
- get size(): number {
128
- return this.nodes.length;
129
- }
130
-
131
- /**
132
- * Get the last element in the heap, which is not necessarily a leaf node.
133
- * @returns The last element or undefined if the heap is empty.
134
- */
135
- get leaf(): E | undefined {
136
- return this.nodes[this.size - 1] ?? undefined;
137
- }
138
-
139
101
  /**
140
102
  * Check if the heap is empty.
141
103
  * @returns True if the heap is empty, otherwise false.
@@ -238,16 +200,54 @@ export class Heap<E> {
238
200
  }
239
201
 
240
202
  /**
241
- * Static method that creates a binary heap from an array of nodes and a comparison function.
242
- * @param nodes
243
- * @param comparator - Comparison function.
244
- * @returns A new Heap instance.
203
+ * Float operation to maintain heap properties after adding an element.
204
+ * @param index - The index of the newly added element.
245
205
  */
246
- static heapify<E>(nodes: E[], comparator: Comparator<E>): Heap<E> {
247
- const binaryHeap = new Heap<E>(comparator);
248
- binaryHeap.nodes = [...nodes];
249
- binaryHeap.fix(); // Fix heap properties
250
- return binaryHeap;
206
+ protected bubbleUp(index: number): void {
207
+ const element = this.nodes[index];
208
+ while (index > 0) {
209
+ const parentIndex = Math.floor((index - 1) / 2);
210
+ const parent = this.nodes[parentIndex];
211
+ if (this.comparator(element, parent) < 0) {
212
+ this.nodes[index] = parent;
213
+ this.nodes[parentIndex] = element;
214
+ index = parentIndex;
215
+ } else {
216
+ break;
217
+ }
218
+ }
219
+ }
220
+
221
+ /**
222
+ * Sinking operation to maintain heap properties after removing the top element.
223
+ * @param index - The index from which to start sinking.
224
+ */
225
+ protected sinkDown(index: number): void {
226
+ const leftChildIndex = 2 * index + 1;
227
+ const rightChildIndex = 2 * index + 2;
228
+ const length = this.nodes.length;
229
+ let targetIndex = index;
230
+
231
+ if (leftChildIndex < length && this.comparator(this.nodes[leftChildIndex], this.nodes[targetIndex]) < 0) {
232
+ targetIndex = leftChildIndex;
233
+ }
234
+ if (rightChildIndex < length && this.comparator(this.nodes[rightChildIndex], this.nodes[targetIndex]) < 0) {
235
+ targetIndex = rightChildIndex;
236
+ }
237
+
238
+ if (targetIndex !== index) {
239
+ const temp = this.nodes[index];
240
+ this.nodes[index] = this.nodes[targetIndex];
241
+ this.nodes[targetIndex] = temp;
242
+ this.sinkDown(targetIndex);
243
+ }
244
+ }
245
+
246
+ /**
247
+ * Fix the entire heap to maintain heap properties.
248
+ */
249
+ protected fix() {
250
+ for (let i = Math.floor(this.size / 2); i >= 0; i--) this.sinkDown(i);
251
251
  }
252
252
  }
253
253
 
@@ -259,6 +259,7 @@ export class FibonacciHeapNode<E> {
259
259
  child?: FibonacciHeapNode<E>;
260
260
  parent?: FibonacciHeapNode<E>;
261
261
  marked: boolean;
262
+
262
263
  constructor(element: E, degree = 0) {
263
264
  this.element = element;
264
265
  this.degree = degree;
@@ -268,8 +269,8 @@ export class FibonacciHeapNode<E> {
268
269
 
269
270
  export class FibonacciHeap<E> {
270
271
  root?: FibonacciHeapNode<E>;
271
- protected min?: FibonacciHeapNode<E>;
272
272
  size: number = 0;
273
+ protected min?: FibonacciHeapNode<E>;
273
274
  protected readonly comparator: Comparator<E>;
274
275
 
275
276
  constructor(comparator?: Comparator<E>) {
@@ -281,18 +282,6 @@ export class FibonacciHeap<E> {
281
282
  }
282
283
  }
283
284
 
284
- /**
285
- * Default comparator function used by the heap.
286
- * @param {E} a
287
- * @param {E} b
288
- * @protected
289
- */
290
- protected defaultComparator(a: E, b: E): number {
291
- if (a < b) return -1;
292
- if (a > b) return 1;
293
- return 0;
294
- }
295
-
296
285
  /**
297
286
  * Get the size (number of elements) of the heap.
298
287
  * @returns {number} The size of the heap. Returns 0 if the heap is empty. Returns -1 if the heap is invalid.
@@ -303,30 +292,6 @@ export class FibonacciHeap<E> {
303
292
  this.size = 0;
304
293
  }
305
294
 
306
- /**
307
- * Create a new node.
308
- * @param element
309
- * @protected
310
- */
311
- protected createNode(element: E): FibonacciHeapNode<E> {
312
- return new FibonacciHeapNode<E>(element);
313
- }
314
-
315
- /**
316
- * Merge the given node with the root list.
317
- * @param node - The node to be merged.
318
- */
319
- protected mergeWithRoot(node: FibonacciHeapNode<E>): void {
320
- if (!this.root) {
321
- this.root = node;
322
- } else {
323
- node.right = this.root.right;
324
- node.left = this.root;
325
- this.root.right!.left = node;
326
- this.root.right = node;
327
- }
328
- }
329
-
330
295
  /**
331
296
  * O(1) time operation.
332
297
  * Insert an element into the heap and maintain the heap properties.
@@ -394,18 +359,6 @@ export class FibonacciHeap<E> {
394
359
  return nodes;
395
360
  }
396
361
 
397
- /**
398
- * O(log n) time operation.
399
- * Remove and return the top element (smallest or largest element) from the heap.
400
- * @param node - The node to be removed.
401
- * @protected
402
- */
403
- protected removeFromRoot(node: FibonacciHeapNode<E>): void {
404
- if (this.root === node) this.root = node.right;
405
- if (node.left) node.left.right = node.right;
406
- if (node.right) node.right.left = node.left;
407
- }
408
-
409
362
  /**
410
363
  * O(log n) time operation.
411
364
  * Remove and return the top element (smallest or largest element) from the heap.
@@ -423,63 +376,6 @@ export class FibonacciHeap<E> {
423
376
  }
424
377
  }
425
378
 
426
- /**
427
- * O(log n) time operation.
428
- * Remove and return the top element (smallest or largest element) from the heap.
429
- * @param y
430
- * @param x
431
- * @protected
432
- */
433
- protected link(y: FibonacciHeapNode<E>, x: FibonacciHeapNode<E>): void {
434
- this.removeFromRoot(y);
435
- y.left = y;
436
- y.right = y;
437
- this.mergeWithChild(x, y);
438
- x.degree++;
439
- y.parent = x;
440
- }
441
-
442
- /**
443
- * O(log n) time operation.
444
- * Remove and return the top element (smallest or largest element) from the heap.
445
- * @protected
446
- */
447
- protected consolidate(): void {
448
- const A: (FibonacciHeapNode<E> | undefined)[] = new Array(this.size);
449
- const nodes = this.consumeLinkedList(this.root);
450
- let x: FibonacciHeapNode<E> | undefined,
451
- y: FibonacciHeapNode<E> | undefined,
452
- d: number,
453
- t: FibonacciHeapNode<E> | undefined;
454
-
455
- for (const node of nodes) {
456
- x = node;
457
- d = x.degree;
458
-
459
- while (A[d]) {
460
- y = A[d] as FibonacciHeapNode<E>;
461
-
462
- if (this.comparator(x.element, y.element) > 0) {
463
- t = x;
464
- x = y;
465
- y = t;
466
- }
467
-
468
- this.link(y, x);
469
- A[d] = undefined;
470
- d++;
471
- }
472
-
473
- A[d] = x;
474
- }
475
-
476
- for (let i = 0; i < this.size; i++) {
477
- if (A[i] && this.comparator(A[i]!.element, this.min!.element) <= 0) {
478
- this.min = A[i]!;
479
- }
480
- }
481
- }
482
-
483
379
  /**
484
380
  * O(log n) time operation.
485
381
  * Remove and return the top element (smallest or largest element) from the heap.
@@ -557,4 +453,109 @@ export class FibonacciHeap<E> {
557
453
  // Clear the heap that was merged
558
454
  heapToMerge.clear();
559
455
  }
456
+
457
+ /**
458
+ * Default comparator function used by the heap.
459
+ * @param {E} a
460
+ * @param {E} b
461
+ * @protected
462
+ */
463
+ protected defaultComparator(a: E, b: E): number {
464
+ if (a < b) return -1;
465
+ if (a > b) return 1;
466
+ return 0;
467
+ }
468
+
469
+ /**
470
+ * Create a new node.
471
+ * @param element
472
+ * @protected
473
+ */
474
+ protected createNode(element: E): FibonacciHeapNode<E> {
475
+ return new FibonacciHeapNode<E>(element);
476
+ }
477
+
478
+ /**
479
+ * Merge the given node with the root list.
480
+ * @param node - The node to be merged.
481
+ */
482
+ protected mergeWithRoot(node: FibonacciHeapNode<E>): void {
483
+ if (!this.root) {
484
+ this.root = node;
485
+ } else {
486
+ node.right = this.root.right;
487
+ node.left = this.root;
488
+ this.root.right!.left = node;
489
+ this.root.right = node;
490
+ }
491
+ }
492
+
493
+ /**
494
+ * O(log n) time operation.
495
+ * Remove and return the top element (smallest or largest element) from the heap.
496
+ * @param node - The node to be removed.
497
+ * @protected
498
+ */
499
+ protected removeFromRoot(node: FibonacciHeapNode<E>): void {
500
+ if (this.root === node) this.root = node.right;
501
+ if (node.left) node.left.right = node.right;
502
+ if (node.right) node.right.left = node.left;
503
+ }
504
+
505
+ /**
506
+ * O(log n) time operation.
507
+ * Remove and return the top element (smallest or largest element) from the heap.
508
+ * @param y
509
+ * @param x
510
+ * @protected
511
+ */
512
+ protected link(y: FibonacciHeapNode<E>, x: FibonacciHeapNode<E>): void {
513
+ this.removeFromRoot(y);
514
+ y.left = y;
515
+ y.right = y;
516
+ this.mergeWithChild(x, y);
517
+ x.degree++;
518
+ y.parent = x;
519
+ }
520
+
521
+ /**
522
+ * O(log n) time operation.
523
+ * Remove and return the top element (smallest or largest element) from the heap.
524
+ * @protected
525
+ */
526
+ protected consolidate(): void {
527
+ const A: (FibonacciHeapNode<E> | undefined)[] = new Array(this.size);
528
+ const nodes = this.consumeLinkedList(this.root);
529
+ let x: FibonacciHeapNode<E> | undefined,
530
+ y: FibonacciHeapNode<E> | undefined,
531
+ d: number,
532
+ t: FibonacciHeapNode<E> | undefined;
533
+
534
+ for (const node of nodes) {
535
+ x = node;
536
+ d = x.degree;
537
+
538
+ while (A[d]) {
539
+ y = A[d] as FibonacciHeapNode<E>;
540
+
541
+ if (this.comparator(x.element, y.element) > 0) {
542
+ t = x;
543
+ x = y;
544
+ y = t;
545
+ }
546
+
547
+ this.link(y, x);
548
+ A[d] = undefined;
549
+ d++;
550
+ }
551
+
552
+ A[d] = x;
553
+ }
554
+
555
+ for (let i = 0; i < this.size; i++) {
556
+ if (A[i] && this.comparator(A[i]!.element, this.min!.element) <= 0) {
557
+ this.min = A[i]!;
558
+ }
559
+ }
560
+ }
560
561
  }