directed-graph-typed 1.48.0 → 1.49.0

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 (89) hide show
  1. package/dist/data-structures/base/index.d.ts +1 -0
  2. package/dist/data-structures/base/index.js +17 -0
  3. package/dist/data-structures/base/iterable-base.d.ts +232 -0
  4. package/dist/data-structures/base/iterable-base.js +312 -0
  5. package/dist/data-structures/binary-tree/avl-tree.d.ts +28 -19
  6. package/dist/data-structures/binary-tree/avl-tree.js +22 -11
  7. package/dist/data-structures/binary-tree/binary-tree.d.ts +158 -152
  8. package/dist/data-structures/binary-tree/binary-tree.js +241 -215
  9. package/dist/data-structures/binary-tree/bst.d.ts +64 -48
  10. package/dist/data-structures/binary-tree/bst.js +94 -65
  11. package/dist/data-structures/binary-tree/rb-tree.d.ts +39 -39
  12. package/dist/data-structures/binary-tree/rb-tree.js +42 -49
  13. package/dist/data-structures/binary-tree/tree-multimap.d.ts +60 -34
  14. package/dist/data-structures/binary-tree/tree-multimap.js +59 -27
  15. package/dist/data-structures/graph/abstract-graph.d.ts +92 -53
  16. package/dist/data-structures/graph/abstract-graph.js +130 -103
  17. package/dist/data-structures/graph/directed-graph.d.ts +70 -52
  18. package/dist/data-structures/graph/directed-graph.js +111 -65
  19. package/dist/data-structures/graph/map-graph.d.ts +5 -5
  20. package/dist/data-structures/graph/map-graph.js +8 -8
  21. package/dist/data-structures/graph/undirected-graph.d.ts +51 -32
  22. package/dist/data-structures/graph/undirected-graph.js +117 -54
  23. package/dist/data-structures/hash/hash-map.d.ts +160 -44
  24. package/dist/data-structures/hash/hash-map.js +314 -82
  25. package/dist/data-structures/heap/heap.d.ts +50 -7
  26. package/dist/data-structures/heap/heap.js +60 -30
  27. package/dist/data-structures/index.d.ts +1 -0
  28. package/dist/data-structures/index.js +1 -0
  29. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +42 -55
  30. package/dist/data-structures/linked-list/doubly-linked-list.js +50 -77
  31. package/dist/data-structures/linked-list/singly-linked-list.d.ts +36 -55
  32. package/dist/data-structures/linked-list/singly-linked-list.js +44 -77
  33. package/dist/data-structures/queue/deque.d.ts +35 -167
  34. package/dist/data-structures/queue/deque.js +43 -249
  35. package/dist/data-structures/queue/queue.d.ts +49 -48
  36. package/dist/data-structures/queue/queue.js +69 -82
  37. package/dist/data-structures/stack/stack.d.ts +43 -10
  38. package/dist/data-structures/stack/stack.js +50 -31
  39. package/dist/data-structures/trie/trie.d.ts +41 -6
  40. package/dist/data-structures/trie/trie.js +53 -32
  41. package/dist/interfaces/binary-tree.d.ts +6 -6
  42. package/dist/types/common.d.ts +11 -8
  43. package/dist/types/common.js +6 -1
  44. package/dist/types/data-structures/base/base.d.ts +5 -0
  45. package/dist/types/data-structures/base/base.js +2 -0
  46. package/dist/types/data-structures/base/index.d.ts +1 -0
  47. package/dist/types/data-structures/base/index.js +17 -0
  48. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +3 -3
  49. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +4 -4
  50. package/dist/types/data-structures/binary-tree/bst.d.ts +6 -6
  51. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +3 -3
  52. package/dist/types/data-structures/binary-tree/tree-multimap.d.ts +3 -3
  53. package/dist/types/data-structures/hash/hash-map.d.ts +4 -0
  54. package/dist/types/data-structures/index.d.ts +1 -0
  55. package/dist/types/data-structures/index.js +1 -0
  56. package/package.json +2 -2
  57. package/src/data-structures/base/index.ts +1 -0
  58. package/src/data-structures/base/iterable-base.ts +329 -0
  59. package/src/data-structures/binary-tree/avl-tree.ts +37 -25
  60. package/src/data-structures/binary-tree/binary-tree.ts +336 -296
  61. package/src/data-structures/binary-tree/bst.ts +135 -89
  62. package/src/data-structures/binary-tree/rb-tree.ts +60 -69
  63. package/src/data-structures/binary-tree/tree-multimap.ts +86 -49
  64. package/src/data-structures/graph/abstract-graph.ts +136 -104
  65. package/src/data-structures/graph/directed-graph.ts +114 -65
  66. package/src/data-structures/graph/map-graph.ts +8 -8
  67. package/src/data-structures/graph/undirected-graph.ts +124 -56
  68. package/src/data-structures/hash/hash-map.ts +335 -84
  69. package/src/data-structures/heap/heap.ts +63 -36
  70. package/src/data-structures/index.ts +1 -0
  71. package/src/data-structures/linked-list/doubly-linked-list.ts +54 -83
  72. package/src/data-structures/linked-list/singly-linked-list.ts +49 -84
  73. package/src/data-structures/queue/deque.ts +43 -275
  74. package/src/data-structures/queue/queue.ts +71 -86
  75. package/src/data-structures/stack/stack.ts +53 -34
  76. package/src/data-structures/trie/trie.ts +58 -35
  77. package/src/interfaces/binary-tree.ts +5 -6
  78. package/src/types/common.ts +11 -8
  79. package/src/types/data-structures/base/base.ts +6 -0
  80. package/src/types/data-structures/base/index.ts +1 -0
  81. package/src/types/data-structures/binary-tree/avl-tree.ts +3 -3
  82. package/src/types/data-structures/binary-tree/binary-tree.ts +6 -5
  83. package/src/types/data-structures/binary-tree/bst.ts +6 -6
  84. package/src/types/data-structures/binary-tree/rb-tree.ts +3 -3
  85. package/src/types/data-structures/binary-tree/tree-multimap.ts +3 -3
  86. package/src/types/data-structures/hash/hash-map.ts +2 -0
  87. package/src/types/data-structures/heap/heap.ts +1 -1
  88. package/src/types/data-structures/index.ts +1 -0
  89. package/src/types/data-structures/priority-queue/priority-queue.ts +1 -1
