priority-queue-typed 1.46.8 → 1.46.9

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 (31) hide show
  1. package/dist/data-structures/binary-tree/avl-tree.d.ts +4 -2
  2. package/dist/data-structures/binary-tree/avl-tree.js +10 -0
  3. package/dist/data-structures/binary-tree/binary-tree.d.ts +19 -13
  4. package/dist/data-structures/binary-tree/binary-tree.js +121 -55
  5. package/dist/data-structures/binary-tree/bst.d.ts +10 -9
  6. package/dist/data-structures/binary-tree/bst.js +16 -14
  7. package/dist/data-structures/binary-tree/rb-tree.d.ts +7 -5
  8. package/dist/data-structures/binary-tree/rb-tree.js +32 -23
  9. package/dist/data-structures/binary-tree/tree-multimap.d.ts +5 -3
  10. package/dist/data-structures/binary-tree/tree-multimap.js +11 -2
  11. package/dist/interfaces/binary-tree.d.ts +3 -3
  12. package/dist/types/common.d.ts +5 -4
  13. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +2 -1
  14. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +3 -1
  15. package/dist/types/data-structures/binary-tree/binary-tree.js +0 -6
  16. package/dist/types/data-structures/binary-tree/bst.d.ts +2 -1
  17. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +2 -1
  18. package/dist/types/data-structures/binary-tree/tree-multimap.d.ts +2 -1
  19. package/package.json +2 -2
  20. package/src/data-structures/binary-tree/avl-tree.ts +17 -5
  21. package/src/data-structures/binary-tree/binary-tree.ts +143 -62
  22. package/src/data-structures/binary-tree/bst.ts +23 -19
  23. package/src/data-structures/binary-tree/rb-tree.ts +38 -27
  24. package/src/data-structures/binary-tree/tree-multimap.ts +19 -6
  25. package/src/interfaces/binary-tree.ts +3 -3
  26. package/src/types/common.ts +2 -5
  27. package/src/types/data-structures/binary-tree/avl-tree.ts +5 -1
  28. package/src/types/data-structures/binary-tree/binary-tree.ts +5 -7
  29. package/src/types/data-structures/binary-tree/bst.ts +3 -1
  30. package/src/types/data-structures/binary-tree/rb-tree.ts +3 -1
  31. package/src/types/data-structures/binary-tree/tree-multimap.ts +3 -1
@@ -6,14 +6,15 @@
6
6
  * @license MIT License
7
7
  */
8
8
  import { BST, BSTNode } from './bst';
9
- import type { AVLTreeNodeNested, AVLTreeOptions, BiTreeDeleteResult, BTNKey } from '../../types';
9
+ import type { AVLTreeNested, AVLTreeNodeNested, AVLTreeOptions, BiTreeDeleteResult, BTNKey } from '../../types';
10
10
  import { BTNCallback } from '../../types';
11
11
  import { IBinaryTree } from '../../interfaces';
12
12
  export declare class AVLTreeNode<V = any, N extends AVLTreeNode<V, N> = AVLTreeNodeNested<V>> extends BSTNode<V, N> {
13
13
  height: number;
14
14
  constructor(key: BTNKey, value?: V);
15
15
  }
