heap-typed 1.53.5 → 1.53.7
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 +136 -171
- package/dist/common/index.d.ts +12 -0
- package/dist/common/index.js +23 -0
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +7 -10
- package/dist/data-structures/binary-tree/avl-tree.js +2 -2
- package/dist/data-structures/binary-tree/binary-tree.d.ts +54 -19
- package/dist/data-structures/binary-tree/binary-tree.js +100 -66
- package/dist/data-structures/binary-tree/bst.d.ts +100 -36
- package/dist/data-structures/binary-tree/bst.js +185 -66
- package/dist/data-structures/binary-tree/rb-tree.d.ts +4 -0
- package/dist/data-structures/binary-tree/rb-tree.js +6 -2
- package/dist/data-structures/binary-tree/tree-multi-map.js +2 -2
- package/dist/data-structures/heap/heap.d.ts +6 -6
- package/dist/data-structures/heap/heap.js +6 -6
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +31 -19
- package/dist/data-structures/linked-list/doubly-linked-list.js +49 -34
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +144 -62
- package/dist/data-structures/linked-list/singly-linked-list.js +201 -97
- package/dist/data-structures/trie/trie.d.ts +104 -4
- package/dist/data-structures/trie/trie.js +116 -12
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/bst.d.ts +3 -2
- package/dist/types/data-structures/binary-tree/rb-tree.d.ts +1 -1
- package/dist/types/utils/utils.d.ts +10 -6
- package/dist/utils/utils.js +4 -2
- package/package.json +2 -2
- package/src/common/index.ts +19 -0
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +7 -9
- package/src/data-structures/binary-tree/avl-tree.ts +3 -2
- package/src/data-structures/binary-tree/binary-tree.ts +108 -64
- package/src/data-structures/binary-tree/bst.ts +190 -69
- package/src/data-structures/binary-tree/rb-tree.ts +6 -2
- package/src/data-structures/binary-tree/tree-multi-map.ts +3 -3
- package/src/data-structures/heap/heap.ts +39 -39
- package/src/data-structures/linked-list/doubly-linked-list.ts +139 -121
- package/src/data-structures/linked-list/singly-linked-list.ts +219 -98
- package/src/data-structures/trie/trie.ts +116 -11
- package/src/index.ts +2 -1
- package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
- package/src/types/data-structures/binary-tree/bst.ts +3 -2
- package/src/types/data-structures/binary-tree/rb-tree.ts +1 -1
- package/src/types/utils/utils.ts +16 -10
- package/src/utils/utils.ts +4 -2
|
@@ -58,6 +58,54 @@ exports.BSTNode = BSTNode;
|
|
|
58
58
|
* 5. Logarithmic Operations: Ideal operations like insertion, deletion, and searching are O(log n) time-efficient.
|
|
59
59
|
* 6. Balance Variability: Can become unbalanced; special types maintain balance.
|
|
60
60
|
* 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.
|
|
61
|
+
* @example
|
|
62
|
+
* // Find kth smallest element
|
|
63
|
+
* // Create a BST with some elements
|
|
64
|
+
* const bst = new BST<number>([5, 3, 7, 1, 4, 6, 8]);
|
|
65
|
+
* const sortedKeys = bst.dfs(node => node.key, 'IN');
|
|
66
|
+
*
|
|
67
|
+
* // Helper function to find kth smallest
|
|
68
|
+
* const findKthSmallest = (k: number): number | undefined => {
|
|
69
|
+
* return sortedKeys[k - 1];
|
|
70
|
+
* };
|
|
71
|
+
*
|
|
72
|
+
* // Assertions
|
|
73
|
+
* console.log(findKthSmallest(1)); // 1
|
|
74
|
+
* console.log(findKthSmallest(3)); // 4
|
|
75
|
+
* console.log(findKthSmallest(7)); // 8
|
|
76
|
+
* @example
|
|
77
|
+
* // Find elements in a range
|
|
78
|
+
* const bst = new BST<number>([10, 5, 15, 3, 7, 12, 18]);
|
|
79
|
+
* console.log(bst.search(new Range(5, 10))); // [10, 5, 7]
|
|
80
|
+
* console.log(bst.search(new Range(4, 12))); // [10, 12, 5, 7]
|
|
81
|
+
* console.log(bst.search(new Range(4, 12, true, false))); // [10, 5, 7]
|
|
82
|
+
* console.log(bst.search(new Range(15, 20))); // [15, 18]
|
|
83
|
+
* console.log(bst.search(new Range(15, 20, false))); // [18]
|
|
84
|
+
* @example
|
|
85
|
+
* // Find lowest common ancestor
|
|
86
|
+
* const bst = new BST<number>([20, 10, 30, 5, 15, 25, 35, 3, 7, 12, 18]);
|
|
87
|
+
*
|
|
88
|
+
* function findFirstCommon(arr1: number[], arr2: number[]): number | undefined {
|
|
89
|
+
* for (const num of arr1) {
|
|
90
|
+
* if (arr2.indexOf(num) !== -1) {
|
|
91
|
+
* return num;
|
|
92
|
+
* }
|
|
93
|
+
* }
|
|
94
|
+
* return undefined;
|
|
95
|
+
* }
|
|
96
|
+
*
|
|
97
|
+
* // LCA helper function
|
|
98
|
+
* const findLCA = (num1: number, num2: number): number | undefined => {
|
|
99
|
+
* const path1 = bst.getPathToRoot(num1);
|
|
100
|
+
* const path2 = bst.getPathToRoot(num2);
|
|
101
|
+
* // Find the first common ancestor
|
|
102
|
+
* return findFirstCommon(path1, path2);
|
|
103
|
+
* };
|
|
104
|
+
*
|
|
105
|
+
* // Assertions
|
|
106
|
+
* console.log(findLCA(3, 10)); // 7
|
|
107
|
+
* console.log(findLCA(5, 35)); // 15
|
|
108
|
+
* console.log(findLCA(20, 30)); // 25
|
|
61
109
|
*/
|
|
62
110
|
class BST extends binary_tree_1.BinaryTree {
|
|
63
111
|
/**
|
|
@@ -71,21 +119,33 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
71
119
|
constructor(keysNodesEntriesOrRaws = [], options) {
|
|
72
120
|
super([], options);
|
|
73
121
|
this._root = undefined;
|
|
74
|
-
this.
|
|
122
|
+
this._isReverse = false;
|
|
123
|
+
this._comparator = (a, b) => {
|
|
124
|
+
if ((0, utils_1.isComparable)(a) && (0, utils_1.isComparable)(b)) {
|
|
125
|
+
if (a > b)
|
|
126
|
+
return 1;
|
|
127
|
+
if (a < b)
|
|
128
|
+
return -1;
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
131
|
+
if (this._extractComparable) {
|
|
132
|
+
if (this._extractComparable(a) > this._extractComparable(b))
|
|
133
|
+
return 1;
|
|
134
|
+
if (this._extractComparable(a) < this._extractComparable(b))
|
|
135
|
+
return -1;
|
|
136
|
+
return 0;
|
|
137
|
+
}
|
|
75
138
|
if (typeof a === 'object' || typeof b === 'object') {
|
|
76
|
-
throw TypeError(`When comparing object types, a custom
|
|
139
|
+
throw TypeError(`When comparing object types, a custom extractComparable must be defined in the constructor's options parameter.`);
|
|
77
140
|
}
|
|
78
|
-
if (a > b)
|
|
79
|
-
return 1;
|
|
80
|
-
if (a < b)
|
|
81
|
-
return -1;
|
|
82
141
|
return 0;
|
|
83
142
|
};
|
|
84
|
-
this._comparator = this._DEFAULT_COMPARATOR;
|
|
85
143
|
if (options) {
|
|
86
|
-
const {
|
|
87
|
-
if (
|
|
88
|
-
this.
|
|
144
|
+
const { extractComparable, isReverse } = options;
|
|
145
|
+
if (typeof extractComparable === 'function')
|
|
146
|
+
this._extractComparable = extractComparable;
|
|
147
|
+
if (isReverse !== undefined)
|
|
148
|
+
this._isReverse = isReverse;
|
|
89
149
|
}
|
|
90
150
|
if (keysNodesEntriesOrRaws)
|
|
91
151
|
this.addMany(keysNodesEntriesOrRaws);
|
|
@@ -97,6 +157,14 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
97
157
|
get root() {
|
|
98
158
|
return this._root;
|
|
99
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* The above function is a getter method in TypeScript that returns the value of the private property
|
|
162
|
+
* `_isReverse`.
|
|
163
|
+
* @returns The `isReverse` property of the object, which is a boolean value.
|
|
164
|
+
*/
|
|
165
|
+
get isReverse() {
|
|
166
|
+
return this._isReverse;
|
|
167
|
+
}
|
|
100
168
|
/**
|
|
101
169
|
* The function creates a new BSTNode with the given key and value and returns it.
|
|
102
170
|
* @param {K} key - The key parameter is of type K, which represents the type of the key for the node
|
|
@@ -116,7 +184,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
116
184
|
* @returns a new instance of the BST class with the provided options.
|
|
117
185
|
*/
|
|
118
186
|
createTree(options) {
|
|
119
|
-
return new BST([], Object.assign({ iterationType: this.iterationType, isMapMode: this._isMapMode,
|
|
187
|
+
return new BST([], Object.assign({ iterationType: this.iterationType, isMapMode: this._isMapMode, extractComparable: this._extractComparable, toEntryFn: this._toEntryFn, isReverse: this._isReverse }, options));
|
|
120
188
|
}
|
|
121
189
|
/**
|
|
122
190
|
* The function overrides a method and converts a key, value pair or entry or raw element to a node.
|
|
@@ -167,11 +235,11 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
167
235
|
* @param {any} key - The `key` parameter is a value that will be checked to determine if it is of
|
|
168
236
|
* type `K`.
|
|
169
237
|
* @returns The `override isKey(key: any): key is K` function is returning a boolean value based on
|
|
170
|
-
* the result of the `isComparable` function with the condition `this.
|
|
238
|
+
* the result of the `isComparable` function with the condition `this._compare !==
|
|
171
239
|
* this._DEFAULT_COMPARATOR`.
|
|
172
240
|
*/
|
|
173
241
|
isKey(key) {
|
|
174
|
-
return (0, utils_1.isComparable)(key, this.
|
|
242
|
+
return (0, utils_1.isComparable)(key, this._extractComparable !== undefined);
|
|
175
243
|
}
|
|
176
244
|
/**
|
|
177
245
|
* Time Complexity: O(log n)
|
|
@@ -197,13 +265,13 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
197
265
|
}
|
|
198
266
|
let current = this._root;
|
|
199
267
|
while (current !== undefined) {
|
|
200
|
-
if (this.
|
|
268
|
+
if (this._compare(current.key, newNode.key) === 0) {
|
|
201
269
|
this._replaceNode(current, newNode);
|
|
202
270
|
if (this._isMapMode)
|
|
203
271
|
this._setValue(current.key, newValue);
|
|
204
272
|
return true;
|
|
205
273
|
}
|
|
206
|
-
else if (this.
|
|
274
|
+
else if (this._compare(current.key, newNode.key) > 0) {
|
|
207
275
|
if (current.left === undefined) {
|
|
208
276
|
current.left = newNode;
|
|
209
277
|
if (this._isMapMode)
|
|
@@ -290,7 +358,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
290
358
|
keyB = b;
|
|
291
359
|
}
|
|
292
360
|
if (keyA !== undefined && keyA !== null && keyB !== undefined && keyB !== null) {
|
|
293
|
-
return this.
|
|
361
|
+
return this._compare(keyA, keyB);
|
|
294
362
|
}
|
|
295
363
|
return 0;
|
|
296
364
|
});
|
|
@@ -328,30 +396,47 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
328
396
|
}
|
|
329
397
|
return inserted;
|
|
330
398
|
}
|
|
399
|
+
/**
|
|
400
|
+
* Time Complexity: O(n)
|
|
401
|
+
* Space Complexity: O(1)
|
|
402
|
+
*
|
|
403
|
+
* The `merge` function overrides the base class method by adding elements from another
|
|
404
|
+
* binary search tree.
|
|
405
|
+
* @param anotherTree - `anotherTree` is an instance of a Binary Search Tree (BST) with key type `K`,
|
|
406
|
+
* value type `V`, return type `R`, node type `NODE`, and tree type `TREE`.
|
|
407
|
+
*/
|
|
408
|
+
merge(anotherTree) {
|
|
409
|
+
this.addMany(anotherTree, [], false);
|
|
410
|
+
}
|
|
331
411
|
/**
|
|
332
412
|
* Time Complexity: O(log n)
|
|
333
413
|
* Space Complexity: O(k + log n)
|
|
334
414
|
*
|
|
335
|
-
* The function `
|
|
336
|
-
*
|
|
337
|
-
* @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate - The
|
|
338
|
-
* parameter in the `
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
415
|
+
* The function `search` in TypeScript overrides the search behavior in a binary tree structure based
|
|
416
|
+
* on specified criteria.
|
|
417
|
+
* @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate - The
|
|
418
|
+
* `keyNodeEntryRawOrPredicate` parameter in the `override search` method can accept one of the
|
|
419
|
+
* following types:
|
|
420
|
+
* @param [onlyOne=false] - The `onlyOne` parameter is a boolean flag that determines whether the
|
|
421
|
+
* search should stop after finding the first matching node. If `onlyOne` is set to `true`, the
|
|
422
|
+
* search will return as soon as a matching node is found. If `onlyOne` is set to `false`, the
|
|
423
|
+
* @param {C} callback - The `callback` parameter in the `override search` function is a function
|
|
424
|
+
* that will be called on each node that matches the search criteria. It is of type `C`, which
|
|
425
|
+
* extends `NodeCallback<NODE>`. The callback function should accept a node of type `NODE` as its
|
|
426
|
+
* argument and
|
|
427
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `override search`
|
|
428
|
+
* method represents the node from which the search operation will begin. It is the starting point
|
|
429
|
+
* for searching within the tree data structure. The method ensures that the `startNode` is a valid
|
|
430
|
+
* node before proceeding with the search operation. If the `
|
|
431
|
+
* @param {IterationType} iterationType - The `iterationType` parameter in the `override search`
|
|
432
|
+
* function determines the type of iteration to be used during the search operation. It can have two
|
|
433
|
+
* possible values:
|
|
434
|
+
* @returns The `override search` method returns an array of values that match the search criteria
|
|
435
|
+
* specified by the input parameters. The method performs a search operation on a binary tree
|
|
436
|
+
* structure based on the provided key, predicate, and other options. The search results are
|
|
437
|
+
* collected in an array and returned as the output of the method.
|
|
353
438
|
*/
|
|
354
|
-
|
|
439
|
+
search(keyNodeEntryRawOrPredicate, onlyOne = false, callback = this._DEFAULT_NODE_CALLBACK, startNode = this._root, iterationType = this.iterationType) {
|
|
355
440
|
if (keyNodeEntryRawOrPredicate === undefined)
|
|
356
441
|
return [];
|
|
357
442
|
if (keyNodeEntryRawOrPredicate === null)
|
|
@@ -359,28 +444,60 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
359
444
|
startNode = this.ensureNode(startNode);
|
|
360
445
|
if (!startNode)
|
|
361
446
|
return [];
|
|
362
|
-
|
|
447
|
+
let predicate;
|
|
448
|
+
const isRange = this.isRange(keyNodeEntryRawOrPredicate);
|
|
449
|
+
// Set predicate based on parameter type
|
|
450
|
+
if (isRange) {
|
|
451
|
+
predicate = node => keyNodeEntryRawOrPredicate.isInRange(node.key, this._comparator);
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
predicate = this._ensurePredicate(keyNodeEntryRawOrPredicate);
|
|
455
|
+
}
|
|
456
|
+
const isToLeftByRange = (cur) => {
|
|
457
|
+
if (isRange) {
|
|
458
|
+
const range = keyNodeEntryRawOrPredicate;
|
|
459
|
+
const leftS = this.isReverse ? range.high : range.low;
|
|
460
|
+
const leftI = this.isReverse ? range.includeHigh : range.includeLow;
|
|
461
|
+
return (leftI && this._compare(cur.key, leftS) >= 0) || (!leftI && this._compare(cur.key, leftS) > 0);
|
|
462
|
+
}
|
|
463
|
+
return false;
|
|
464
|
+
};
|
|
465
|
+
const isToRightByRange = (cur) => {
|
|
466
|
+
if (isRange) {
|
|
467
|
+
const range = keyNodeEntryRawOrPredicate;
|
|
468
|
+
const rightS = this.isReverse ? range.low : range.high;
|
|
469
|
+
const rightI = this.isReverse ? range.includeLow : range.includeLow;
|
|
470
|
+
return (rightI && this._compare(cur.key, rightS) <= 0) || (!rightI && this._compare(cur.key, rightS) < 0);
|
|
471
|
+
}
|
|
472
|
+
return false;
|
|
473
|
+
};
|
|
363
474
|
const ans = [];
|
|
364
475
|
if (iterationType === 'RECURSIVE') {
|
|
365
476
|
const dfs = (cur) => {
|
|
366
|
-
if (
|
|
367
|
-
ans.push(cur);
|
|
477
|
+
if (predicate(cur)) {
|
|
478
|
+
ans.push(callback(cur));
|
|
368
479
|
if (onlyOne)
|
|
369
480
|
return;
|
|
370
481
|
}
|
|
371
482
|
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right))
|
|
372
483
|
return;
|
|
373
|
-
if (
|
|
374
|
-
|
|
484
|
+
if (isRange) {
|
|
485
|
+
if (this.isRealNode(cur.left) && isToLeftByRange(cur))
|
|
486
|
+
dfs(cur.left);
|
|
487
|
+
if (this.isRealNode(cur.right) && isToRightByRange(cur))
|
|
488
|
+
dfs(cur.right);
|
|
489
|
+
}
|
|
490
|
+
else if (!this._isPredicate(keyNodeEntryRawOrPredicate)) {
|
|
491
|
+
const benchmarkKey = this._extractKey(keyNodeEntryRawOrPredicate);
|
|
375
492
|
if (this.isRealNode(cur.left) &&
|
|
376
493
|
benchmarkKey !== null &&
|
|
377
494
|
benchmarkKey !== undefined &&
|
|
378
|
-
this.
|
|
495
|
+
this._compare(cur.key, benchmarkKey) > 0)
|
|
379
496
|
dfs(cur.left);
|
|
380
497
|
if (this.isRealNode(cur.right) &&
|
|
381
498
|
benchmarkKey !== null &&
|
|
382
499
|
benchmarkKey !== undefined &&
|
|
383
|
-
this.
|
|
500
|
+
this._compare(cur.key, benchmarkKey) < 0)
|
|
384
501
|
dfs(cur.right);
|
|
385
502
|
}
|
|
386
503
|
else {
|
|
@@ -396,22 +513,28 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
396
513
|
const stack = [startNode];
|
|
397
514
|
while (stack.length > 0) {
|
|
398
515
|
const cur = stack.pop();
|
|
399
|
-
if (
|
|
400
|
-
ans.push(cur);
|
|
516
|
+
if (predicate(cur)) {
|
|
517
|
+
ans.push(callback(cur));
|
|
401
518
|
if (onlyOne)
|
|
402
519
|
return ans;
|
|
403
520
|
}
|
|
404
|
-
if (
|
|
405
|
-
|
|
521
|
+
if (isRange) {
|
|
522
|
+
if (this.isRealNode(cur.left) && isToLeftByRange(cur))
|
|
523
|
+
stack.push(cur.left);
|
|
524
|
+
if (this.isRealNode(cur.right) && isToRightByRange(cur))
|
|
525
|
+
stack.push(cur.right);
|
|
526
|
+
}
|
|
527
|
+
else if (!this._isPredicate(keyNodeEntryRawOrPredicate)) {
|
|
528
|
+
const benchmarkKey = this._extractKey(keyNodeEntryRawOrPredicate);
|
|
406
529
|
if (this.isRealNode(cur.right) &&
|
|
407
530
|
benchmarkKey !== null &&
|
|
408
531
|
benchmarkKey !== undefined &&
|
|
409
|
-
this.
|
|
532
|
+
this._compare(cur.key, benchmarkKey) < 0)
|
|
410
533
|
stack.push(cur.right);
|
|
411
534
|
if (this.isRealNode(cur.left) &&
|
|
412
535
|
benchmarkKey !== null &&
|
|
413
536
|
benchmarkKey !== undefined &&
|
|
414
|
-
this.
|
|
537
|
+
this._compare(cur.key, benchmarkKey) > 0)
|
|
415
538
|
stack.push(cur.left);
|
|
416
539
|
}
|
|
417
540
|
else {
|
|
@@ -448,22 +571,6 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
448
571
|
var _a;
|
|
449
572
|
return (_a = this.getNodes(keyNodeEntryRawOrPredicate, true, startNode, iterationType)[0]) !== null && _a !== void 0 ? _a : undefined;
|
|
450
573
|
}
|
|
451
|
-
/**
|
|
452
|
-
* Time Complexity: O(log n)
|
|
453
|
-
* Space Complexity: O(1)
|
|
454
|
-
*
|
|
455
|
-
* The function `getNodeByKey` returns a node with a specific key from a tree data structure.
|
|
456
|
-
* @param {K} key - The key parameter is the value used to search for a specific node in the tree. It
|
|
457
|
-
* is typically a unique identifier or a value that can be used to determine the position of the node
|
|
458
|
-
* in the tree structure.
|
|
459
|
-
* @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional
|
|
460
|
-
* parameter that specifies the type of iteration to be used when searching for a node in the tree.
|
|
461
|
-
* It has a default value of `'ITERATIVE'`.
|
|
462
|
-
* @returns The method is returning a NODE object or undefined.
|
|
463
|
-
*/
|
|
464
|
-
getNodeByKey(key, iterationType = this.iterationType) {
|
|
465
|
-
return this.getNode(key, this._root, iterationType);
|
|
466
|
-
}
|
|
467
574
|
/**
|
|
468
575
|
* Time complexity: O(n)
|
|
469
576
|
* Space complexity: O(n)
|
|
@@ -559,9 +666,10 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
559
666
|
const targetKey = targetNodeEnsured.key;
|
|
560
667
|
if (iterationType === 'RECURSIVE') {
|
|
561
668
|
const dfs = (cur) => {
|
|
562
|
-
const compared = this.
|
|
669
|
+
const compared = this._compare(cur.key, targetKey);
|
|
563
670
|
if (Math.sign(compared) === lesserOrGreater)
|
|
564
671
|
ans.push(callback(cur));
|
|
672
|
+
// TODO here can be optimized to O(log n)
|
|
565
673
|
if (this.isRealNode(cur.left))
|
|
566
674
|
dfs(cur.left);
|
|
567
675
|
if (this.isRealNode(cur.right))
|
|
@@ -575,7 +683,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
575
683
|
while (queue.size > 0) {
|
|
576
684
|
const cur = queue.shift();
|
|
577
685
|
if (this.isRealNode(cur)) {
|
|
578
|
-
const compared = this.
|
|
686
|
+
const compared = this._compare(cur.key, targetKey);
|
|
579
687
|
if (Math.sign(compared) === lesserOrGreater)
|
|
580
688
|
ans.push(callback(cur));
|
|
581
689
|
if (this.isRealNode(cur.left))
|
|
@@ -705,6 +813,14 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
705
813
|
get comparator() {
|
|
706
814
|
return this._comparator;
|
|
707
815
|
}
|
|
816
|
+
/**
|
|
817
|
+
* This function returns the value of the `_extractComparable` property.
|
|
818
|
+
* @returns The method `extractComparable()` is being returned, which is a getter method for the
|
|
819
|
+
* `_extractComparable` property.
|
|
820
|
+
*/
|
|
821
|
+
get extractComparable() {
|
|
822
|
+
return this._extractComparable;
|
|
823
|
+
}
|
|
708
824
|
/**
|
|
709
825
|
* The function sets the root of a tree-like structure and updates the parent property of the new
|
|
710
826
|
* root.
|
|
@@ -716,5 +832,8 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
716
832
|
}
|
|
717
833
|
this._root = v;
|
|
718
834
|
}
|
|
835
|
+
_compare(a, b) {
|
|
836
|
+
return this._isReverse ? -this._comparator(a, b) : this._comparator(a, b);
|
|
837
|
+
}
|
|
719
838
|
}
|
|
720
839
|
exports.BST = BST;
|
|
@@ -26,6 +26,10 @@ export declare class RedBlackTreeNode<K = any, V = any, NODE extends RedBlackTre
|
|
|
26
26
|
*/
|
|
27
27
|
set color(value: RBTNColor);
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* 1. Efficient self-balancing, but not completely balanced. Compared with AVLTree, the addition and deletion efficiency is high but the query efficiency is slightly lower.
|
|
31
|
+
* 2. It is BST itself. Compared with Heap which is not completely ordered, RedBlackTree is completely ordered.
|
|
32
|
+
*/
|
|
29
33
|
export declare class RedBlackTree<K = any, V = any, R = object, NODE extends RedBlackTreeNode<K, V, NODE> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>, TREE extends RedBlackTree<K, V, R, NODE, TREE> = RedBlackTree<K, V, R, NODE, RedBlackTreeNested<K, V, R, NODE>>> extends BST<K, V, R, NODE, TREE> implements IBinaryTree<K, V, R, NODE, TREE> {
|
|
30
34
|
/**
|
|
31
35
|
* This is the constructor function for a Red-Black Tree data structure in TypeScript.
|
|
@@ -34,6 +34,10 @@ class RedBlackTreeNode extends bst_1.BSTNode {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
exports.RedBlackTreeNode = RedBlackTreeNode;
|
|
37
|
+
/**
|
|
38
|
+
* 1. Efficient self-balancing, but not completely balanced. Compared with AVLTree, the addition and deletion efficiency is high but the query efficiency is slightly lower.
|
|
39
|
+
* 2. It is BST itself. Compared with Heap which is not completely ordered, RedBlackTree is completely ordered.
|
|
40
|
+
*/
|
|
37
41
|
class RedBlackTree extends bst_1.BST {
|
|
38
42
|
/**
|
|
39
43
|
* This is the constructor function for a Red-Black Tree data structure in TypeScript.
|
|
@@ -83,7 +87,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
83
87
|
* @returns a new instance of a RedBlackTree object.
|
|
84
88
|
*/
|
|
85
89
|
createTree(options) {
|
|
86
|
-
return new RedBlackTree([], Object.assign({ iterationType: this.iterationType, isMapMode: this._isMapMode,
|
|
90
|
+
return new RedBlackTree([], Object.assign({ iterationType: this.iterationType, isMapMode: this._isMapMode, extractComparable: this._extractComparable, toEntryFn: this._toEntryFn }, options));
|
|
87
91
|
}
|
|
88
92
|
/**
|
|
89
93
|
* Time Complexity: O(1)
|
|
@@ -303,7 +307,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
303
307
|
let parent = undefined;
|
|
304
308
|
while (this.isRealNode(current)) {
|
|
305
309
|
parent = current;
|
|
306
|
-
const compared = this.
|
|
310
|
+
const compared = this._compare(node.key, current.key);
|
|
307
311
|
if (compared < 0) {
|
|
308
312
|
current = (_a = current.left) !== null && _a !== void 0 ? _a : this.NIL;
|
|
309
313
|
}
|
|
@@ -99,7 +99,7 @@ class TreeMultiMap extends rb_tree_1.RedBlackTree {
|
|
|
99
99
|
* existing `iterationType` property. The returned value is casted as `TREE`.
|
|
100
100
|
*/
|
|
101
101
|
createTree(options) {
|
|
102
|
-
return new TreeMultiMap([], Object.assign({ iterationType: this.iterationType, isMapMode: this._isMapMode,
|
|
102
|
+
return new TreeMultiMap([], Object.assign({ iterationType: this.iterationType, isMapMode: this._isMapMode, extractComparable: this._extractComparable, toEntryFn: this._toEntryFn }, options));
|
|
103
103
|
}
|
|
104
104
|
/**
|
|
105
105
|
* The function `keyValueNodeEntryRawToNodeAndValue` takes in a key, value, and count and returns a
|
|
@@ -126,7 +126,7 @@ class TreeMultiMap extends rb_tree_1.RedBlackTree {
|
|
|
126
126
|
if (this.isKey(key))
|
|
127
127
|
return [this.createNode(key, finalValue, 'BLACK', count), finalValue];
|
|
128
128
|
}
|
|
129
|
-
if (this.
|
|
129
|
+
if (this.isRaw(keyNodeEntryOrRaw)) {
|
|
130
130
|
const [key, entryValue] = this._toEntryFn(keyNodeEntryOrRaw);
|
|
131
131
|
const finalValue = value !== null && value !== void 0 ? value : entryValue;
|
|
132
132
|
if (this.isKey(key))
|
|
@@ -19,7 +19,7 @@ import { IterableElementBase } from '../base';
|
|
|
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
20
|
* @example
|
|
21
21
|
* // Use Heap to sort an array
|
|
22
|
-
*
|
|
22
|
+
* function heapSort(arr: number[]): number[] {
|
|
23
23
|
* const heap = new Heap<number>(arr, { comparator: (a, b) => a - b });
|
|
24
24
|
* const sorted: number[] = [];
|
|
25
25
|
* while (!heap.isEmpty()) {
|
|
@@ -32,7 +32,7 @@ import { IterableElementBase } from '../base';
|
|
|
32
32
|
* console.log(heapSort(array)); // [1, 2, 3, 4, 5, 8]
|
|
33
33
|
* @example
|
|
34
34
|
* // Use Heap to solve top k problems
|
|
35
|
-
*
|
|
35
|
+
* function topKElements(arr: number[], k: number): number[] {
|
|
36
36
|
* const heap = new Heap<number>([], { comparator: (a, b) => b - a }); // Max heap
|
|
37
37
|
* arr.forEach(num => {
|
|
38
38
|
* heap.add(num);
|
|
@@ -45,7 +45,7 @@ import { IterableElementBase } from '../base';
|
|
|
45
45
|
* console.log(topKElements(numbers, 3)); // [15, 10, 5]
|
|
46
46
|
* @example
|
|
47
47
|
* // Use Heap to merge sorted sequences
|
|
48
|
-
*
|
|
48
|
+
* function mergeSortedSequences(sequences: number[][]): number[] {
|
|
49
49
|
* const heap = new Heap<{ value: number; seqIndex: number; itemIndex: number }>([], {
|
|
50
50
|
* comparator: (a, b) => a.value - b.value // Min heap
|
|
51
51
|
* });
|
|
@@ -82,7 +82,7 @@ import { IterableElementBase } from '../base';
|
|
|
82
82
|
* console.log(mergeSortedSequences(sequences)); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
83
83
|
* @example
|
|
84
84
|
* // Use Heap to dynamically maintain the median
|
|
85
|
-
*
|
|
85
|
+
* class MedianFinder {
|
|
86
86
|
* private low: MaxHeap<number>; // Max heap, stores the smaller half
|
|
87
87
|
* private high: MinHeap<number>; // Min heap, stores the larger half
|
|
88
88
|
*
|
|
@@ -119,7 +119,7 @@ import { IterableElementBase } from '../base';
|
|
|
119
119
|
* console.log(medianFinder.findMedian()); // 30
|
|
120
120
|
* @example
|
|
121
121
|
* // Use Heap for load balancing
|
|
122
|
-
*
|
|
122
|
+
* function loadBalance(requests: number[], servers: number): number[] {
|
|
123
123
|
* const serverHeap = new Heap<{ id: number; load: number }>([], { comparator: (a, b) => a.load - b.load }); // min heap
|
|
124
124
|
* const serverLoads = new Array(servers).fill(0);
|
|
125
125
|
*
|
|
@@ -141,7 +141,7 @@ import { IterableElementBase } from '../base';
|
|
|
141
141
|
* console.log(loadBalance(requests, 3)); // [12, 8, 5]
|
|
142
142
|
* @example
|
|
143
143
|
* // Use Heap to schedule tasks
|
|
144
|
-
*
|
|
144
|
+
* type Task = [string, number];
|
|
145
145
|
*
|
|
146
146
|
* function scheduleTasks(tasks: Task[], machines: number): Map<number, Task[]> {
|
|
147
147
|
* const machineHeap = new Heap<{ id: number; load: number }>([], { comparator: (a, b) => a.load - b.load }); // Min heap
|
|
@@ -21,7 +21,7 @@ const base_1 = require("../base");
|
|
|
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
22
|
* @example
|
|
23
23
|
* // Use Heap to sort an array
|
|
24
|
-
*
|
|
24
|
+
* function heapSort(arr: number[]): number[] {
|
|
25
25
|
* const heap = new Heap<number>(arr, { comparator: (a, b) => a - b });
|
|
26
26
|
* const sorted: number[] = [];
|
|
27
27
|
* while (!heap.isEmpty()) {
|
|
@@ -34,7 +34,7 @@ const base_1 = require("../base");
|
|
|
34
34
|
* console.log(heapSort(array)); // [1, 2, 3, 4, 5, 8]
|
|
35
35
|
* @example
|
|
36
36
|
* // Use Heap to solve top k problems
|
|
37
|
-
*
|
|
37
|
+
* function topKElements(arr: number[], k: number): number[] {
|
|
38
38
|
* const heap = new Heap<number>([], { comparator: (a, b) => b - a }); // Max heap
|
|
39
39
|
* arr.forEach(num => {
|
|
40
40
|
* heap.add(num);
|
|
@@ -47,7 +47,7 @@ const base_1 = require("../base");
|
|
|
47
47
|
* console.log(topKElements(numbers, 3)); // [15, 10, 5]
|
|
48
48
|
* @example
|
|
49
49
|
* // Use Heap to merge sorted sequences
|
|
50
|
-
*
|
|
50
|
+
* function mergeSortedSequences(sequences: number[][]): number[] {
|
|
51
51
|
* const heap = new Heap<{ value: number; seqIndex: number; itemIndex: number }>([], {
|
|
52
52
|
* comparator: (a, b) => a.value - b.value // Min heap
|
|
53
53
|
* });
|
|
@@ -84,7 +84,7 @@ const base_1 = require("../base");
|
|
|
84
84
|
* console.log(mergeSortedSequences(sequences)); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
85
85
|
* @example
|
|
86
86
|
* // Use Heap to dynamically maintain the median
|
|
87
|
-
*
|
|
87
|
+
* class MedianFinder {
|
|
88
88
|
* private low: MaxHeap<number>; // Max heap, stores the smaller half
|
|
89
89
|
* private high: MinHeap<number>; // Min heap, stores the larger half
|
|
90
90
|
*
|
|
@@ -121,7 +121,7 @@ const base_1 = require("../base");
|
|
|
121
121
|
* console.log(medianFinder.findMedian()); // 30
|
|
122
122
|
* @example
|
|
123
123
|
* // Use Heap for load balancing
|
|
124
|
-
*
|
|
124
|
+
* function loadBalance(requests: number[], servers: number): number[] {
|
|
125
125
|
* const serverHeap = new Heap<{ id: number; load: number }>([], { comparator: (a, b) => a.load - b.load }); // min heap
|
|
126
126
|
* const serverLoads = new Array(servers).fill(0);
|
|
127
127
|
*
|
|
@@ -143,7 +143,7 @@ const base_1 = require("../base");
|
|
|
143
143
|
* console.log(loadBalance(requests, 3)); // [12, 8, 5]
|
|
144
144
|
* @example
|
|
145
145
|
* // Use Heap to schedule tasks
|
|
146
|
-
*
|
|
146
|
+
* type Task = [string, number];
|
|
147
147
|
*
|
|
148
148
|
* function scheduleTasks(tasks: Task[], machines: number): Map<number, Task[]> {
|
|
149
149
|
* const machineHeap = new Heap<{ id: number; load: number }>([], { comparator: (a, b) => a.load - b.load }); // Min heap
|