graph-typed 1.53.6 → 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 (44) hide show
  1. package/dist/common/index.d.ts +12 -0
  2. package/dist/common/index.js +23 -0
  3. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +7 -10
  4. package/dist/data-structures/binary-tree/avl-tree.js +2 -2
  5. package/dist/data-structures/binary-tree/binary-tree.d.ts +54 -19
  6. package/dist/data-structures/binary-tree/binary-tree.js +100 -66
  7. package/dist/data-structures/binary-tree/bst.d.ts +100 -36
  8. package/dist/data-structures/binary-tree/bst.js +185 -66
  9. package/dist/data-structures/binary-tree/rb-tree.d.ts +4 -0
  10. package/dist/data-structures/binary-tree/rb-tree.js +6 -2
  11. package/dist/data-structures/binary-tree/tree-multi-map.js +2 -2
  12. package/dist/data-structures/heap/heap.d.ts +6 -6
  13. package/dist/data-structures/heap/heap.js +6 -6
  14. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +18 -8
  15. package/dist/data-structures/linked-list/doubly-linked-list.js +24 -10
  16. package/dist/data-structures/linked-list/singly-linked-list.d.ts +1 -1
  17. package/dist/data-structures/linked-list/singly-linked-list.js +1 -1
  18. package/dist/data-structures/trie/trie.d.ts +104 -4
  19. package/dist/data-structures/trie/trie.js +116 -12
  20. package/dist/index.d.ts +2 -1
  21. package/dist/index.js +2 -1
  22. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
  23. package/dist/types/data-structures/binary-tree/bst.d.ts +3 -2
  24. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +1 -1
  25. package/dist/types/utils/utils.d.ts +10 -6
  26. package/dist/utils/utils.js +4 -2
  27. package/package.json +2 -2
  28. package/src/common/index.ts +19 -0
  29. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +7 -9
  30. package/src/data-structures/binary-tree/avl-tree.ts +3 -2
  31. package/src/data-structures/binary-tree/binary-tree.ts +108 -64
  32. package/src/data-structures/binary-tree/bst.ts +190 -69
  33. package/src/data-structures/binary-tree/rb-tree.ts +6 -2
  34. package/src/data-structures/binary-tree/tree-multi-map.ts +3 -3
  35. package/src/data-structures/heap/heap.ts +39 -39
  36. package/src/data-structures/linked-list/doubly-linked-list.ts +111 -97
  37. package/src/data-structures/linked-list/singly-linked-list.ts +1 -1
  38. package/src/data-structures/trie/trie.ts +116 -11
  39. package/src/index.ts +2 -1
  40. package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
  41. package/src/types/data-structures/binary-tree/bst.ts +3 -2
  42. package/src/types/data-structures/binary-tree/rb-tree.ts +1 -1
  43. package/src/types/utils/utils.ts +16 -10
  44. package/src/utils/utils.ts +4 -2
@@ -5,9 +5,10 @@
5
5
  * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
6
6
  * @license MIT License
7
7
  */
8
- import type { BSTNested, BSTNodeNested, BSTNOptKeyOrNode, BSTOptions, BTNRep, Comparator, CP, DFSOrderPattern, IterationType, NodeCallback, NodePredicate, OptNode } from '../../types';
8
+ import type { BSTNested, BSTNodeNested, BSTNOptKeyOrNode, BSTOptions, BTNRep, Comparable, Comparator, CP, DFSOrderPattern, IterationType, NodeCallback, NodePredicate, OptNode } from '../../types';
9
9
  import { BinaryTree, BinaryTreeNode } from './binary-tree';
10
10
  import { IBinaryTree } from '../../interfaces';