16
- export declare class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTreeNodeNested<V>>> extends BST<V, N> implements IBinaryTree<V, N> {
16
+ export declare class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTreeNodeNested<V>>, TREE extends AVLTree<V, N, TREE> = AVLTree<V, N, AVLTreeNested<V, N>>> extends BST<V, N, TREE> implements IBinaryTree<V, N, TREE> {
17
+ options: AVLTreeOptions;
17
18
  /**
18
19
  * This is a constructor function for an AVL tree data structure in TypeScript.
19
20
  * @param {AVLTreeOptions} [options] - The `options` parameter is an optional object that can be passed to the
@@ -31,6 +32,7 @@ export declare class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<
31
32
  * @returns a new AVLTreeNode object with the specified key and value.
32
33
  */
33
34
  createNode(key: BTNKey, value?: V): N;
35
+ createTree(options?: AVLTreeOptions): TREE;
34
36
  /**
35
37
  * Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity.
36
38
  * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
@@ -9,6 +9,7 @@ exports.AVLTree = exports.AVLTreeNode = void 0;
9
9
  * @license MIT License
10
10
  */
11
11
  const bst_1 = require("./bst");
12
+ const types_1 = require("../../types");
12
13
  class AVLTreeNode extends bst_1.BSTNode {
13
14
  constructor(key, value) {
14
15
  super(key, value);
@@ -25,6 +26,12 @@ class AVLTree extends bst_1.BST {
25
26
  */
26
27
  constructor(options) {
27
28
  super(options);
29
+ if (options) {
30
+ this.options = Object.assign({ iterationType: types_1.IterationType.ITERATIVE, comparator: (a, b) => a - b }, options);
31
+ }
32
+ else {
33
+ this.options = { iterationType: types_1.IterationType.ITERATIVE, comparator: (a, b) => a - b };
34
+ }
28
35
  }
29
36
  /**
30
37
  * The function creates a new AVL tree node with the specified key and value.
@@ -38,6 +45,9 @@ class AVLTree extends bst_1.BST {
38
45
  createNode(key, value) {
39
46
  return new AVLTreeNode(key, value);
40
47
  }
48
+ createTree(options) {
49
+ return new AVLTree(Object.assign(Object.assign({}, this.options), options));
50
+ }
41
51
  /**
42
52
  * Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity.
43
53
  * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
@@ -6,7 +6,7 @@
6
6
  * @license MIT License
7
7
  */
8
8
  import type { BinaryTreeNodeNested, BinaryTreeOptions, BTNCallback, BTNKey } from '../../types';
9
- import { BiTreeDeleteResult, DFSOrderPattern, FamilyPosition, IterationType } from '../../types';
9
+ import { BinaryTreeNested, BinaryTreePrintOptions, BiTreeDeleteResult, DFSOrderPattern, FamilyPosition, IterationType, NodeDisplayLayout } from '../../types';
10
10
  import { IBinaryTree } from '../../interfaces';
11
11
  /**
12
12
  * Represents a node in a binary tree.
@@ -62,8 +62,8 @@ export declare class BinaryTreeNode<V = any, N extends BinaryTreeNode<V, N> = Bi
62
62
  * Represents a binary tree data structure.
63
63
  * @template N - The type of the binary tree's nodes.
64
64
  */
65
- export declare class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode<V, BinaryTreeNodeNested<V>>> implements IBinaryTree<V, N> {
66
- iterationType: IterationType;
65
+ export declare class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode<V, BinaryTreeNodeNested<V>>, TREE extends BinaryTree<V, N, TREE> = BinaryTree<V, N, BinaryTreeNested<V, N>>> implements IBinaryTree<V, N, TREE> {
66
+ options: BinaryTreeOptions;
67
67
  /**
68
68
  * Creates a new instance of BinaryTree.
69
69
  * @param {BinaryTreeOptions} [options] - The options for the binary tree.
@@ -86,6 +86,7 @@ export declare class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = Binary
86
86
  * @returns {N} - The newly created BinaryTreeNode.
87
87
  */
88
88
  createNode(key: BTNKey, value?: V): N;
89
+ createTree(options?: BinaryTreeOptions): TREE;
89
90
  /**
90
91
  * Time Complexity: O(n)
91
92
  * Space Complexity: O(1)
@@ -181,7 +182,7 @@ export declare class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = Binary
181
182
  * values:
182
183
  * @returns the height of the binary tree.
183
184
  */
184
- getHeight(beginRoot?: BTNKey | N | null | undefined, iterationType?: IterationType): number;
185
+ getHeight(beginRoot?: BTNKey | N | null | undefined, iterationType?: IterationType | undefined): number;
185
186
  /**
186
187
  * Time Complexity: O(n)
187
188
  * Space Complexity: O(log n)
@@ -200,7 +201,7 @@ export declare class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = Binary
200
201
  * to calculate the minimum height of a binary tree. It can have two possible values:
201
202
  * @returns The function `getMinHeight` returns the minimum height of a binary tree.
202
203
  */
203
- getMinHeight(beginRoot?: BTNKey | N | null | undefined, iterationType?: IterationType): number;
204
+ getMinHeight(beginRoot?: BTNKey | N | null | undefined, iterationType?: IterationType | undefined): number;
204
205
  /**
205
206
  * Time Complexity: O(n)
206
207
  * Space Complexity: O(log n)
@@ -306,7 +307,7 @@ export declare class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = Binary
306
307
  * @returns The function `getLeftMost` returns the leftmost node (`N`) in the binary tree. If there
307
308
  * is no leftmost node, it returns `null` or `undefined` depending on the input.
308
309
  */
309
- getLeftMost(beginRoot?: BTNKey | N | null | undefined, iterationType?: IterationType): N | null | undefined;
310
+ getLeftMost(beginRoot?: BTNKey | N | null | undefined, iterationType?: IterationType | undefined): N | null | undefined;
310
311
  /**
311
312
  * Time Complexity: O(log n)
312
313
  * Space Complexity: O(1)
@@ -326,7 +327,7 @@ export declare class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = Binary
326
327
  * @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If there
327
328
  * is no rightmost node, it returns `null` or `undefined`, depending on the input.
328
329
  */
329
- getRightMost(beginRoot?: BTNKey | N | null | undefined, iterationType?: IterationType): N | null | undefined;
330
+ getRightMost(beginRoot?: BTNKey | N | null | undefined, iterationType?: IterationType | undefined): N | null | undefined;
330
331
  /**
331
332
  * Time Complexity: O(n)
332
333
  * Space Complexity: O(1)
@@ -343,7 +344,7 @@ export declare class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = Binary
343
344
  * possible values:
344
345
  * @returns a boolean value.
345
346
  */
346
- isSubtreeBST(beginRoot: BTNKey | N | null | undefined, iterationType?: IterationType): boolean;
347
+ isSubtreeBST(beginRoot: BTNKey | N | null | undefined, iterationType?: IterationType | undefined): boolean;
347
348
  /**
348
349
  * Time Complexity: O(n)
349
350
  * Space Complexity: O(1)
@@ -359,7 +360,7 @@ export declare class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = Binary
359
360
  * expected to be
360
361
  * @returns a boolean value.
361
362
  */
362
- isBST(iterationType?: IterationType): boolean;
363
+ isBST(iterationType?: IterationType | undefined): boolean;
363
364
  subTreeTraverse<C extends BTNCallback<N>>(callback?: C, beginRoot?: BTNKey | N | null | undefined, iterationType?: IterationType, includeNull?: false): ReturnType<C>[];
364
365
  subTreeTraverse<C extends BTNCallback<N>>(callback?: C, beginRoot?: BTNKey | N | null | undefined, iterationType?: IterationType, includeNull?: undefined): ReturnType<C>[];
365
366
  subTreeTraverse<C extends BTNCallback<N | null | undefined>>(callback?: C, beginRoot?: BTNKey | N | null | undefined, iterationType?: IterationType, includeNull?: true): ReturnType<C>[];
@@ -429,6 +430,10 @@ export declare class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = Binary
429
430
  * by the return type of the `callback` function.
430
431
  */
431
432
  morris<C extends BTNCallback<N>>(callback?: C, pattern?: DFSOrderPattern, beginRoot?: BTNKey | N | null | undefined): ReturnType<C>[];
433
+ forEach(callback: (entry: [BTNKey, V | undefined], tree: typeof this) => void): void;
434
+ filter(predicate: (entry: [BTNKey, V | undefined], tree: typeof this) => boolean): TREE;
435
+ map(callback: (entry: [BTNKey, V | undefined], tree: typeof this) => V): TREE;
436
+ reduce<T>(callback: (accumulator: T, entry: [BTNKey, V | undefined], tree: typeof this) => T, initialValue: T): T;
432
437
  /**
433
438
  * The above function is an iterator for a binary tree that can be used to traverse the tree in
434
439
  * either an iterative or recursive manner.
@@ -438,15 +443,16 @@ export declare class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = Binary
438
443
  * @returns The `*[Symbol.iterator]` method returns a generator object that yields the keys of the
439
444
  * binary tree nodes in a specific order.
440
445
  */
441
- [Symbol.iterator](node?: N | null | undefined): Generator<BTNKey, void, undefined>;
446
+ [Symbol.iterator](node?: N | null | undefined): Generator<[BTNKey, V | undefined], void, undefined>;
442
447
  /**
443
448
  * The `print` function is used to display a binary tree structure in a visually appealing way.
444
- * @param {N | null | undefined} beginRoot - The `root` parameter is of type `BTNKey | N | null |
449
+ * @param {BTNKey | N | null | undefined} [beginRoot=this.root] - The `root` parameter is of type `BTNKey | N | null |
445
450
  * undefined`. It represents the root node of a binary tree. The root node can have one of the
446
451
  * following types:
452
+ * @param {BinaryTreePrintOptions} [options={ isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false}] - Options object that controls printing behavior. You can specify whether to display undefined, null, or sentinel nodes.
447
453
  */
448
- print(beginRoot?: BTNKey | N | null | undefined): void;
449
- protected _displayAux(node: N | null | undefined): [string[], number, number, number];
454
+ print(beginRoot?: BTNKey | N | null | undefined, options?: BinaryTreePrintOptions): void;
455
+ protected _displayAux(node: N | null | undefined, options: BinaryTreePrintOptions): NodeDisplayLayout;
450
456
  protected _defaultOneParamCallback: (node: N) => number;
451
457
  /**
452
458
  * Swap the data of two nodes in the binary tree.
@@ -87,11 +87,12 @@ class BinaryTree {
87
87
  * @param {BinaryTreeOptions} [options] - The options for the binary tree.
88
88
  */
89
89
  constructor(options) {
90
- this.iterationType = types_1.IterationType.ITERATIVE;
91
90
  this._defaultOneParamCallback = (node) => node.key;
92
91
  if (options) {
93
- const { iterationType = types_1.IterationType.ITERATIVE } = options;
94
- this.iterationType = iterationType;
92
+ this.options = Object.assign({ iterationType: types_1.IterationType.ITERATIVE }, options);
93
+ }
94
+ else {
95
+ this.options = { iterationType: types_1.IterationType.ITERATIVE };
95
96
  }
96
97
  this._size = 0;
97
98
  }
@@ -116,6 +117,9 @@ class BinaryTree {
116
117
  createNode(key, value) {
117
118
  return new BinaryTreeNode(key, value);
118
119
  }
120
+ createTree(options) {
121
+ return new BinaryTree(Object.assign(Object.assign({}, this.options), options));
122
+ }
119
123
  /**
120
124
  * Time Complexity: O(n)
121
125
  * Space Complexity: O(1)
@@ -347,7 +351,7 @@ class BinaryTree {
347
351
  * values:
348
352
  * @returns the height of the binary tree.
349
353
  */
350
- getHeight(beginRoot = this.root, iterationType = this.iterationType) {
354
+ getHeight(beginRoot = this.root, iterationType = this.options.iterationType) {
351
355
  beginRoot = this.ensureNotKey(beginRoot);
352
356
  if (!beginRoot)
353
357
  return -1;
@@ -393,7 +397,7 @@ class BinaryTree {
393
397
  * to calculate the minimum height of a binary tree. It can have two possible values:
394
398
  * @returns The function `getMinHeight` returns the minimum height of a binary tree.
395
399
  */
396
- getMinHeight(beginRoot = this.root, iterationType = this.iterationType) {
400
+ getMinHeight(beginRoot = this.root, iterationType = this.options.iterationType) {
397
401
  var _a, _b, _c;
398
402
  beginRoot = this.ensureNotKey(beginRoot);
399
403
  if (!beginRoot)
@@ -485,7 +489,7 @@ class BinaryTree {
485
489
  * traverse the binary tree. It can have two possible values:
486
490
  * @returns an array of nodes of type `N`.
487
491
  */
488
- getNodes(identifier, callback = this._defaultOneParamCallback, onlyOne = false, beginRoot = this.root, iterationType = this.iterationType) {
492
+ getNodes(identifier, callback = this._defaultOneParamCallback, onlyOne = false, beginRoot = this.root, iterationType = this.options.iterationType) {
489
493
  if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
490
494
  callback = (node => node);
491
495
  beginRoot = this.ensureNotKey(beginRoot);
@@ -547,7 +551,7 @@ class BinaryTree {
547
551
  * be performed in a pre-order, in-order, or post-order manner.
548
552
  * @returns a boolean value.
549
553
  */
550
- has(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
554
+ has(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.options.iterationType) {
551
555
  if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
552
556
  callback = (node => node);
553
557
  return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
@@ -577,7 +581,7 @@ class BinaryTree {
577
581
  * nodes are visited during the search.
578
582
  * @returns a value of type `N | null | undefined`.
579
583
  */
580
- getNode(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
584
+ getNode(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.options.iterationType) {
581
585
  var _a;
582
586
  if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
583
587
  callback = (node => node);
@@ -670,7 +674,7 @@ class BinaryTree {
670
674
  * @returns The value of the node with the given identifier is being returned. If the node is not
671
675
  * found, `undefined` is returned.
672
676
  */
673
- get(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
677
+ get(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.options.iterationType) {
674
678
  var _a, _b;
675
679
  if ((!callback || callback === this._defaultOneParamCallback) && identifier instanceof BinaryTreeNode)
676
680
  callback = (node => node);
@@ -741,7 +745,7 @@ class BinaryTree {
741
745
  * @returns The function `getLeftMost` returns the leftmost node (`N`) in the binary tree. If there
742
746
  * is no leftmost node, it returns `null` or `undefined` depending on the input.
743
747
  */
744
- getLeftMost(beginRoot = this.root, iterationType = this.iterationType) {
748
+ getLeftMost(beginRoot = this.root, iterationType = this.options.iterationType) {
745
749
  beginRoot = this.ensureNotKey(beginRoot);
746
750
  if (!beginRoot)
747
751
  return beginRoot;
@@ -782,7 +786,7 @@ class BinaryTree {
782
786
  * @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If there
783
787
  * is no rightmost node, it returns `null` or `undefined`, depending on the input.
784
788
  */
785
- getRightMost(beginRoot = this.root, iterationType = this.iterationType) {
789
+ getRightMost(beginRoot = this.root, iterationType = this.options.iterationType) {
786
790
  // TODO support get right most by passing key in
787
791
  beginRoot = this.ensureNotKey(beginRoot);
788
792
  if (!beginRoot)
@@ -821,7 +825,7 @@ class BinaryTree {
821
825
  * possible values:
822
826
  * @returns a boolean value.
823
827
  */
824
- isSubtreeBST(beginRoot, iterationType = this.iterationType) {
828
+ isSubtreeBST(beginRoot, iterationType = this.options.iterationType) {
825
829
  // TODO there is a bug
826
830
  beginRoot = this.ensureNotKey(beginRoot);
827
831
  if (!beginRoot)
@@ -868,7 +872,7 @@ class BinaryTree {
868
872
  * expected to be
869
873
  * @returns a boolean value.
870
874
  */
871
- isBST(iterationType = this.iterationType) {
875
+ isBST(iterationType = this.options.iterationType) {
872
876
  if (this.root === null)
873
877
  return true;
874
878
  return this.isSubtreeBST(this.root, iterationType);
@@ -893,13 +897,13 @@ class BinaryTree {
893
897
  * @param iterationType - The `iterationType` parameter determines the type of traversal to be
894
898
  * performed on the subtree. It can have two possible values:
895
899
  * @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines
896
- * whether or not to include null values in the traversal. If `includeNull` is set to `true`, the
900
+ * whether to include null values in the traversal. If `includeNull` is set to `true`, the
897
901
  * traversal will include null values, otherwise it will skip them.
898
902
  * @returns The function `subTreeTraverse` returns an array of values that are the result of invoking
899
903
  * the `callback` function on each node in the subtree. The type of the array elements is determined
900
904
  * by the return type of the `callback` function.
901
905
  */
902
- subTreeTraverse(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
906
+ subTreeTraverse(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.options.iterationType, includeNull = false) {
903
907
  beginRoot = this.ensureNotKey(beginRoot);
904
908
  const ans = [];
905
909
  if (!beginRoot)
@@ -1126,12 +1130,12 @@ class BinaryTree {
1126
1130
  * @param iterationType - The `iterationType` parameter determines the type of iteration to be
1127
1131
  * performed during the breadth-first search (BFS). It can have two possible values:
1128
1132
  * @param [includeNull=false] - The `includeNull` parameter is a boolean flag that determines whether
1129
- * or not to include null values in the breadth-first search traversal. If `includeNull` is set to
1133
+ * to include null values in the breadth-first search traversal. If `includeNull` is set to
1130
1134
  * `true`, null values will be included in the traversal, otherwise they will be skipped.
1131
1135
  * @returns an array of values that are the result of invoking the callback function on each node in
1132
1136
  * the breadth-first traversal of a binary tree.
1133
1137
  */
1134
- bfs(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
1138
+ bfs(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.options.iterationType, includeNull = false) {
1135
1139
  beginRoot = this.ensureNotKey(beginRoot);
1136
1140
  if (!beginRoot)
1137
1141
  return [];
@@ -1203,12 +1207,12 @@ class BinaryTree {
1203
1207
  * @param iterationType - The `iterationType` parameter determines the type of iteration to be
1204
1208
  * performed on the tree. It can have two possible values:
1205
1209
  * @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines
1206
- * whether or not to include null values in the resulting levels. If `includeNull` is set to `true`,
1210
+ * whether to include null values in the resulting levels. If `includeNull` is set to `true`,
1207
1211
  * null values will be included in the levels. If `includeNull` is set to `false`, null values will
1208
1212
  * be excluded
1209
1213
  * @returns The function `listLevels` returns a two-dimensional array of type `ReturnType<C>[][]`.
1210
1214
  */
1211
- listLevels(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType, includeNull = false) {
1215
+ listLevels(callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.options.iterationType, includeNull = false) {
1212
1216
  beginRoot = this.ensureNotKey(beginRoot);
1213
1217
  const levelsNodes = [];
1214
1218
  if (!beginRoot)
@@ -1407,6 +1411,42 @@ class BinaryTree {
1407
1411
  }
1408
1412
  return ans;
1409
1413
  }
1414
+ forEach(callback) {
1415
+ for (const entry of this) {
1416
+ callback(entry, this);
1417
+ }
1418
+ }
1419
+ filter(predicate) {
1420
+ const newTree = this.createTree();
1421
+ for (const [key, value] of this) {
1422
+ if (predicate([key, value], this)) {
1423
+ newTree.add(key, value);
1424
+ }
1425
+ }
1426
+ return newTree;
1427
+ }
1428
+ // TODO Type error, need to return a TREE<NV> that is a value type only for callback function.
1429
+ // map<NV>(callback: (entry: [BTNKey, V | undefined], tree: typeof this) => NV) {
1430
+ // const newTree = this.createTree();
1431
+ // for (const [key, value] of this) {
1432
+ // newTree.add(key, callback([key, value], this));
1433
+ // }
1434
+ // return newTree;
1435
+ // }
1436
+ map(callback) {
1437
+ const newTree = this.createTree();
1438
+ for (const [key, value] of this) {
1439
+ newTree.add(key, callback([key, value], this));
1440
+ }
1441
+ return newTree;
1442
+ }
1443
+ reduce(callback, initialValue) {
1444
+ let accumulator = initialValue;
1445
+ for (const [key, value] of this) {
1446
+ accumulator = callback(accumulator, [key, value], this);
1447
+ }
1448
+ return accumulator;
1449
+ }
1410
1450
  /**
1411
1451
  * The above function is an iterator for a binary tree that can be used to traverse the tree in
1412
1452
  * either an iterative or recursive manner.
@@ -1417,78 +1457,104 @@ class BinaryTree {
1417
1457
  * binary tree nodes in a specific order.
1418
1458
  */
1419
1459
  *[Symbol.iterator](node = this.root) {
1420
- if (!node) {
1460
+ if (!node)
1421
1461
  return;
1422
- }
1423
- if (this.iterationType === types_1.IterationType.ITERATIVE) {
1462
+ if (this.options.iterationType === types_1.IterationType.ITERATIVE) {
1424
1463
  const stack = [];
1425
1464
  let current = node;
1426
1465
  while (current || stack.length > 0) {
1427
- while (current) {
1466
+ while (current && !isNaN(current.key)) {
1428
1467
  stack.push(current);
1429
1468
  current = current.left;
1430
1469
  }
1431
1470
  current = stack.pop();
1432
- if (current)
1433
- yield current.key;
1434
- if (current)
1471
+ if (current && !isNaN(current.key)) {
1472
+ yield [current.key, current.value];
1435
1473
  current = current.right;
1474
+ }
1436
1475
  }
1437
1476
  }
1438
1477
  else {
1439
- if (node.left) {
1478
+ if (node.left && !isNaN(node.key)) {
1440
1479
  yield* this[Symbol.iterator](node.left);
1441
1480
  }
1442
- yield node.key;
1443
- if (node.right) {
1481
+ yield [node.key, node.value];
1482
+ if (node.right && !isNaN(node.key)) {
1444
1483
  yield* this[Symbol.iterator](node.right);
1445
1484
  }
1446
1485
  }
1447
1486
  }
1448
1487
  /**
1449
1488
  * The `print` function is used to display a binary tree structure in a visually appealing way.
1450
- * @param {N | null | undefined} beginRoot - The `root` parameter is of type `BTNKey | N | null |
1489
+ * @param {BTNKey | N | null | undefined} [beginRoot=this.root] - The `root` parameter is of type `BTNKey | N | null |
1451
1490
  * undefined`. It represents the root node of a binary tree. The root node can have one of the
1452
1491
  * following types:
1492
+ * @param {BinaryTreePrintOptions} [options={ isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false}] - Options object that controls printing behavior. You can specify whether to display undefined, null, or sentinel nodes.
1453
1493
  */
1454
- print(beginRoot = this.root) {
1494
+ print(beginRoot = this.root, options) {
1495
+ const opts = Object.assign({ isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false }, options);
1455
1496
  beginRoot = this.ensureNotKey(beginRoot);
1456
1497
  if (!beginRoot)
1457
1498
  return;
1499
+ if (opts.isShowUndefined)
1500
+ console.log(`U for undefined
1501
+ `);
1502
+ if (opts.isShowNull)
1503
+ console.log(`N for null
1504
+ `);
1505
+ if (opts.isShowRedBlackNIL)
1506
+ console.log(`S for Sentinel Node
1507
+ `);
1458
1508
  const display = (root) => {
1459
- const [lines, , ,] = this._displayAux(root);
1509
+ const [lines, , ,] = this._displayAux(root, opts);
1460
1510
  for (const line of lines) {
1461
1511
  console.log(line);
1462
1512
  }
1463
1513
  };
1464
1514
  display(beginRoot);
1465
1515
  }
1466
- _displayAux(node) {
1467
- if (!node) {
1468
- return [['─'], 1, 0, 0];
1516
+ _displayAux(node, options) {
1517
+ const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
1518
+ const emptyDisplayLayout = [['─'], 1, 0, 0];
1519
+ // Check if node is null or undefined or key is NaN
1520
+ if (node === null && !isShowNull) {
1521
+ return emptyDisplayLayout;
1522
+ }
1523
+ else if (node === undefined && !isShowUndefined) {
1524
+ return emptyDisplayLayout;
1469
1525
  }
1470
- const line = node.key.toString();
1471
- const width = line.length;
1472
- if (!node.left && !node.right) {
1473
- return [[line], width, 1, Math.floor(width / 2)];
1526
+ else if (node !== null && node !== undefined && isNaN(node.key) && !isShowRedBlackNIL) {
1527
+ return emptyDisplayLayout;
1474
1528
  }
1475
- const [leftLines, leftWidth, leftHeight, leftMiddle] = node.left ? this._displayAux(node.left) : [[''], 0, 0, 0];
1476
- const [rightLines, rightWidth, rightHeight, rightMiddle] = node.right ? this._displayAux(node.right) : [[''], 0, 0, 0];
1477
- const firstLine = ' '.repeat(Math.max(0, leftMiddle + 1))
1478
- + '_'.repeat(Math.max(0, leftWidth - leftMiddle - 1))
1479
- + line
1480
- + '_'.repeat(Math.max(0, rightMiddle))
1481
- + ' '.repeat(Math.max(0, rightWidth - rightMiddle));
1482
- const secondLine = (leftHeight > 0 ? ' '.repeat(leftMiddle) + '/' + ' '.repeat(leftWidth - leftMiddle - 1) : ' '.repeat(leftWidth))
1483
- + ' '.repeat(width)
1484
- + (rightHeight > 0 ? ' '.repeat(rightMiddle) + '\\' + ' '.repeat(rightWidth - rightMiddle - 1) : ' '.repeat(rightWidth));
1485
- const mergedLines = [firstLine, secondLine];
1486
- for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
1487
- const leftLine = i < leftHeight ? leftLines[i] : ' '.repeat(leftWidth);
1488
- const rightLine = i < rightHeight ? rightLines[i] : ' '.repeat(rightWidth);
1489
- mergedLines.push(leftLine + ' '.repeat(width) + rightLine);
1529
+ else if (node !== null && node !== undefined) {
1530
+ // Display logic of normal nodes
1531
+ const key = node.key, line = isNaN(key) ? 'S' : key.toString(), width = line.length;
1532
+ return _buildNodeDisplay(line, width, this._displayAux(node.left, options), this._displayAux(node.right, options));
1533
+ }
1534
+ else {
1535
+ // For cases where none of the conditions are met, null, undefined, and NaN nodes are not displayed
1536
+ const line = node === undefined ? 'U' : 'N', width = line.length;
1537
+ return _buildNodeDisplay(line, width, [[''], 1, 0, 0], [[''], 1, 0, 0]);
1538
+ }
1539
+ function _buildNodeDisplay(line, width, left, right) {
1540
+ const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
1541
+ const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
1542
+ const firstLine = ' '.repeat(Math.max(0, leftMiddle + 1))
1543
+ + '_'.repeat(Math.max(0, leftWidth - leftMiddle - 1))
1544
+ + line
1545
+ + '_'.repeat(Math.max(0, rightMiddle))
1546
+ + ' '.repeat(Math.max(0, rightWidth - rightMiddle));
1547
+ const secondLine = (leftHeight > 0 ? ' '.repeat(leftMiddle) + '/' + ' '.repeat(leftWidth - leftMiddle - 1) : ' '.repeat(leftWidth))
1548
+ + ' '.repeat(width)
1549
+ + (rightHeight > 0 ? ' '.repeat(rightMiddle) + '\\' + ' '.repeat(rightWidth - rightMiddle - 1) : ' '.repeat(rightWidth));
1550
+ const mergedLines = [firstLine, secondLine];
1551
+ for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
1552
+ const leftLine = i < leftHeight ? leftLines[i] : ' '.repeat(leftWidth);
1553
+ const rightLine = i < rightHeight ? rightLines[i] : ' '.repeat(rightWidth);
1554
+ mergedLines.push(leftLine + ' '.repeat(width) + rightLine);
1555
+ }
1556
+ return [mergedLines, leftWidth + width + rightWidth, Math.max(leftHeight, rightHeight) + 2, leftWidth + Math.floor(width / 2)];
1490
1557
  }
1491
- return [mergedLines, leftWidth + width + rightWidth, Math.max(leftHeight, rightHeight) + 2, leftWidth + Math.floor(width / 2)];
1492
1558
  }
1493
1559
  /**
1494
1560
  * Swap the data of two nodes in the binary tree.
@@ -5,7 +5,7 @@
5
5
  * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
6
6
  * @license MIT License
7
7
  */
8
- import type { BSTComparator, BSTNodeNested, BSTOptions, BTNCallback, BTNKey } from '../../types';
8
+ import type { BSTNested, BSTNodeNested, BSTOptions, BTNCallback, BTNKey } from '../../types';
9
9
  import { CP, IterationType } from '../../types';
10
10
  import { BinaryTree, BinaryTreeNode } from './binary-tree';
11
11
  import { IBinaryTree } from '../../interfaces';
@@ -33,7 +33,8 @@ export declare class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>
33
33
  */
34
34
  set right(v: N | undefined);
35
35
  }
36
- export declare class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>> extends BinaryTree<V, N> implements IBinaryTree<V, N> {
36
+ export declare 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>>> extends BinaryTree<V, N, TREE> implements IBinaryTree<V, N, TREE> {
37
+ options: BSTOptions;
37
38
  /**
38
39
  * The constructor function initializes a binary search tree with an optional comparator function.
39
40
  * @param {BSTOptions} [options] - An optional object that contains additional configuration options
@@ -54,6 +55,7 @@ export declare class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNe
54
55
  * @returns a new instance of the BSTNode class with the specified key and value.
55
56
  */
56
57
  createNode(key: BTNKey, value?: V): N;
58
+ createTree(options?: BSTOptions): TREE;
57
59
  /**
58
60
  * Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n).
59
61
  * Space Complexity: O(1) - Constant space is used.
@@ -95,7 +97,7 @@ export declare class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNe
95
97
  * current instance of the binary search tree
96
98
  * @returns The function `addMany` returns an array of nodes (`N`) or `undefined` values.
97
99
  */
98
- addMany(keysOrNodes: (BTNKey | N | undefined)[], data?: (V | undefined)[], isBalanceAdd?: boolean, iterationType?: IterationType): (N | undefined)[];
100
+ addMany(keysOrNodes: (BTNKey | N | undefined)[], data?: (V | undefined)[], isBalanceAdd?: boolean, iterationType?: IterationType | undefined): (N | undefined)[];
99
101
  /**
100
102
  * Time Complexity: O(log n) - Average case for a balanced tree.
101
103
  * Space Complexity: O(1) - Constant space is used.
@@ -115,7 +117,7 @@ export declare class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNe
115
117
  * the key of the leftmost node if the comparison result is greater than, and the key of the
116
118
  * rightmost node otherwise. If no node is found, it returns 0.
117
119
  */
118
- lastKey(beginRoot?: BTNKey | N | undefined, iterationType?: IterationType): BTNKey;
120
+ lastKey(beginRoot?: BTNKey | N | undefined, iterationType?: IterationType | undefined): BTNKey;
119
121
  /**
120
122
  * Time Complexity: O(log n) - Average case for a balanced tree.
121
123
  * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
@@ -172,7 +174,7 @@ export declare class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNe
172
174
  * performed on the binary tree. It can have two possible values:
173
175
  * @returns The method returns an array of nodes (`N[]`).
174
176
  */
175
- getNodes<C extends BTNCallback<N>>(identifier: ReturnType<C> | undefined, callback?: C, onlyOne?: boolean, beginRoot?: BTNKey | N | undefined, iterationType?: IterationType): N[];
177
+ getNodes<C extends BTNCallback<N>>(identifier: ReturnType<C> | undefined, callback?: C, onlyOne?: boolean, beginRoot?: BTNKey | N | undefined, iterationType?: IterationType | undefined): N[];
176
178
  /**
177
179
  * Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key.
178
180
  * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
@@ -198,7 +200,7 @@ export declare class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNe
198
200
  * @returns The function `lesserOrGreaterTraverse` returns an array of values of type
199
201
  * `ReturnType<C>`, which is the return type of the callback function passed as an argument.
200
202
  */
201
- lesserOrGreaterTraverse<C extends BTNCallback<N>>(callback?: C, lesserOrGreater?: CP, targetNode?: BTNKey | N | undefined, iterationType?: IterationType): ReturnType<C>[];
203
+ lesserOrGreaterTraverse<C extends BTNCallback<N>>(callback?: C, lesserOrGreater?: CP, targetNode?: BTNKey | N | undefined, iterationType?: IterationType | undefined): ReturnType<C>[];
202
204
  /**
203
205
  * Balancing Adjustment:
204
206
  * Perfectly Balanced Binary Tree: Since the balance of a perfectly balanced binary tree is already fixed, no additional balancing adjustment is needed. Any insertion or deletion operation will disrupt the perfect balance, often requiring a complete reconstruction of the tree.
@@ -223,7 +225,7 @@ export declare class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNe
223
225
  * values:
224
226
  * @returns The function `perfectlyBalance` returns a boolean value.
225
227
  */
226
- perfectlyBalance(iterationType?: IterationType): boolean;
228
+ perfectlyBalance(iterationType?: IterationType | undefined): boolean;
227
229
  /**
228
230
  * Time Complexity: O(n) - Visiting each node once.
229
231
  * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
@@ -237,8 +239,7 @@ export declare class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNe
237
239
  * to check if the AVL tree is balanced. It can have two possible values:
238
240
  * @returns a boolean value.
239
241
  */
240
- isAVLBalanced(iterationType?: IterationType): boolean;
241
- protected _comparator: BSTComparator;
242
+ isAVLBalanced(iterationType?: IterationType | undefined): boolean;
242
243
  protected _setRoot(v: N | undefined): void;
243
244
  /**
244
245
  * The function compares two values using a comparator function and returns whether the first value