graph-typed 1.48.2 → 1.48.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/data-structures/binary-tree/avl-tree.d.ts +16 -16
  2. package/dist/data-structures/binary-tree/avl-tree.js +7 -7
  3. package/dist/data-structures/binary-tree/binary-tree.d.ts +89 -87
  4. package/dist/data-structures/binary-tree/binary-tree.js +67 -58
  5. package/dist/data-structures/binary-tree/bst.d.ts +28 -47
  6. package/dist/data-structures/binary-tree/bst.js +54 -57
  7. package/dist/data-structures/binary-tree/rb-tree.d.ts +15 -15
  8. package/dist/data-structures/binary-tree/rb-tree.js +7 -7
  9. package/dist/data-structures/binary-tree/tree-multimap.d.ts +22 -22
  10. package/dist/data-structures/binary-tree/tree-multimap.js +11 -11
  11. package/dist/data-structures/graph/abstract-graph.d.ts +1 -0
  12. package/dist/data-structures/graph/abstract-graph.js +4 -0
  13. package/dist/data-structures/graph/directed-graph.d.ts +25 -7
  14. package/dist/data-structures/graph/directed-graph.js +58 -12
  15. package/dist/data-structures/graph/undirected-graph.d.ts +25 -6
  16. package/dist/data-structures/graph/undirected-graph.js +70 -7
  17. package/dist/interfaces/binary-tree.d.ts +6 -6
  18. package/dist/types/common.d.ts +11 -8
  19. package/dist/types/common.js +6 -1
  20. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +3 -3
  21. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +4 -4
  22. package/dist/types/data-structures/binary-tree/bst.d.ts +6 -6
  23. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +3 -3
  24. package/dist/types/data-structures/binary-tree/tree-multimap.d.ts +3 -3
  25. package/package.json +2 -2
  26. package/src/data-structures/binary-tree/avl-tree.ts +20 -21
  27. package/src/data-structures/binary-tree/binary-tree.ts +147 -136
  28. package/src/data-structures/binary-tree/bst.ts +86 -82
  29. package/src/data-structures/binary-tree/rb-tree.ts +25 -26
  30. package/src/data-structures/binary-tree/tree-multimap.ts +30 -35
  31. package/src/data-structures/graph/abstract-graph.ts +5 -0
  32. package/src/data-structures/graph/directed-graph.ts +61 -12
  33. package/src/data-structures/graph/undirected-graph.ts +75 -7
  34. package/src/interfaces/binary-tree.ts +5 -6
  35. package/src/types/common.ts +11 -8
  36. package/src/types/data-structures/binary-tree/avl-tree.ts +3 -3
  37. package/src/types/data-structures/binary-tree/binary-tree.ts +6 -5
  38. package/src/types/data-structures/binary-tree/bst.ts +6 -6
  39. package/src/types/data-structures/binary-tree/rb-tree.ts +3 -3
  40. package/src/types/data-structures/binary-tree/tree-multimap.ts +3 -3
@@ -11,20 +11,18 @@ import type {
11
11
  BSTNodeNested,
12
12
  BSTOptions,
13
13
  BTNCallback,
14
- BTNKey,
15
14
  BTNodeExemplar,
16
- BTNodePureExemplar,
17
- Comparator
15
+ BTNodePureExemplar
18
16
  } from '../../types';
19
- import { CP, IterationType } from '../../types';
17
+ import { BSTVariant, CP, IterationType } from '../../types';
20
18
  import { BinaryTree, BinaryTreeNode } from './binary-tree';
21
19
  import { IBinaryTree } from '../../interfaces';
22
20
  import { Queue } from '../queue';
23
21
 