@@ -11,6 +11,7 @@ exports.BinaryTree = exports.BinaryTreeNode = void 0;
11
11
  const types_1 = require("../../types");
12
12
  const utils_1 = require("../../utils");
13
13
  const queue_1 = require("../queue");
14
+ const base_1 = require("../base");
14
15
  /**
15
16
  * Represents a node in a binary tree.
16
17
  * @template V - The type of data stored in the node.
@@ -64,12 +65,8 @@ exports.BinaryTreeNode = BinaryTreeNode;
64
65
  * 3. Depth and Height: Depth is the number of edges from the root to a node; height is the maximum depth in the tree.
65
66
  * 4. Subtrees: Each child of a node forms the root of a subtree.
66
67
  * 5. Leaf Nodes: Nodes without children are leaves.
67
- * 6. Internal Nodes: Nodes with at least one child are internal.
68
- * 7. Balanced Trees: The heights of the left and right subtrees of any node differ by no more than one.
69
- * 8. Full Trees: Every node has either 0 or 2 children.
70
- * 9. Complete Trees: All levels are fully filled except possibly the last, filled from left to right.
71
68
  */
72
- class BinaryTree {
69
+ class BinaryTree extends base_1.IterableEntryBase {
73
70
  /**
74
71
  * The constructor function initializes a binary tree object with optional elements and options.
75
72
  * @param [elements] - An optional iterable of BTNodeExemplar objects. These objects represent the
@@ -80,18 +77,26 @@ class BinaryTree {
80
77
  * required.
81
78
  */
82
79
  constructor(elements, options) {
80
+ super();
83
81
  this.iterationType = types_1.IterationType.ITERATIVE;
82
+ this._extractor = (key) => Number(key);
84
83
  this._defaultOneParamCallback = (node) => node.key;
85
84
  if (options) {
86
- const { iterationType } = options;
85
+ const { iterationType, extractor } = options;
87
86
  if (iterationType) {
88
87
  this.iterationType = iterationType;
89
88
  }
89
+ if (extractor) {
90
+ this._extractor = extractor;
91
+ }
90
92
  }
91
93
  this._size = 0;
92
94
  if (elements)
93
95
  this.addMany(elements);
94
96
  }
97
+ get extractor() {
98
+ return this._extractor;
99
+ }
95
100
  get root() {
96
101
  return this._root;
97
102
  }
@@ -100,7 +105,7 @@ class BinaryTree {
100
105
  }
101
106
  /**
102
107
  * Creates a new instance of BinaryTreeNode with the given key and value.
103
- * @param {BTNKey} key - The key for the new node.
108
+ * @param {K} key - The key for the new node.
104
109
  * @param {V} value - The value for the new node.
105
110
  * @returns {N} - The newly created BinaryTreeNode.
106
111
  */
@@ -119,20 +124,21 @@ class BinaryTree {
119
124
  }
120
125
  /**
121
126
  * The function "isNode" checks if an exemplar is an instance of the BinaryTreeNode class.
122
- * @param exemplar - The `exemplar` parameter is a variable of type `BTNodeExemplar<V, N>`.
127
+ * @param exemplar - The `exemplar` parameter is a variable of type `BTNodeExemplar<K, V,N>`.
123
128
  * @returns a boolean value indicating whether the exemplar is an instance of the class N.
124
129
  */
125
130
  isNode(exemplar) {
126
131
  return exemplar instanceof BinaryTreeNode;
127
132
  }
128
133
  /**
129
- * The function `exemplarToNode` converts an exemplar of a binary tree node into an actual node
130
- * object.
131
- * @param exemplar - BTNodeExemplar<V, N> - A generic type representing the exemplar parameter of the
132
- * function. It can be any type.
133
- * @returns a value of type `N` (which represents a node), or `null`, or `undefined`.
134
+ * The function `exemplarToNode` converts an exemplar object into a node object.
135
+ * @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<K, V, N>`.
136
+ * @param {V} [value] - The `value` parameter is an optional value that can be passed to the
137
+ * `exemplarToNode` function. It represents the value associated with the exemplar node. If no value
138
+ * is provided, it will be `undefined`.
139
+ * @returns a value of type N (node), or null, or undefined.
134
140
  */
135
- exemplarToNode(exemplar) {
141
+ exemplarToNode(exemplar, value) {
136
142
  if (exemplar === undefined)
137
143
  return;
138
144
  let node;
@@ -154,8 +160,8 @@ class BinaryTree {
154
160
  else if (this.isNode(exemplar)) {
155
161
  node = exemplar;
156
162
  }
157
- else if (this.isNodeKey(exemplar)) {
158
- node = this.createNode(exemplar);
163
+ else if (this.isNotNodeInstance(exemplar)) {
164
+ node = this.createNode(exemplar, value);
159
165
  }
160
166
  else {
161
167
  return;
@@ -164,7 +170,7 @@ class BinaryTree {
164
170
  }
165
171
  /**
166
172
  * The function checks if a given value is an entry in a binary tree node.
167
- * @param kne - BTNodeExemplar<V, N> - A generic type representing a node in a binary tree. It has
173
+ * @param kne - BTNodeExemplar<K, V,N> - A generic type representing a node in a binary tree. It has
168
174
  * two type parameters V and N, representing the value and node type respectively.
169
175
  * @returns a boolean value.
170
176
  */
@@ -179,46 +185,57 @@ class BinaryTree {
179
185
  * Time Complexity O(log n) - O(n)
180
186
  * Space Complexity O(1)
181
187
  *
182
- * The `add` function adds a new node to a binary tree, either by key or by providing a node object.
183
- * @param keyOrNodeOrEntry - The parameter `keyOrNodeOrEntry` can be one of the following:
184
- * @returns The function `add` returns the inserted node (`N`), `null`, or `undefined`.
185
- */
186
- add(keyOrNodeOrEntry) {
187
- let inserted;
188
- const newNode = this.exemplarToNode(keyOrNodeOrEntry);
188
+ * The `add` function adds a new node to a binary tree, either by creating a new node or replacing an
189
+ * existing node with the same key.
190
+ * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be one of the following:
191
+ * @param {V} [value] - The value to be inserted into the binary tree.
192
+ * @returns The function `add` returns either a node (`N`), `null`, or `undefined`.
193
+ */
194
+ add(keyOrNodeOrEntry, value) {
195
+ const newNode = this.exemplarToNode(keyOrNodeOrEntry, value);
189
196
  if (newNode === undefined)
190
197
  return;
191
- const _bfs = (root, newNode) => {
192
- const queue = new queue_1.Queue([root]);
193
- while (queue.size > 0) {
194
- const cur = queue.shift();
195
- if (newNode && cur.key === newNode.key) {
196
- this._replaceNode(cur, newNode);
197
- return newNode;
198
- }
199
- const inserted = this._addTo(newNode, cur);
200
- if (inserted !== undefined)
201
- return inserted;
202
- if (cur.left)
203
- queue.push(cur.left);
204
- if (cur.right)
205
- queue.push(cur.right);
198
+ // If the tree is empty, directly set the new node as the root node
199
+ if (!this.root) {
200
+ this._root = newNode;
201
+ this._size = 1;
202
+ return newNode;
203
+ }
204
+ const queue = new queue_1.Queue([this.root]);
205
+ let potentialParent; // Record the parent node of the potential insertion location
206
+ while (queue.size > 0) {
207
+ const cur = queue.shift();
208
+ if (!cur)
209
+ continue;
210
+ // Check for duplicate keys when newNode is not null
211
+ if (newNode !== null && cur.key === newNode.key) {
212
+ this._replaceNode(cur, newNode);
213
+ return newNode; // If duplicate keys are found, no insertion is performed
214
+ }
215
+ // Record the first possible insertion location found
216
+ if (potentialParent === undefined && (cur.left === undefined || cur.right === undefined)) {
217
+ potentialParent = cur;
218
+ }
219
+ // Continue traversing the left and right subtrees
220
+ if (cur.left !== null) {
221
+ cur.left && queue.push(cur.left);
222
+ }
223
+ if (cur.right !== null) {
224
+ cur.right && queue.push(cur.right);
206
225
  }
207
- };
208
- if (this.root) {
209
- inserted = _bfs(this.root, newNode);
210
226
  }
211
- else {
212
- this._setRoot(newNode);
213
- if (newNode) {
214
- this._size = 1;
227
+ // At the end of the traversal, if the insertion position is found, insert
228
+ if (potentialParent) {
229
+ if (potentialParent.left === undefined) {
230
+ potentialParent.left = newNode;
215
231
  }
216
- else {
217
- this._size = 0;
232
+ else if (potentialParent.right === undefined) {
233
+ potentialParent.right = newNode;
218
234
  }
219
- inserted = this.root;
235
+ this._size++;
236
+ return newNode;
220
237
  }
221
- return inserted;
238
+ return undefined; // If the insertion position cannot be found, return undefined
222
239
  }
223
240
  /**
224
241
  * Time Complexity: O(k log n) - O(k * n)
@@ -229,18 +246,28 @@ class BinaryTree {
229
246
  * Time Complexity: O(k log n) - O(k * n)
230
247
  * Space Complexity: O(1)
231
248
  *
232
- * The function `addMany` takes in an iterable of `BTNodeExemplar` objects, adds each object to the
233
- * current instance, and returns an array of the inserted nodes.
234
- * @param nodes - The `nodes` parameter is an iterable (such as an array or a set) of
235
- * `BTNodeExemplar<V, N>` objects.
236
- * @returns The function `addMany` returns an array of values, where each value is either of type
237
- * `N`, `null`, or `undefined`.
238
- */
239
- addMany(nodes) {
249
+ * The `addMany` function takes in a collection of nodes and an optional collection of values, and
250
+ * adds each node with its corresponding value to the data structure.
251
+ * @param nodes - An iterable collection of BTNodeExemplar objects.
252
+ * @param [values] - An optional iterable of values that will be assigned to each node being added.
253
+ * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
254
+ */
255
+ addMany(nodes, values) {
240
256
  // TODO not sure addMany not be run multi times
241
257
  const inserted = [];
258
+ let valuesIterator;
259
+ if (values) {
260
+ valuesIterator = values[Symbol.iterator]();
261
+ }
242
262
  for (const kne of nodes) {
243
- inserted.push(this.add(kne));
263
+ let value = undefined;
264
+ if (valuesIterator) {
265
+ const valueResult = valuesIterator.next();
266
+ if (!valueResult.done) {
267
+ value = valueResult.value;
268
+ }
269
+ }
270
+ inserted.push(this.add(kne, value));
244
271
  }
245
272
  return inserted;
246
273
  }
@@ -248,17 +275,9 @@ class BinaryTree {
248
275
  * Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
249
276
  * Space Complexity: O(1)
250
277
  */
251
- /**
252
- * Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
253
- * Space Complexity: O(1)
254
- *
255
- * The `refill` function clears the current collection and adds new nodes, keys, or entries to it.
256
- * @param nodesOrKeysOrEntries - The parameter `nodesOrKeysOrEntries` is an iterable object that can
257
- * contain either `BTNodeExemplar` objects, keys, or entries.
258
- */
259
- refill(nodesOrKeysOrEntries) {
278
+ refill(nodesOrKeysOrEntries, values) {
260
279
  this.clear();
261
- this.addMany(nodesOrKeysOrEntries);
280
+ this.addMany(nodesOrKeysOrEntries, values);
262
281
  }
263
282
  /**
264
283
  * Time Complexity: O(n)
@@ -332,11 +351,11 @@ class BinaryTree {
332
351
  * Space Complexity: O(1)
333
352
  *
334
353
  * The function calculates the depth of a given node in a binary tree.
335
- * @param {BTNKey | N | null | undefined} distNode - The `distNode` parameter represents the node in
336
- * the binary tree whose depth we want to find. It can be of type `BTNKey`, `N`, `null`, or
354
+ * @param {K | N | null | undefined} distNode - The `distNode` parameter represents the node in
355
+ * the binary tree whose depth we want to find. It can be of type `K`, `N`, `null`, or
337
356
  * `undefined`.
338
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
339
- * from which we want to calculate the depth. It can be either a `BTNKey` (binary tree node key) or
357
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
358
+ * from which we want to calculate the depth. It can be either a `K` (binary tree node key) or
340
359
  * `N` (binary tree node) or `null` or `undefined`. If no value is provided for `beginRoot
341
360
  * @returns the depth of the `distNode` relative to the `beginRoot`.
342
361
  */
@@ -363,9 +382,9 @@ class BinaryTree {
363
382
  *
364
383
  * The function `getHeight` calculates the maximum height of a binary tree using either recursive or
365
384
  * iterative traversal.
366
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
385
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
367
386
  * starting node of the binary tree from which we want to calculate the height. It can be of type
368
- * `BTNKey`, `N`, `null`, or `undefined`. If not provided, it defaults to `this.root`.
387
+ * `K`, `N`, `null`, or `undefined`. If not provided, it defaults to `this.root`.
369
388
  * @param iterationType - The `iterationType` parameter is used to determine whether to calculate the
370
389
  * height of the tree using a recursive approach or an iterative approach. It can have two possible
371
390
  * values:
@@ -410,9 +429,9 @@ class BinaryTree {
410
429
  *
411
430
  * The `getMinHeight` function calculates the minimum height of a binary tree using either a
412
431
  * recursive or iterative approach.
413
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
432
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
414
433
  * starting node of the binary tree from which we want to calculate the minimum height. It can be of
415
- * type `BTNKey`, `N`, `null`, or `undefined`. If no value is provided, it defaults to `this.root`.
434
+ * type `K`, `N`, `null`, or `undefined`. If no value is provided, it defaults to `this.root`.
416
435
  * @param iterationType - The `iterationType` parameter is used to determine the method of iteration
417
436
  * to calculate the minimum height of a binary tree. It can have two possible values:
418
437
  * @returns The function `getMinHeight` returns the minimum height of a binary tree.
@@ -473,8 +492,8 @@ class BinaryTree {
473
492
  *
474
493
  * The function checks if a binary tree is perfectly balanced by comparing the minimum height and the
475
494
  * height of the tree.
476
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
477
- * for calculating the height and minimum height of a binary tree. It can be either a `BTNKey` (a key
495
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
496
+ * for calculating the height and minimum height of a binary tree. It can be either a `K` (a key
478
497
  * value of a binary tree node), `N` (a node of a binary tree), `null`, or `undefined`. If
479
498
  * @returns a boolean value.
480
499
  */
@@ -499,7 +518,7 @@ class BinaryTree {
499
518
  * matches the identifier. If set to true, the function will stop iterating once it finds a matching
500
519
  * node and return that node. If set to false (default), the function will continue iterating and
501
520
  * return all nodes that match the identifier.
502
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
521
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
503
522
  * starting node for the traversal. It can be either a key, a node object, or `null`/`undefined`. If
504
523
  * it is `null` or `undefined`, an empty array will be returned.
505
524
  * @param iterationType - The `iterationType` parameter determines the type of iteration used to
@@ -556,8 +575,8 @@ class BinaryTree {
556
575
  * the binary tree. It is used to filter the nodes based on certain conditions. The `callback`
557
576
  * function should return a boolean value indicating whether the node should be included in the
558
577
  * result or not.
559
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
560
- * for the search in the binary tree. It can be specified as a `BTNKey` (a unique identifier for a
578
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
579
+ * for the search in the binary tree. It can be specified as a `K` (a unique identifier for a
561
580
  * node in the binary tree), a node object (`N`), or `null`/`undefined` to start the search from
562
581
  * @param iterationType - The `iterationType` parameter is a variable that determines the type of
563
582
  * iteration to be performed on the binary tree. It is used to specify whether the iteration should
@@ -582,7 +601,7 @@ class BinaryTree {
582
601
  * @param {C} callback - The `callback` parameter is a function that will be called for each node in
583
602
  * the binary tree. It is used to determine if a node matches the given identifier. The `callback`
584
603
  * function should take a single parameter of type `N` (the type of the nodes in the binary tree) and
585
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
604
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
586
605
  * for searching the binary tree. It can be either a key value, a node object, or `null`/`undefined`.
587
606
  * If `null` or `undefined` is passed, the search will start from the root of the binary tree.
588
607
  * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
@@ -606,7 +625,7 @@ class BinaryTree {
606
625
  *
607
626
  * The function `getNodeByKey` searches for a node in a binary tree by its key, using either
608
627
  * recursive or iterative iteration.
609
- * @param {BTNKey} key - The `key` parameter is the key value that we are searching for in the tree.
628
+ * @param {K} key - The `key` parameter is the key value that we are searching for in the tree.
610
629
  * It is used to find the node with the matching key value.
611
630
  * @param iterationType - The `iterationType` parameter is used to determine whether the search for
612
631
  * the node with the given key should be performed iteratively or recursively. It has two possible
@@ -650,7 +669,7 @@ class BinaryTree {
650
669
  /**
651
670
  * The function `ensureNode` returns the node corresponding to the given key if it is a valid node
652
671
  * key, otherwise it returns the key itself.
653
- * @param {BTNKey | N | null | undefined} key - The `key` parameter can be of type `BTNKey`, `N`,
672
+ * @param {K | N | null | undefined} key - The `key` parameter can be of type `K`, `N`,
654
673
  * `null`, or `undefined`. It represents a key used to identify a node in a binary tree.
655
674
  * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
656
675
  * type of iteration to be used when searching for a node by key. It has a default value of
@@ -659,7 +678,7 @@ class BinaryTree {
659
678
  * itself if it is not a valid node key.
660
679
  */
661
680
  ensureNode(key, iterationType = types_1.IterationType.ITERATIVE) {
662
- return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key;
681
+ return this.isNotNodeInstance(key) ? this.getNodeByKey(key, iterationType) : key;
663
682
  }
664
683
  /**
665
684
  * Time Complexity: O(n)
@@ -674,8 +693,8 @@ class BinaryTree {
674
693
  * the binary tree. It is used to determine whether a node matches the given identifier. The callback
675
694
  * function should return a value that can be compared to the identifier to determine if it is a
676
695
  * match.
677
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
678
- * for the search in the binary tree. It can be specified as a `BTNKey` (a unique identifier for a
696
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
697
+ * for the search in the binary tree. It can be specified as a `K` (a unique identifier for a
679
698
  * node), a node object of type `N`, or `null`/`undefined` to start the search from the root of
680
699
  * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
681
700
  * be performed when searching for a node in the binary tree. It is an optional parameter with a
@@ -713,8 +732,8 @@ class BinaryTree {
713
732
  *
714
733
  * The function `getPathToRoot` returns an array of nodes from a given node to the root of a tree
715
734
  * structure, with the option to reverse the order of the nodes.
716
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
717
- * starting node from which you want to find the path to the root. It can be of type `BTNKey`, `N`,
735
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
736
+ * starting node from which you want to find the path to the root. It can be of type `K`, `N`,
718
737
  * `null`, or `undefined`.
719
738
  * @param [isReverse=true] - The `isReverse` parameter is a boolean flag that determines whether the
720
739
  * resulting path should be reversed or not. If `isReverse` is set to `true`, the path will be
@@ -746,8 +765,8 @@ class BinaryTree {
746
765
  *
747
766
  * The function `getLeftMost` returns the leftmost node in a binary tree, either recursively or
748
767
  * iteratively.
749
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
750
- * for finding the leftmost node in a binary tree. It can be either a `BTNKey` (a key value), `N` (a
768
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
769
+ * for finding the leftmost node in a binary tree. It can be either a `K` (a key value), `N` (a
751
770
  * node), `null`, or `undefined`. If not provided, it defaults to `this.root`,
752
771
  * @param iterationType - The `iterationType` parameter is used to determine the type of iteration to
753
772
  * be performed when finding the leftmost node in a binary tree. It can have two possible values:
@@ -786,8 +805,8 @@ class BinaryTree {
786
805
  *
787
806
  * The function `getRightMost` returns the rightmost node in a binary tree, either recursively or
788
807
  * iteratively.
789
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
790
- * starting node from which we want to find the rightmost node. It can be of type `BTNKey`, `N`,
808
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
809
+ * starting node from which we want to find the rightmost node. It can be of type `K`, `N`,
791
810
  * `null`, or `undefined`. If not provided, it defaults to `this.root`, which is a property of the
792
811
  * current object.
793
812
  * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
@@ -827,7 +846,7 @@ class BinaryTree {
827
846
  * Space Complexity: O(1)
828
847
  *
829
848
  * The function `isSubtreeBST` checks if a given binary tree is a valid binary search tree.
830
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the root
849
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the root
831
850
  * node of the binary search tree (BST) that you want to check if it is a subtree of another BST.
832
851
  * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
833
852
  * type of iteration to use when checking if a subtree is a binary search tree (BST). It can have two
@@ -843,9 +862,10 @@ class BinaryTree {
843
862
  const dfs = (cur, min, max) => {
844
863
  if (!cur)
845
864
  return true;
846
- if (cur.key <= min || cur.key >= max)
865
+ const numKey = this.extractor(cur.key);
866
+ if (numKey <= min || numKey >= max)
847
867
  return false;
848
- return dfs(cur.left, min, cur.key) && dfs(cur.right, cur.key, max);
868
+ return dfs(cur.left, min, numKey) && dfs(cur.right, numKey, max);
849
869
  };
850
870
  return dfs(beginRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
851
871
  }
@@ -858,9 +878,10 @@ class BinaryTree {
858
878
  curr = curr.left;
859
879
  }
860
880
  curr = stack.pop();
861
- if (!curr || prev >= curr.key)
881
+ const numKey = this.extractor(curr.key);
882
+ if (!curr || prev >= numKey)
862
883
  return false;
863
- prev = curr.key;
884
+ prev = numKey;
864
885
  curr = curr.right;
865
886
  }
866
887
  return true;
@@ -895,8 +916,8 @@ class BinaryTree {
895
916
  * @param {C} callback - The `callback` parameter is a function that will be called for each node in
896
917
  * the subtree traversal. It takes a single parameter, which is the current node being traversed, and
897
918
  * returns a value of any type.
898
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
899
- * starting node or key from which the subtree traversal should begin. It can be of type `BTNKey`,
919
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
920
+ * starting node or key from which the subtree traversal should begin. It can be of type `K`,
900
921
  * `N`, `null`, or `undefined`. If not provided, the `root` property of the current object is used as
901
922
  * the default value.
902
923
  * @param iterationType - The `iterationType` parameter determines the type of traversal to be
@@ -959,7 +980,7 @@ class BinaryTree {
959
980
  * @returns a boolean value.
960
981
  */
961
982
  isRealNode(node) {
962
- return node instanceof BinaryTreeNode && node.key.toString() !== 'NaN';
983
+ return node instanceof BinaryTreeNode && String(node.key) !== 'NaN';
963
984
  }
964
985
  /**
965
986
  * The function checks if a given node is a BinaryTreeNode instance and has a key value of NaN.
@@ -967,7 +988,7 @@ class BinaryTree {
967
988
  * @returns a boolean value.
968
989
  */
969
990
  isNIL(node) {
970
- return node instanceof BinaryTreeNode && node.key.toString() === 'NaN';
991
+ return node instanceof BinaryTreeNode && String(node.key) === 'NaN';
971
992
  }
972
993
  /**
973
994
  * The function checks if a given node is a real node or null.
@@ -978,13 +999,13 @@ class BinaryTree {
978
999
  return this.isRealNode(node) || node === null;
979
1000
  }
980
1001
  /**
981
- * The function "isNodeKey" checks if a potential key is a number.
1002
+ * The function "isNotNodeInstance" checks if a potential key is a K.
982
1003
  * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any
983
1004
  * data type.
984
1005
  * @returns a boolean value indicating whether the potentialKey is of type number or not.
985
1006
  */
986
- isNodeKey(potentialKey) {
987
- return typeof potentialKey === 'number';
1007
+ isNotNodeInstance(potentialKey) {
1008
+ return !(potentialKey instanceof BinaryTreeNode);
988
1009
  }
989
1010
  /**
990
1011
  * Time complexity: O(n)
@@ -998,7 +1019,7 @@ class BinaryTree {
998
1019
  * `null`, or `undefined`, and returns a value of any type. The default value for this parameter is
999
1020
  * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter determines the order in which the
1000
1021
  * nodes are traversed during the depth-first search. It can have one of the following values:
1001
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
1022
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
1002
1023
  * for the depth-first search traversal. It can be specified as a key, a node object, or
1003
1024
  * `null`/`undefined`. If not provided, the `beginRoot` will default to the root node of the tree.
1004
1025
  * @param {IterationType} iterationType - The `iterationType` parameter determines the type of
@@ -1124,7 +1145,7 @@ class BinaryTree {
1124
1145
  * @param {C} callback - The `callback` parameter is a function that will be called for each node in
1125
1146
  * the breadth-first search traversal. It takes a single parameter, which is the current node being
1126
1147
  * visited, and returns a value of any type.
1127
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
1148
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
1128
1149
  * starting node for the breadth-first search traversal. It can be specified as a key, a node object,
1129
1150
  * or `null`/`undefined` to indicate the root of the tree. If not provided, the `root` property of
1130
1151
  * the class is used as
@@ -1198,9 +1219,9 @@ class BinaryTree {
1198
1219
  * @param {C} callback - The `callback` parameter is a function that will be called for each node in
1199
1220
  * the tree. It takes a single parameter, which can be of type `N`, `null`, or `undefined`, and
1200
1221
  * returns a value of any type.
1201
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
1222
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
1202
1223
  * starting node for traversing the tree. It can be either a node object (`N`), a key value
1203
- * (`BTNKey`), `null`, or `undefined`. If not provided, it defaults to the root node of the tree.
1224
+ * (`K`), `null`, or `undefined`. If not provided, it defaults to the root node of the tree.
1204
1225
  * @param iterationType - The `iterationType` parameter determines the type of iteration to be
1205
1226
  * performed on the tree. It can have two possible values:
1206
1227
  * @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines
@@ -1259,19 +1280,23 @@ class BinaryTree {
1259
1280
  return levelsNodes;
1260
1281
  }
1261
1282
  /**
1262
- * The function `getPredecessor` returns the predecessor node of a given node in a binary tree.
1263
- * @param {BTNKey | N | null | undefined} node - The `node` parameter can be of type `BTNKey`, `N`,
1264
- * `null`, or `undefined`.
1265
- * @returns The function `getPredecessor` returns a value of type `N | undefined`.
1283
+ * Time Complexity: O(log n)
1284
+ * Space Complexity: O(1)
1285
+ */
1286
+ /**
1287
+ * Time Complexity: O(log n)
1288
+ * Space Complexity: O(1)
1289
+ *
1290
+ * The function returns the predecessor of a given node in a tree.
1291
+ * @param {N} node - The parameter `node` is of type `RedBlackTreeNode`, which represents a node in a
1292
+ * tree.
1293
+ * @returns the predecessor of the given 'node'.
1266
1294
  */
1267
1295
  getPredecessor(node) {
1268
- node = this.ensureNode(node);
1269
- if (!this.isRealNode(node))
1270
- return undefined;
1271
- if (node.left) {
1296
+ if (this.isRealNode(node.left)) {
1272
1297
  let predecessor = node.left;
1273
1298
  while (!this.isRealNode(predecessor) || (this.isRealNode(predecessor.right) && predecessor.right !== node)) {
1274
- if (predecessor) {
1299
+ if (this.isRealNode(predecessor)) {
1275
1300
  predecessor = predecessor.right;
1276
1301
  }
1277
1302
  }
@@ -1283,19 +1308,19 @@ class BinaryTree {
1283
1308
  }
1284
1309
  /**
1285
1310
  * The function `getSuccessor` returns the next node in a binary tree given a current node.
1286
- * @param {BTNKey | N | null} [x] - The parameter `x` can be of type `BTNKey`, `N`, or `null`.
1311
+ * @param {K | N | null} [x] - The parameter `x` can be of type `K`, `N`, or `null`.
1287
1312
  * @returns the successor of the given node or key. The successor is the node that comes immediately
1288
1313
  * after the given node in the inorder traversal of the binary tree.
1289
1314
  */
1290
1315
  getSuccessor(x) {
1291
1316
  x = this.ensureNode(x);
1292
- if (!x)
1317
+ if (!this.isRealNode(x))
1293
1318
  return undefined;
1294
- if (x.right) {
1319
+ if (this.isRealNode(x.right)) {
1295
1320
  return this.getLeftMost(x.right);
1296
1321
  }
1297
1322
  let y = x.parent;
1298
- while (y && y && x === y.right) {
1323
+ while (this.isRealNode(y) && x === y.right) {
1299
1324
  x = y;
1300
1325
  y = y.parent;
1301
1326
  }
@@ -1312,7 +1337,7 @@ class BinaryTree {
1312
1337
  * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter in the `morris` function
1313
1338
  * determines the order in which the nodes of a binary tree are traversed. It can have one of the
1314
1339
  * following values:
1315
- * @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
1340
+ * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
1316
1341
  * for the traversal. It can be specified as a key, a node object, or `null`/`undefined` to indicate
1317
1342
  * the root of the tree. If no value is provided, the default value is the root of the tree.
1318
1343
  * @returns The function `morris` returns an array of values that are the result of invoking the
@@ -1406,116 +1431,89 @@ class BinaryTree {
1406
1431
  }
1407
1432
  /**
1408
1433
  * Time complexity: O(n)
1409
- * Space complexity: O(1)
1434
+ * Space complexity: O(n)
1410
1435
  */
1411
1436
  /**
1412
- * The `forEach` function iterates over each entry in a tree and calls a callback function with the
1413
- * entry and the tree as arguments.
1414
- * @param callback - The callback parameter is a function that will be called for each entry in the
1415
- * tree. It takes two parameters: entry and tree.
1416
- */
1417
- forEach(callback) {
1418
- for (const entry of this) {
1419
- callback(entry, this);
1420
- }
1437
+ * Time complexity: O(n)
1438
+ * Space complexity: O(n)
1439
+ *
1440
+ * The `clone` function creates a new tree object and copies all the nodes from the original tree to
1441
+ * the new tree.
1442
+ * @returns The `clone()` method is returning a cloned instance of the `TREE` object.
1443
+ */
1444
+ clone() {
1445
+ const cloned = this.createTree();
1446
+ this.bfs(node => cloned.add([node.key, node.value]));
1447
+ return cloned;
1421
1448
  }
1422
1449
  /**
1423
- * The `filter` function creates a new tree by iterating over the entries of the current tree and
1424
- * adding the entries that satisfy the given predicate.
1425
- * @param predicate - The `predicate` parameter is a function that takes two arguments: `entry` and
1426
- * `tree`.
1427
- * @returns The `filter` method is returning a new tree object that contains only the entries that
1428
- * satisfy the given predicate function.
1450
+ * Time Complexity: O(n)
1451
+ * Space Complexity: O(n)
1429
1452
  */
1430
- filter(predicate) {
1453
+ /**
1454
+ * Time Complexity: O(n)
1455
+ * Space Complexity: O(n)
1456
+ *
1457
+ * The `filter` function creates a new tree by iterating over the elements of the current tree and
1458
+ * adding only the elements that satisfy the given predicate function.
1459
+ * @param predicate - The `predicate` parameter is a function that takes three arguments: `value`,
1460
+ * `key`, and `index`. It should return a boolean value indicating whether the pair should be
1461
+ * included in the filtered tree or not.
1462
+ * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value
1463
+ * to be used as the `this` value when executing the `predicate` function. If `thisArg` is provided,
1464
+ * it will be passed as the first argument to the `predicate` function. If `thisArg` is
1465
+ * @returns The `filter` method is returning a new tree object that contains the key-value pairs that
1466
+ * pass the given predicate function.
1467
+ */
1468
+ filter(predicate, thisArg) {
1431
1469
  const newTree = this.createTree();
1470
+ let index = 0;
1432
1471
  for (const [key, value] of this) {
1433
- if (predicate([key, value], this)) {
1472
+ if (predicate.call(thisArg, value, key, index++, this)) {
1434
1473
  newTree.add([key, value]);
1435
1474
  }
1436
1475
  }
1437
1476
  return newTree;
1438
1477
  }
1439
1478
  /**
1440
- * The `map` function creates a new tree by applying a callback function to each entry in the current
1441
- * tree.
1442
- * @param callback - The callback parameter is a function that takes two arguments: entry and tree.
1479
+ * Time Complexity: O(n)
1480
+ * Space Complexity: O(n)
1481
+ */
1482
+ /**
1483
+ * Time Complexity: O(n)
1484
+ * Space Complexity: O(n)
1485
+ *
1486
+ * The `map` function creates a new tree by applying a callback function to each key-value pair in
1487
+ * the original tree.
1488
+ * @param callback - The callback parameter is a function that will be called for each key-value pair
1489
+ * in the tree. It takes four arguments: the value of the current pair, the key of the current pair,
1490
+ * the index of the current pair, and a reference to the tree itself. The callback function should
1491
+ * return a new
1492
+ * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
1493
+ * specify the value of `this` within the callback function. If you pass a value for `thisArg`, it
1494
+ * will be used as the `this` value when the callback function is called. If you don't pass a value
1443
1495
  * @returns The `map` method is returning a new tree object.
1444
1496
  */
1445
- map(callback) {
1497
+ map(callback, thisArg) {
1446
1498
  const newTree = this.createTree();
1499
+ let index = 0;
1447
1500
  for (const [key, value] of this) {
1448
- newTree.add([key, callback([key, value], this)]);
1501
+ newTree.add([key, callback.call(thisArg, value, key, index++, this)]);
1449
1502
  }
1450
1503
  return newTree;
1451
1504
  }
1452
- // TODO Type error, need to return a TREE<NV> that is a value type only for callback function.
1453
- // map<NV>(callback: (entry: [BTNKey, V | undefined], tree: this) => NV) {
1454
- // const newTree = this.createTree();
1455
- // for (const [key, value] of this) {
1456
- // newTree.add(key, callback([key, value], this));
1457
- // }
1458
- // return newTree;
1459
- // }
1460
- /**
1461
- * The `reduce` function iterates over the entries of a tree and applies a callback function to each
1462
- * entry, accumulating a single value.
1463
- * @param callback - The callback parameter is a function that takes three arguments: accumulator,
1464
- * entry, and tree. It is called for each entry in the tree and is used to accumulate a single value
1465
- * based on the logic defined in the callback function.
1466
- * @param {T} initialValue - The initialValue parameter is the initial value of the accumulator. It
1467
- * is the value that will be passed as the first argument to the callback function when reducing the
1468
- * elements of the tree.
1469
- * @returns The `reduce` method is returning the final value of the accumulator after iterating over
1470
- * all the entries in the tree and applying the callback function to each entry.
1471
- */
1472
- reduce(callback, initialValue) {
1473
- let accumulator = initialValue;
1474
- for (const [key, value] of this) {
1475
- accumulator = callback(accumulator, [key, value], this);
1476
- }
1477
- return accumulator;
1478
- }
1479
- /**
1480
- * The above function is an iterator for a binary tree that can be used to traverse the tree in
1481
- * either an iterative or recursive manner.
1482
- * @param node - The `node` parameter represents the current node in the binary tree from which the
1483
- * iteration starts. It is an optional parameter with a default value of `this.root`, which means
1484
- * that if no node is provided, the iteration will start from the root of the binary tree.
1485
- * @returns The `*[Symbol.iterator]` method returns a generator object that yields the keys of the
1486
- * binary tree nodes in a specific order.
1487
- */
1488
- *[Symbol.iterator](node = this.root) {
1489
- if (!node)
1490
- return;
1491
- if (this.iterationType === types_1.IterationType.ITERATIVE) {
1492
- const stack = [];
1493
- let current = node;
1494
- while (current || stack.length > 0) {
1495
- while (current && !isNaN(current.key)) {
1496
- stack.push(current);
1497
- current = current.left;
1498
- }
1499
- current = stack.pop();
1500
- if (current && !isNaN(current.key)) {
1501
- yield [current.key, current.value];
1502
- current = current.right;
1503
- }
1504
- }
1505
- }
1506
- else {
1507
- if (node.left && !isNaN(node.key)) {
1508
- yield* this[Symbol.iterator](node.left);
1509
- }
1510
- yield [node.key, node.value];
1511
- if (node.right && !isNaN(node.key)) {
1512
- yield* this[Symbol.iterator](node.right);
1513
- }
1514
- }
1515
- }
1505
+ // // TODO Type error, need to return a TREE<NV> that is a value type only for callback function.
1506
+ // // map<NV>(callback: (entry: [K, V | undefined], tree: this) => NV) {
1507
+ // // const newTree = this.createTree();
1508
+ // // for (const [key, value] of this) {
1509
+ // // newTree.add(key, callback([key, value], this));
1510
+ // // }
1511
+ // // return newTree;
1512
+ // // }
1513
+ //
1516
1514
  /**
1517
1515
  * The `print` function is used to display a binary tree structure in a visually appealing way.
1518
- * @param {BTNKey | N | null | undefined} [beginRoot=this.root] - The `root` parameter is of type `BTNKey | N | null |
1516
+ * @param {K | N | null | undefined} [beginRoot=this.root] - The `root` parameter is of type `K | N | null |
1519
1517
  * undefined`. It represents the root node of a binary tree. The root node can have one of the
1520
1518
  * following types:
1521
1519
  * @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.
@@ -1542,6 +1540,34 @@ class BinaryTree {
1542
1540
  };
1543
1541
  display(beginRoot);
1544
1542
  }
1543
+ *_getIterator(node = this.root) {
1544
+ if (!node)
1545
+ return;
1546
+ if (this.iterationType === types_1.IterationType.ITERATIVE) {
1547
+ const stack = [];
1548
+ let current = node;
1549
+ while (current || stack.length > 0) {
1550
+ while (current && !isNaN(this.extractor(current.key))) {
1551
+ stack.push(current);
1552
+ current = current.left;
1553
+ }
1554
+ current = stack.pop();
1555
+ if (current && !isNaN(this.extractor(current.key))) {
1556
+ yield [current.key, current.value];
1557
+ current = current.right;
1558
+ }
1559
+ }
1560
+ }
1561
+ else {
1562
+ if (node.left && !isNaN(this.extractor(node.key))) {
1563
+ yield* this[Symbol.iterator](node.left);
1564
+ }
1565
+ yield [node.key, node.value];
1566
+ if (node.right && !isNaN(this.extractor(node.key))) {
1567
+ yield* this[Symbol.iterator](node.right);
1568
+ }
1569
+ }
1570
+ }
1545
1571
  _displayAux(node, options) {
1546
1572
  const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
1547
1573
  const emptyDisplayLayout = [['─'], 1, 0, 0];
@@ -1552,12 +1578,12 @@ class BinaryTree {
1552
1578
  else if (node === undefined && !isShowUndefined) {
1553
1579
  return emptyDisplayLayout;
1554
1580
  }
1555
- else if (node !== null && node !== undefined && isNaN(node.key) && !isShowRedBlackNIL) {
1581
+ else if (node !== null && node !== undefined && isNaN(this.extractor(node.key)) && !isShowRedBlackNIL) {
1556
1582
  return emptyDisplayLayout;
1557
1583
  }
1558
1584
  else if (node !== null && node !== undefined) {
1559
1585
  // Display logic of normal nodes
1560
- const key = node.key, line = isNaN(key) ? 'S' : key.toString(), width = line.length;
1586
+ const key = node.key, line = isNaN(this.extractor(key)) ? 'S' : this.extractor(key).toString(), width = line.length;
1561
1587
  return _buildNodeDisplay(line, width, this._displayAux(node.left, options), this._displayAux(node.right, options));
1562
1588
  }
1563
1589
  else {
@@ -1644,7 +1670,7 @@ class BinaryTree {
1644
1670
  * If the parent node is null, the function also returns undefined.
1645
1671
  */
1646
1672
  _addTo(newNode, parent) {
1647
- if (this.isNodeKey(parent))
1673
+ if (this.isNotNodeInstance(parent))
1648
1674
  parent = this.getNode(parent);
1649
1675
  if (parent) {
1650
1676
  // When all leaf nodes are null, it will no longer be possible to add new entity nodes to this binary tree.