11
+ import { Range } from '../../common';
11
12
  export declare class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNodeNested<K, V>> extends BinaryTreeNode<K, V, NODE> {
12
13
  parent?: NODE;
13
14
  constructor(key: K, value?: V);
@@ -45,6 +46,54 @@ export declare class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE>
45
46
  * 5. Logarithmic Operations: Ideal operations like insertion, deletion, and searching are O(log n) time-efficient.
46
47
  * 6. Balance Variability: Can become unbalanced; special types maintain balance.
47
48
  * 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.
49
+ * @example
50
+ * // Find kth smallest element
51
+ * // Create a BST with some elements
52
+ * const bst = new BST<number>([5, 3, 7, 1, 4, 6, 8]);
53
+ * const sortedKeys = bst.dfs(node => node.key, 'IN');
54
+ *
55
+ * // Helper function to find kth smallest
56
+ * const findKthSmallest = (k: number): number | undefined => {
57
+ * return sortedKeys[k - 1];
58
+ * };
59
+ *
60
+ * // Assertions
61
+ * console.log(findKthSmallest(1)); // 1
62
+ * console.log(findKthSmallest(3)); // 4
63
+ * console.log(findKthSmallest(7)); // 8
64
+ * @example
65
+ * // Find elements in a range
66
+ * const bst = new BST<number>([10, 5, 15, 3, 7, 12, 18]);
67
+ * console.log(bst.search(new Range(5, 10))); // [10, 5, 7]
68
+ * console.log(bst.search(new Range(4, 12))); // [10, 12, 5, 7]
69
+ * console.log(bst.search(new Range(4, 12, true, false))); // [10, 5, 7]
70
+ * console.log(bst.search(new Range(15, 20))); // [15, 18]
71
+ * console.log(bst.search(new Range(15, 20, false))); // [18]
72
+ * @example
73
+ * // Find lowest common ancestor
74
+ * const bst = new BST<number>([20, 10, 30, 5, 15, 25, 35, 3, 7, 12, 18]);
75
+ *
76
+ * function findFirstCommon(arr1: number[], arr2: number[]): number | undefined {
77
+ * for (const num of arr1) {
78
+ * if (arr2.indexOf(num) !== -1) {
79
+ * return num;
80
+ * }
81
+ * }
82
+ * return undefined;
83
+ * }
84
+ *
85
+ * // LCA helper function
86
+ * const findLCA = (num1: number, num2: number): number | undefined => {
87
+ * const path1 = bst.getPathToRoot(num1);
88
+ * const path2 = bst.getPathToRoot(num2);
89
+ * // Find the first common ancestor
90
+ * return findFirstCommon(path1, path2);
91
+ * };
92
+ *
93
+ * // Assertions
94
+ * console.log(findLCA(3, 10)); // 7
95
+ * console.log(findLCA(5, 35)); // 15
96
+ * console.log(findLCA(20, 30)); // 25
48
97
  */
49
98
  export declare class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE> = BSTNode<K, V, BSTNodeNested<K, V>>, TREE extends BST<K, V, R, NODE, TREE> = BST<K, V, R, NODE, BSTNested<K, V, R, NODE>>> extends BinaryTree<K, V, R, NODE, TREE> implements IBinaryTree<K, V, R, NODE, TREE> {
50
99
  /**
@@ -62,6 +111,13 @@ export declare class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V
62
111
  * @returns The `_root` property of the object, which is of type `NODE` or `undefined`.
63
112
  */
64
113
  get root(): OptNode<NODE>;
114
+ protected _isReverse: boolean;
115
+ /**
116
+ * The above function is a getter method in TypeScript that returns the value of the private property
117
+ * `_isReverse`.
118
+ * @returns The `isReverse` property of the object, which is a boolean value.
119
+ */
120
+ get isReverse(): boolean;
65
121
  /**
66
122
  * The function creates a new BSTNode with the given key and value and returns it.
67
123
  * @param {K} key - The key parameter is of type K, which represents the type of the key for the node
@@ -118,7 +174,7 @@ export declare class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V
118
174
  * @param {any} key - The `key` parameter is a value that will be checked to determine if it is of
119
175
  * type `K`.
120
176
  * @returns The `override isKey(key: any): key is K` function is returning a boolean value based on
121
- * the result of the `isComparable` function with the condition `this.comparator !==
177
+ * the result of the `isComparable` function with the condition `this._compare !==
122
178
  * this._DEFAULT_COMPARATOR`.
123
179
  */
124
180
  isKey(key: any): key is K;
@@ -156,30 +212,45 @@ export declare class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V
156
212
  * successfully inserted into the data structure.
157
213
  */
158
214
  addMany(keysNodesEntriesOrRaws: Iterable<R | BTNRep<K, V, NODE>>, values?: Iterable<V | undefined>, isBalanceAdd?: boolean, iterationType?: IterationType): boolean[];
215
+ /**
216
+ * Time Complexity: O(n)
217
+ * Space Complexity: O(1)
218
+ *
219
+ * The `merge` function overrides the base class method by adding elements from another
220
+ * binary search tree.
221
+ * @param anotherTree - `anotherTree` is an instance of a Binary Search Tree (BST) with key type `K`,
222
+ * value type `V`, return type `R`, node type `NODE`, and tree type `TREE`.
223
+ */
224
+ merge(anotherTree: BST<K, V, R, NODE, TREE>): void;
159
225
  /**
160
226
  * Time Complexity: O(log n)
161
227
  * Space Complexity: O(k + log n)
162
228
  *
163
- * The function `getNodes` in TypeScript overrides the base class method to retrieve nodes based on a
164
- * given keyNodeEntryRawOrPredicate and iteration type.
165
- * @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate - The `keyNodeEntryRawOrPredicate`
166
- * parameter in the `getNodes` method is used to filter the nodes that will be returned. It can be a
167
- * key, a node, an entry, or a custom keyNodeEntryRawOrPredicate function that determines whether a node should be
168
- * included in the result.
169
- * @param [onlyOne=false] - The `onlyOne` parameter in the `getNodes` method is a boolean flag that
170
- * determines whether to return only the first node that matches the keyNodeEntryRawOrPredicate (`true`) or all nodes
171
- * that match the keyNodeEntryRawOrPredicate (`false`). If `onlyOne` is set to `true`, the method will stop iterating
172
- * and
173
- * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the
174
- * `getNodes` method is used to specify the starting point for traversing the tree when searching for
175
- * nodes that match a given keyNodeEntryRawOrPredicate. It represents the root node of the subtree where the search
176
- * should begin. If not explicitly provided, the default value for `begin
177
- * @param {IterationType} iterationType - The `iterationType` parameter in the `getNodes` method
178
- * specifies the type of iteration to be performed when traversing the nodes of a binary tree. It can
179
- * have two possible values:
180
- * @returns The `getNodes` method returns an array of nodes that satisfy the given keyNodeEntryRawOrPredicate.
229
+ * The function `search` in TypeScript overrides the search behavior in a binary tree structure based
230
+ * on specified criteria.
231
+ * @param {BTNRep<K, V, NODE> | R | NodePredicate<NODE>} keyNodeEntryRawOrPredicate - The
232
+ * `keyNodeEntryRawOrPredicate` parameter in the `override search` method can accept one of the
233
+ * following types:
234
+ * @param [onlyOne=false] - The `onlyOne` parameter is a boolean flag that determines whether the
235
+ * search should stop after finding the first matching node. If `onlyOne` is set to `true`, the
236
+ * search will return as soon as a matching node is found. If `onlyOne` is set to `false`, the
237
+ * @param {C} callback - The `callback` parameter in the `override search` function is a function
238
+ * that will be called on each node that matches the search criteria. It is of type `C`, which
239
+ * extends `NodeCallback<NODE>`. The callback function should accept a node of type `NODE` as its
240
+ * argument and
241
+ * @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `override search`
242
+ * method represents the node from which the search operation will begin. It is the starting point
243
+ * for searching within the tree data structure. The method ensures that the `startNode` is a valid
244
+ * node before proceeding with the search operation. If the `
245
+ * @param {IterationType} iterationType - The `iterationType` parameter in the `override search`
246
+ * function determines the type of iteration to be used during the search operation. It can have two
247
+ * possible values:
248
+ * @returns The `override search` method returns an array of values that match the search criteria
249
+ * specified by the input parameters. The method performs a search operation on a binary tree
250
+ * structure based on the provided key, predicate, and other options. The search results are
251
+ * collected in an array and returned as the output of the method.
181
252
  */
182
- getNodes(keyNodeEntryRawOrPredicate: BTNRep<K, V, NODE> | R | NodePredicate<NODE>, onlyOne?: boolean, startNode?: BTNRep<K, V, NODE> | R, iterationType?: IterationType): NODE[];
253
+ search<C extends NodeCallback<NODE>>(keyNodeEntryRawOrPredicate: BTNRep<K, V, NODE> | R | NodePredicate<NODE> | Range<K>, onlyOne?: boolean, callback?: C, startNode?: BTNRep<K, V, NODE> | R, iterationType?: IterationType): ReturnType<C>[];
183
254
  /**
184
255
  * Time Complexity: O(log n)
185
256
  * Space Complexity: O(1)
@@ -201,20 +272,6 @@ export declare class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V
201
272
  * returns the first node found or `undefined` if no node is found.
202
273
  */
203
274
  getNode(keyNodeEntryRawOrPredicate: BTNRep<K, V, NODE> | R | NodePredicate<NODE>, startNode?: R | BSTNOptKeyOrNode<K, NODE>, iterationType?: IterationType): OptNode<NODE>;
204
- /**
205
- * Time Complexity: O(log n)
206
- * Space Complexity: O(1)
207
- *
208
- * The function `getNodeByKey` returns a node with a specific key from a tree data structure.
209
- * @param {K} key - The key parameter is the value used to search for a specific node in the tree. It
210
- * is typically a unique identifier or a value that can be used to determine the position of the node
211
- * in the tree structure.
212
- * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional
213
- * parameter that specifies the type of iteration to be used when searching for a node in the tree.
214
- * It has a default value of `'ITERATIVE'`.
215
- * @returns The method is returning a NODE object or undefined.
216
- */
217
- getNodeByKey(key: K, iterationType?: IterationType): OptNode<NODE>;
218
275
  /**
219
276
  * Time complexity: O(n)
220
277
  * Space complexity: O(n)
@@ -321,17 +378,24 @@ export declare class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V
321
378
  * @returns a boolean value.
322
379
  */
323
380
  isAVLBalanced(iterationType?: IterationType): boolean;
324
- protected _DEFAULT_COMPARATOR: (a: K, b: K) => number;
325
381
  protected _comparator: Comparator<K>;
326
382
  /**
327
383
  * The function returns the value of the _comparator property.
328
384
  * @returns The `_comparator` property is being returned.
329
385
  */
330
386
  get comparator(): Comparator<K>;
387
+ protected _extractComparable?: (key: K) => Comparable;
388
+ /**
389
+ * This function returns the value of the `_extractComparable` property.
390
+ * @returns The method `extractComparable()` is being returned, which is a getter method for the
391
+ * `_extractComparable` property.
392
+ */
393
+ get extractComparable(): ((key: K) => Comparable) | undefined;
331
394
  /**
332
395
  * The function sets the root of a tree-like structure and updates the parent property of the new
333
396
  * root.
334
397
  * @param {OptNode<NODE>} v - v is a parameter of type NODE or undefined.
335
398
  */
336
399
  protected _setRoot(v: OptNode<NODE>): void;
400
+ protected _compare(a: K, b: K): number;
337
401
  }
@@ -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
  }