24
- export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extends BinaryTreeNode<V, N> {
22
+ export class BSTNode<K = any, V = any, N extends BSTNode<K, V, N> = BSTNodeNested<K, V>> extends BinaryTreeNode<K, V, N> {
25
23
  override parent?: N;
26
24
 
27
- constructor(key: BTNKey, value?: V) {
25
+ constructor(key: K, value?: V) {
28
26
  super(key, value);
29
27
  this.parent = undefined;
30
28
  this._left = undefined;
@@ -81,9 +79,9 @@ export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extend
81
79
  * 6. Balance Variability: Can become unbalanced; special types maintain balance.
82
80
  * 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.
83
81
  */
84
- export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>, TREE extends BST<V, N, TREE> = BST<V, N, BSTNested<V, N>>>
85
- extends BinaryTree<V, N, TREE>
86
- implements IBinaryTree<V, N, TREE> {
82
+ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BSTNodeNested<K, V>>, TREE extends BST<K, V, N, TREE> = BST<K, V, N, BSTNested<K, V, N>>>
83
+ extends BinaryTree<K, V, N, TREE>
84
+ implements IBinaryTree<K, V, N, TREE> {
87
85
 
88
86
 
89
87
  /**
@@ -94,13 +92,13 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
94
92
  * @param [options] - The `options` parameter is an optional object that can contain additional
95
93
  * configuration options for the binary search tree. It can have the following properties:
96
94
  */
97
- constructor(elements?: Iterable<BTNodeExemplar<V, N>>, options?: Partial<BSTOptions>) {
95
+ constructor(elements?: Iterable<BTNodeExemplar<K, V, N>>, options?: Partial<BSTOptions<K>>) {
98
96
  super([], options);
99
97
 
100
98
  if (options) {
101
- const { comparator } = options;
102
- if (comparator) {
103
- this.comparator = comparator;
99
+ const { variant } = options;
100
+ if (variant) {
101
+ this._variant = variant;
104
102
  }
105
103
  }
106
104
 
@@ -115,18 +113,22 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
115
113
  return this._root;
116
114
  }
117
115
 
118
- comparator: Comparator<BTNKey> = (a, b) => a - b
116
+ protected _variant = BSTVariant.MIN
117
+
118
+ get variant() {
119
+ return this._variant;
120
+ }
119
121
 
120
122
  /**
121
123
  * The function creates a new binary search tree node with the given key and value.
122
- * @param {BTNKey} key - The key parameter is the key value that will be associated with
124
+ * @param {K} key - The key parameter is the key value that will be associated with
123
125
  * the new node. It is used to determine the position of the node in the binary search tree.
124
126
  * @param [value] - The parameter `value` is an optional value that can be assigned to the node. It
125
127
  * represents the value associated with the node in a binary search tree.
126
128
  * @returns a new instance of the BSTNode class with the specified key and value.
127
129
  */
128
- override createNode(key: BTNKey, value?: V): N {
129
- return new BSTNode<V, N>(key, value) as N;
130
+ override createNode(key: K, value?: V): N {
131
+ return new BSTNode<K, V, N>(key, value) as N;
130
132
  }
131
133
 
132
134
  /**
@@ -136,29 +138,29 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
136
138
  * that defines various options for creating a binary search tree.
137
139
  * @returns a new instance of the BST class with the specified options.
138
140
  */
139
- override createTree(options?: Partial<BSTOptions>): TREE {
140
- return new BST<V, N, TREE>([], {
141
+ override createTree(options?: Partial<BSTOptions<K>>): TREE {
142
+ return new BST<K, V, N, TREE>([], {
141
143
  iterationType: this.iterationType,
142
- comparator: this.comparator, ...options
144
+ variant: this.variant, ...options
143
145
  }) as TREE;
144
146
  }
145
147
 
146
148
  /**
147
149
  * The function checks if an exemplar is an instance of BSTNode.
148
- * @param exemplar - The `exemplar` parameter is a variable of type `BTNodeExemplar<V, N>`.
150
+ * @param exemplar - The `exemplar` parameter is a variable of type `BTNodeExemplar<K, V, N>`.
149
151
  * @returns a boolean value indicating whether the exemplar is an instance of the BSTNode class.
150
152
  */
151
- override isNode(exemplar: BTNodeExemplar<V, N>): exemplar is N {
153
+ override isNode(exemplar: BTNodeExemplar<K, V, N>): exemplar is N {
152
154
  return exemplar instanceof BSTNode;
153
155
  }
154
156
 
155
157
  /**
156
158
  * The function `exemplarToNode` takes an exemplar and returns a corresponding node if the exemplar
157
159
  * is valid, otherwise it returns undefined.
158
- * @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<V, N>`.
160
+ * @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<K, V, N>`.
159
161
  * @returns a variable `node` which is of type `N` or `undefined`.
160
162
  */
161
- override exemplarToNode(exemplar: BTNodeExemplar<V, N>): N | undefined {
163
+ override exemplarToNode(exemplar: BTNodeExemplar<K, V, N>): N | undefined {
162
164
  let node: N | undefined;
163
165
  if (exemplar === null || exemplar === undefined) {
164
166
  return;
@@ -171,7 +173,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
171
173
  } else {
172
174
  node = this.createNode(key, value);
173
175
  }
174
- } else if (this.isNodeKey(exemplar)) {
176
+ } else if (this.isNotNodeInstance(exemplar)) {
175
177
  node = this.createNode(exemplar);
176
178
  } else {
177
179
  return;
@@ -194,7 +196,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
194
196
  * @returns The method returns either the newly added node (`newNode`) or `undefined` if the input
195
197
  * (`keyOrNodeOrEntry`) is null, undefined, or does not match any of the expected types.
196
198
  */
197
- override add(keyOrNodeOrEntry: BTNodeExemplar<V, N>): N | undefined {
199
+ override add(keyOrNodeOrEntry: BTNodeExemplar<K, V, N>): N | undefined {
198
200
  const newNode = this.exemplarToNode(keyOrNodeOrEntry);
199
201
  if (newNode === undefined) return;
200
202
 
@@ -262,7 +264,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
262
264
  * @returns The `addMany` function returns an array of `N` or `undefined` values.
263
265
  */
264
266
  override addMany(
265
- keysOrNodesOrEntries: Iterable<BTNodeExemplar<V, N>>,
267
+ keysOrNodesOrEntries: Iterable<BTNodeExemplar<K, V, N>>,
266
268
  isBalanceAdd = true,
267
269
  iterationType = this.iterationType
268
270
  ): (N | undefined)[] {
@@ -274,9 +276,9 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
274
276
  }
275
277
  return inserted;
276
278
  }
277
- const realBTNExemplars: BTNodePureExemplar<V, N>[] = [];
279
+ const realBTNExemplars: BTNodePureExemplar<K, V, N>[] = [];
278
280
 
279
- const isRealBTNExemplar = (kve: BTNodeExemplar<V, N>): kve is BTNodePureExemplar<V, N> => {
281
+ const isRealBTNExemplar = (kve: BTNodeExemplar<K, V, N>): kve is BTNodePureExemplar<K, V, N> => {
280
282
  if (kve === undefined || kve === null) return false;
281
283
  return !(this.isEntry(kve) && (kve[0] === undefined || kve[0] === null));
282
284
  }
@@ -286,23 +288,23 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
286
288
  }
287
289
 
288
290
  // TODO this addMany function is inefficient, it should be optimized
289
- let sorted: BTNodePureExemplar<V, N>[] = [];
291
+ let sorted: BTNodePureExemplar<K, V, N>[] = [];
290
292
 
291
293
  sorted = realBTNExemplars.sort((a, b) => {
292
294
  let aR: number, bR: number;
293
- if (this.isEntry(a)) aR = a[0]
294
- else if (this.isRealNode(a)) aR = a.key
295
- else aR = a;
295
+ if (this.isEntry(a)) aR = this.extractor(a[0])
296
+ else if (this.isRealNode(a)) aR = this.extractor(a.key)
297
+ else aR = this.extractor(a);
296
298
 
297
- if (this.isEntry(b)) bR = b[0]
298
- else if (this.isRealNode(b)) bR = b.key
299
- else bR = b;
299
+ if (this.isEntry(b)) bR = this.extractor(b[0])
300
+ else if (this.isRealNode(b)) bR = this.extractor(b.key)
301
+ else bR = this.extractor(b);
300
302
 
301
303
  return aR - bR;
302
304
  })
303
305
 
304
306
 
305
- const _dfs = (arr: BTNodePureExemplar<V, N>[]) => {
307
+ const _dfs = (arr: BTNodePureExemplar<K, V, N>[]) => {
306
308
  if (arr.length === 0) return;
307
309
 
308
310
  const mid = Math.floor((arr.length - 1) / 2);
@@ -337,31 +339,31 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
337
339
  return inserted;
338
340
  }
339
341
 
340
- /**
341
- * Time Complexity: O(n log n) - Adding each element individually in a balanced tree.
342
- * Space Complexity: O(n) - Additional space is required for the sorted array.
343
- */
344
-
345
- /**
346
- * Time Complexity: O(log n) - Average case for a balanced tree.
347
- * Space Complexity: O(1) - Constant space is used.
348
- *
349
- * The `lastKey` function returns the key of the rightmost node in a binary tree, or the key of the
350
- * leftmost node if the comparison result is greater than.
351
- * @param {BTNKey | N | undefined} beginRoot - The `beginRoot` parameter is optional and can be of
352
- * type `BTNKey`, `N`, or `undefined`. It represents the starting point for finding the last key in
353
- * the binary tree. If not provided, it defaults to the root of the binary tree (`this.root`).
354
- * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
355
- * be performed. It can have one of the following values:
356
- * @returns the key of the rightmost node in the binary tree if the comparison result is less than,
357
- * the key of the leftmost node if the comparison result is greater than, and the key of the
358
- * rightmost node otherwise. If no node is found, it returns 0.
359
- */
360
- lastKey(beginRoot: BSTNodeKeyOrNode<N> = this.root, iterationType = this.iterationType): BTNKey {
361
- if (this._compare(0, 1) === CP.lt) return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
362
- else if (this._compare(0, 1) === CP.gt) return this.getLeftMost(beginRoot, iterationType)?.key ?? 0;
363
- else return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
364
- }
342
+ // /**
343
+ // * Time Complexity: O(n log n) - Adding each element individually in a balanced tree.
344
+ // * Space Complexity: O(n) - Additional space is required for the sorted array.
345
+ // */
346
+ //
347
+ // /**
348
+ // * Time Complexity: O(log n) - Average case for a balanced tree.
349
+ // * Space Complexity: O(1) - Constant space is used.
350
+ // *
351
+ // * The `lastKey` function returns the key of the rightmost node in a binary tree, or the key of the
352
+ // * leftmost node if the comparison result is greater than.
353
+ // * @param {K | N | undefined} beginRoot - The `beginRoot` parameter is optional and can be of
354
+ // * type `K`, `N`, or `undefined`. It represents the starting point for finding the last key in
355
+ // * the binary tree. If not provided, it defaults to the root of the binary tree (`this.root`).
356
+ // * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
357
+ // * be performed. It can have one of the following values:
358
+ // * @returns the key of the rightmost node in the binary tree if the comparison result is less than,
359
+ // * the key of the leftmost node if the comparison result is greater than, and the key of the
360
+ // * rightmost node otherwise. If no node is found, it returns 0.
361
+ // */
362
+ // lastKey(beginRoot: BSTNodeKeyOrNode<K,N> = this.root, iterationType = this.iterationType): K {
363
+ // if (this._compare(0, 1) === CP.lt) return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
364
+ // else if (this._compare(0, 1) === CP.gt) return this.getLeftMost(beginRoot, iterationType)?.key ?? 0;
365
+ // else return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
366
+ // }
365
367
 
366
368
  /**
367
369
  * Time Complexity: O(log n) - Average case for a balanced tree.
@@ -374,7 +376,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
374
376
  *
375
377
  * The function `getNodeByKey` searches for a node in a binary tree based on a given key, using
376
378
  * either recursive or iterative methods.
377
- * @param {BTNKey} key - The `key` parameter is the key value that we are searching for in the tree.
379
+ * @param {K} key - The `key` parameter is the key value that we are searching for in the tree.
378
380
  * It is used to identify the node that we want to retrieve.
379
381
  * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
380
382
  * type of iteration to use when searching for a node in the binary tree. It can have two possible
@@ -382,7 +384,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
382
384
  * @returns The function `getNodeByKey` returns a node (`N`) if a node with the specified key is
383
385
  * found in the binary tree. If no node is found, it returns `undefined`.
384
386
  */
385
- override getNodeByKey(key: BTNKey, iterationType = IterationType.ITERATIVE): N | undefined {
387
+ override getNodeByKey(key: K, iterationType = IterationType.ITERATIVE): N | undefined {
386
388
  if (!this.root) return undefined;
387
389
  if (iterationType === IterationType.RECURSIVE) {
388
390
  const _dfs = (cur: N): N | undefined => {
@@ -415,14 +417,14 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
415
417
  /**
416
418
  * The function `ensureNode` returns the node corresponding to the given key if it is a node key,
417
419
  * otherwise it returns the key itself.
418
- * @param {BTNKey | N | undefined} key - The `key` parameter can be of type `BTNKey`, `N`, or
420
+ * @param {K | N | undefined} key - The `key` parameter can be of type `K`, `N`, or
419
421
  * `undefined`.
420
422
  * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
421
423
  * type of iteration to be performed. It has a default value of `IterationType.ITERATIVE`.
422
424
  * @returns either a node object (N) or undefined.
423
425
  */
424
- override ensureNode(key: BSTNodeKeyOrNode<N>, iterationType = IterationType.ITERATIVE): N | undefined {
425
- return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key;
426
+ override ensureNode(key: BSTNodeKeyOrNode<K, N>, iterationType = IterationType.ITERATIVE): N | undefined {
427
+ return this.isNotNodeInstance(key) ? this.getNodeByKey(key, iterationType) : key;
426
428
  }
427
429
 
428
430
  /**
@@ -441,7 +443,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
441
443
  * first node that matches the identifier. If set to true, the function will return an array
442
444
  * containing only the first matching node. If set to false (default), the function will continue
443
445
  * searching for all nodes that match the identifier and return an array containing
444
- * @param {BTNKey | N | undefined} beginRoot - The `beginRoot` parameter represents the starting node
446
+ * @param {K | N | undefined} beginRoot - The `beginRoot` parameter represents the starting node
445
447
  * for the traversal. It can be either a key value or a node object. If it is undefined, the
446
448
  * traversal will start from the root of the tree.
447
449
  * @param iterationType - The `iterationType` parameter determines the type of iteration to be
@@ -452,7 +454,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
452
454
  identifier: ReturnType<C> | undefined,
453
455
  callback: C = this._defaultOneParamCallback as C,
454
456
  onlyOne = false,
455
- beginRoot: BSTNodeKeyOrNode<N> = this.root,
457
+ beginRoot: BSTNodeKeyOrNode<K, N> = this.root,
456
458
  iterationType = this.iterationType
457
459
  ): N[] {
458
460
  beginRoot = this.ensureNode(beginRoot);
@@ -470,8 +472,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
470
472
  if (!cur.left && !cur.right) return;
471
473
  // TODO potential bug
472
474
  if (callback === this._defaultOneParamCallback) {
473
- if (this._compare(cur.key, identifier as number) === CP.gt) cur.left && _traverse(cur.left);
474
- if (this._compare(cur.key, identifier as number) === CP.lt) cur.right && _traverse(cur.right);
475
+ if (this._compare(cur.key, identifier as K) === CP.gt) cur.left && _traverse(cur.left);
476
+ if (this._compare(cur.key, identifier as K) === CP.lt) cur.right && _traverse(cur.right);
475
477
  } else {
476
478
  cur.left && _traverse(cur.left);
477
479
  cur.right && _traverse(cur.right);
@@ -491,8 +493,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
491
493
  }
492
494
  // TODO potential bug
493
495
  if (callback === this._defaultOneParamCallback) {
494
- if (this._compare(cur.key, identifier as number) === CP.gt) cur.left && queue.push(cur.left);
495
- if (this._compare(cur.key, identifier as number) === CP.lt) cur.right && queue.push(cur.right);
496
+ if (this._compare(cur.key, identifier as K) === CP.gt) cur.left && queue.push(cur.left);
497
+ if (this._compare(cur.key, identifier as K) === CP.lt) cur.right && queue.push(cur.right);
496
498
  } else {
497
499
  cur.left && queue.push(cur.left);
498
500
  cur.right && queue.push(cur.right);
@@ -522,7 +524,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
522
524
  * traverse nodes that are lesser than, greater than, or equal to the `targetNode`. It is of type
523
525
  * `CP`, which is a custom type representing the comparison operator. The possible values for
524
526
  * `lesserOrGreater` are
525
- * @param {BTNKey | N | undefined} targetNode - The `targetNode` parameter represents the node in the
527
+ * @param {K | N | undefined} targetNode - The `targetNode` parameter represents the node in the
526
528
  * binary tree that you want to traverse from. It can be specified either by its key, by the node
527
529
  * object itself, or it can be left undefined to start the traversal from the root of the tree.
528
530
  * @param iterationType - The `iterationType` parameter determines the type of traversal to be
@@ -533,7 +535,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
533
535
  lesserOrGreaterTraverse<C extends BTNCallback<N>>(
534
536
  callback: C = this._defaultOneParamCallback as C,
535
537
  lesserOrGreater: CP = CP.lt,
536
- targetNode: BSTNodeKeyOrNode<N> = this.root,
538
+ targetNode: BSTNodeKeyOrNode<K, N> = this.root,
537
539
  iterationType = this.iterationType
538
540
  ): ReturnType<C>[] {
539
541
  targetNode = this.ensureNode(targetNode);
@@ -704,15 +706,17 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
704
706
  /**
705
707
  * The function compares two values using a comparator function and returns whether the first value
706
708
  * is greater than, less than, or equal to the second value.
707
- * @param {BTNKey} a - The parameter "a" is of type BTNKey.
708
- * @param {BTNKey} b - The parameter "b" in the above code represents a BTNKey.
709
+ * @param {K} a - The parameter "a" is of type K.
710
+ * @param {K} b - The parameter "b" in the above code represents a K.
709
711
  * @returns a value of type CP (ComparisonResult). The possible return values are CP.gt (greater
710
712
  * than), CP.lt (less than), or CP.eq (equal).
711
713
  */
712
- protected _compare(a: BTNKey, b: BTNKey): CP {
713
- const compared = this.comparator(a, b);
714
- if (compared > 0) return CP.gt;
715
- else if (compared < 0) return CP.lt;
716
- else return CP.eq;
714
+ protected _compare(a: K, b: K): CP {
715
+ const extractedA = this.extractor(a);
716
+ const extractedB = this.extractor(b);
717
+ const compared = this.variant === BSTVariant.MIN ? extractedA - extractedB : extractedB - extractedA;
718
+
719
+ return compared > 0 ? CP.gt : compared < 0 ? CP.lt : CP.eq;
717
720
  }
721
+
718
722
  }
@@ -10,7 +10,6 @@ import {
10
10
  BiTreeDeleteResult,
11
11
  BSTNodeKeyOrNode,
12
12
  BTNCallback,
13
- BTNKey,
14
13
  BTNodeExemplar,
15
14
  IterationType,
16
15
  RBTNColor,
@@ -22,13 +21,13 @@ import { BST, BSTNode } from './bst';
22
21
  import { IBinaryTree } from '../../interfaces';
23
22
  import { BinaryTreeNode } from './binary-tree';
24
23
 
25
- export class RedBlackTreeNode<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTreeNodeNested<V>> extends BSTNode<
26
- V,
24
+ export class RedBlackTreeNode<K = any, V = any, N extends RedBlackTreeNode<K, V, N> = RedBlackTreeNodeNested<K, V>> extends BSTNode<
25
+ K, V,
27
26
  N
28
27
  > {
29
28
  color: RBTNColor;
30
29
 
31
- constructor(key: BTNKey, value?: V, color: RBTNColor = RBTNColor.BLACK) {
30
+ constructor(key: K, value?: V, color: RBTNColor = RBTNColor.BLACK) {
32
31
  super(key, value);
33
32
  this.color = color;
34
33
  }
@@ -41,15 +40,15 @@ export class RedBlackTreeNode<V = any, N extends RedBlackTreeNode<V, N> = RedBla
41
40
  * 4. Red nodes must have black children.
42
41
  * 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.
43
42
  */
44
- export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTreeNode<V, RedBlackTreeNodeNested<V>>, TREE extends RedBlackTree<V, N, TREE> = RedBlackTree<V, N, RedBlackTreeNested<V, N>>>
45
- extends BST<V, N, TREE>
46
- implements IBinaryTree<V, N, TREE> {
47
- Sentinel: N = new RedBlackTreeNode<V>(NaN) as unknown as N;
43
+ export class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>, TREE extends RedBlackTree<K, V, N, TREE> = RedBlackTree<K, V, N, RedBlackTreeNested<K, V, N>>>
44
+ extends BST<K, V, N, TREE>
45
+ implements IBinaryTree<K, V, N, TREE> {
46
+ Sentinel: N = new RedBlackTreeNode<K, V>(NaN as K) as unknown as N;
48
47
 
49
48
  /**
50
49
  * This is the constructor function for a Red-Black Tree data structure in TypeScript, which
51
50
  * initializes the tree with optional elements and options.
52
- * @param [elements] - The `elements` parameter is an optional iterable of `BTNodeExemplar<V, N>`
51
+ * @param [elements] - The `elements` parameter is an optional iterable of `BTNodeExemplar<K, V, N>`
53
52
  * objects. It represents the initial elements that will be added to the RBTree during its
54
53
  * construction. If this parameter is provided, the `addMany` method is called to add all the
55
54
  * elements to the
@@ -57,7 +56,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
57
56
  * behavior of the RBTree. It is of type `Partial<RBTreeOptions>`, which means that you can provide
58
57
  * only a subset of the properties defined in the `RBTreeOptions` interface.
59
58
  */
60
- constructor(elements?: Iterable<BTNodeExemplar<V, N>>, options?: Partial<RBTreeOptions>) {
59
+ constructor(elements?: Iterable<BTNodeExemplar<K, V, N>>, options?: Partial<RBTreeOptions<K>>) {
61
60
  super([], options);
62
61
 
63
62
  this._root = this.Sentinel;
@@ -78,7 +77,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
78
77
 
79
78
  /**
80
79
  * The function creates a new Red-Black Tree node with the specified key, value, and color.
81
- * @param {BTNKey} key - The key parameter is the key value associated with the node. It is used to
80
+ * @param {K} key - The key parameter is the key value associated with the node. It is used to
82
81
  * identify and compare nodes in the Red-Black Tree.
83
82
  * @param {V} [value] - The `value` parameter is an optional parameter that represents the value
84
83
  * associated with the node. It is of type `V`, which is a generic type that can be replaced with any
@@ -88,8 +87,8 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
88
87
  * @returns The method is returning a new instance of a RedBlackTreeNode with the specified key,
89
88
  * value, and color.
90
89
  */
91
- override createNode(key: BTNKey, value?: V, color: RBTNColor = RBTNColor.BLACK): N {
92
- return new RedBlackTreeNode<V, N>(key, value, color) as N;
90
+ override createNode(key: K, value?: V, color: RBTNColor = RBTNColor.BLACK): N {
91
+ return new RedBlackTreeNode<K, V, N>(key, value, color) as N;
93
92
  }
94
93
 
95
94
  /**
@@ -99,32 +98,32 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
99
98
  * class.
100
99
  * @returns a new instance of a RedBlackTree object.
101
100
  */
102
- override createTree(options?: RBTreeOptions): TREE {
103
- return new RedBlackTree<V, N, TREE>([], {
101
+ override createTree(options?: RBTreeOptions<K>): TREE {
102
+ return new RedBlackTree<K, V, N, TREE>([], {
104
103
  iterationType: this.iterationType,
105
- comparator: this.comparator, ...options
104
+ variant: this.variant, ...options
106
105
  }) as TREE;
107
106
  }
108
107
 
109
108
  /**
110
109
  * The function checks if an exemplar is an instance of the RedBlackTreeNode class.
111
- * @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<V, N>`.
110
+ * @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<K, V, N>`.
112
111
  * @returns a boolean value indicating whether the exemplar is an instance of the RedBlackTreeNode
113
112
  * class.
114
113
  */
115
- override isNode(exemplar: BTNodeExemplar<V, N>): exemplar is N {
114
+ override isNode(exemplar: BTNodeExemplar<K, V, N>): exemplar is N {
116
115
  return exemplar instanceof RedBlackTreeNode;
117
116
  }
118
117
 
119
118
  /**
120
119
  * The function `exemplarToNode` takes an exemplar and returns a node if the exemplar is valid,
121
120
  * otherwise it returns undefined.
122
- * @param exemplar - BTNodeExemplar<V, N> - A generic type representing an exemplar of a binary tree
121
+ * @param exemplar - BTNodeExemplar<K, V, N> - A generic type representing an exemplar of a binary tree
123
122
  * node. It can be either a node itself, an entry (key-value pair), a node key, or any other value
124
123
  * that is not a valid exemplar.
125
124
  * @returns a variable `node` which is of type `N | undefined`.
126
125
  */
127
- override exemplarToNode(exemplar: BTNodeExemplar<V, N>): N | undefined {
126
+ override exemplarToNode(exemplar: BTNodeExemplar<K, V, N>): N | undefined {
128
127
  let node: N | undefined;
129
128
 
130
129
  if (exemplar === null || exemplar === undefined) {
@@ -138,7 +137,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
138
137
  } else {
139
138
  node = this.createNode(key, value, RBTNColor.RED);
140
139
  }
141
- } else if (this.isNodeKey(exemplar)) {
140
+ } else if (this.isNotNodeInstance(exemplar)) {
142
141
  node = this.createNode(exemplar, undefined, RBTNColor.RED);
143
142
  } else {
144
143
  return;
@@ -157,7 +156,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
157
156
  * @returns The method `add` returns either an instance of `N` (the node that was added) or
158
157
  * `undefined`.
159
158
  */
160
- override add(keyOrNodeOrEntry: BTNodeExemplar<V, N>): N | undefined {
159
+ override add(keyOrNodeOrEntry: BTNodeExemplar<K, V, N>): N | undefined {
161
160
  const newNode = this.exemplarToNode(keyOrNodeOrEntry);
162
161
  if (newNode === undefined) return;
163
162
 
@@ -298,8 +297,8 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
298
297
  return node !== this.Sentinel && node !== undefined;
299
298
  }
300
299
 
301
- getNode<C extends BTNCallback<N, BTNKey>>(
302
- identifier: BTNKey,
300
+ getNode<C extends BTNCallback<N, K>>(
301
+ identifier: K,
303
302
  callback?: C,
304
303
  beginRoot?: N | undefined,
305
304
  iterationType?: IterationType
@@ -337,7 +336,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
337
336
  * @param {C} callback - The `callback` parameter is a function that will be called for each node in
338
337
  * the binary tree. It is used to determine if a node matches the given identifier. The `callback`
339
338
  * function should take a single parameter of type `N` (the type of the nodes in the binary tree) and
340
- * @param {BTNKey | N | undefined} beginRoot - The `beginRoot` parameter is the starting point for
339
+ * @param {K | N | undefined} beginRoot - The `beginRoot` parameter is the starting point for
341
340
  * searching for a node in a binary tree. It can be either a key value or a node object. If it is not
342
341
  * provided, the search will start from the root of the binary tree.
343
342
  * @param iterationType - The `iterationType` parameter is a variable that determines the type of
@@ -348,7 +347,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
348
347
  getNode<C extends BTNCallback<N>>(
349
348
  identifier: ReturnType<C> | undefined,
350
349
  callback: C = this._defaultOneParamCallback as C,
351
- beginRoot: BSTNodeKeyOrNode<N> = this.root,
350
+ beginRoot: BSTNodeKeyOrNode<K, N> = this.root,
352
351
  iterationType = this.iterationType
353
352
  ): N | null | undefined {
354
353
  if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;