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.
Files changed (45) hide show
  1. package/README.md +136 -171
  2. package/dist/common/index.d.ts +12 -0
  3. package/dist/common/index.js +23 -0
  4. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +7 -10
  5. package/dist/data-structures/binary-tree/avl-tree.js +2 -2
  6. package/dist/data-structures/binary-tree/binary-tree.d.ts +54 -19
  7. package/dist/data-structures/binary-tree/binary-tree.js +100 -66
  8. package/dist/data-structures/binary-tree/bst.d.ts +100 -36
  9. package/dist/data-structures/binary-tree/bst.js +185 -66
  10. package/dist/data-structures/binary-tree/rb-tree.d.ts +4 -0
  11. package/dist/data-structures/binary-tree/rb-tree.js +6 -2
  12. package/dist/data-structures/binary-tree/tree-multi-map.js +2 -2
  13. package/dist/data-structures/heap/heap.d.ts +6 -6
  14. package/dist/data-structures/heap/heap.js +6 -6
  15. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +31 -19
  16. package/dist/data-structures/linked-list/doubly-linked-list.js +49 -34
  17. package/dist/data-structures/linked-list/singly-linked-list.d.ts +144 -62
  18. package/dist/data-structures/linked-list/singly-linked-list.js +201 -97
  19. package/dist/data-structures/trie/trie.d.ts +104 -4
  20. package/dist/data-structures/trie/trie.js +116 -12
  21. package/dist/index.d.ts +2 -1
  22. package/dist/index.js +2 -1
  23. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
  24. package/dist/types/data-structures/binary-tree/bst.d.ts +3 -2
  25. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +1 -1
  26. package/dist/types/utils/utils.d.ts +10 -6
  27. package/dist/utils/utils.js +4 -2
  28. package/package.json +2 -2
  29. package/src/common/index.ts +19 -0
  30. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +7 -9
  31. package/src/data-structures/binary-tree/avl-tree.ts +3 -2
  32. package/src/data-structures/binary-tree/binary-tree.ts +108 -64
  33. package/src/data-structures/binary-tree/bst.ts +190 -69
  34. package/src/data-structures/binary-tree/rb-tree.ts +6 -2
  35. package/src/data-structures/binary-tree/tree-multi-map.ts +3 -3
  36. package/src/data-structures/heap/heap.ts +39 -39
  37. package/src/data-structures/linked-list/doubly-linked-list.ts +139 -121
  38. package/src/data-structures/linked-list/singly-linked-list.ts +219 -98
  39. package/src/data-structures/trie/trie.ts +116 -11
  40. package/src/index.ts +2 -1
  41. package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
  42. package/src/types/data-structures/binary-tree/bst.ts +3 -2
  43. package/src/types/data-structures/binary-tree/rb-tree.ts +1 -1
  44. package/src/types/utils/utils.ts +16 -10
  45. 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._DEFAULT_COMPARATOR = (a, b) => {
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 comparator must be defined in the constructor's options parameter.`);
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 { comparator } = options;
87
- if (comparator)
88
- this._comparator = comparator;
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, comparator: this._comparator, toEntryFn: this._toEntryFn }, options));
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.comparator !==
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.comparator !== this._DEFAULT_COMPARATOR);
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.comparator(current.key, newNode.key) === 0) {
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.comparator(current.key, newNode.key) > 0) {
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.comparator(keyA, keyB);
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 `getNodes` in TypeScript overrides the base class method to retrieve nodes based on a
336
- * given keyNodeEntryRawOrPredicate and iteration type.
337
- * @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate - The `keyNodeEntryRawOrPredicate`
338
- * parameter in the `getNodes` method is used to filter the nodes that will be returned. It can be a
339
- * key, a node, an entry, or a custom keyNodeEntryRawOrPredicate function that determines whether a node should be
340
- * included in the result.
341
- * @param [onlyOne=false] - The `onlyOne` parameter in the `getNodes` method is a boolean flag that
342
- * determines whether to return only the first node that matches the keyNodeEntryRawOrPredicate (`true`) or all nodes
343
- * that match the keyNodeEntryRawOrPredicate (`false`). If `onlyOne` is set to `true`, the method will stop iterating
344
- * and
345
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
346
- * `getNodes` method is used to specify the starting point for traversing the tree when searching for
347
- * nodes that match a given keyNodeEntryRawOrPredicate. It represents the root node of the subtree where the search
348
- * should begin. If not explicitly provided, the default value for `begin
349
- * @param {IterationType} iterationType - The `iterationType` parameter in the `getNodes` method
350
- * specifies the type of iteration to be performed when traversing the nodes of a binary tree. It can
351
- * have two possible values:
352
- * @returns The `getNodes` method returns an array of nodes that satisfy the given keyNodeEntryRawOrPredicate.
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
- getNodes(keyNodeEntryRawOrPredicate, onlyOne = false, startNode = this._root, iterationType = this.iterationType) {
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
- const callback = this._ensurePredicate(keyNodeEntryRawOrPredicate);
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 (callback(cur)) {
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 (!this._isPredicate(keyNodeEntryRawOrPredicate)) {
374
- const benchmarkKey = this._getKey(keyNodeEntryRawOrPredicate);
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.comparator(cur.key, benchmarkKey) > 0)
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.comparator(cur.key, benchmarkKey) < 0)
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 (callback(cur)) {
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 (!this._isPredicate(keyNodeEntryRawOrPredicate)) {
405
- const benchmarkKey = this._getKey(keyNodeEntryRawOrPredicate);
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.comparator(cur.key, benchmarkKey) < 0)
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.comparator(cur.key, benchmarkKey) > 0)
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.comparator(cur.key, targetKey);
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.comparator(cur.key, targetKey);
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, comparator: this._comparator, toEntryFn: this._toEntryFn }, options));
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.comparator(node.key, current.key);
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, comparator: this._comparator, toEntryFn: this._toEntryFn }, options));
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._toEntryFn) {
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
- * function heapSort(arr: number[]): number[] {
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
- * function topKElements(arr: number[], k: number): number[] {
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
- * function mergeSortedSequences(sequences: number[][]): number[] {
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
- * class MedianFinder {
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
- * function loadBalance(requests: number[], servers: number): number[] {
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
- * type Task = [string, number];
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
- * function heapSort(arr: number[]): number[] {
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
- * function topKElements(arr: number[], k: number): number[] {
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
- * function mergeSortedSequences(sequences: number[][]): number[] {
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
- * class MedianFinder {
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
- * function loadBalance(requests: number[], servers: number): number[] {
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
- * type Task = [string, number];
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