min-heap-typed 1.38.5 → 1.38.6

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.
@@ -126,7 +126,7 @@ class BST extends binary_tree_1.BinaryTree {
126
126
  /**
127
127
  * The `addMany` function is used to efficiently add multiple nodes to a binary search tree while
128
128
  * maintaining balance.
129
- * @param {[BinaryTreeNodeKey | N, N['val']][]} arr - The `arr` parameter in the `addMany` function
129
+ * @param {[BinaryTreeNodeKey | N, N['val']][]} keysOrNodes - The `arr` parameter in the `addMany` function
130
130
  * represents an array of keys or nodes that need to be added to the binary search tree. It can be an
131
131
  * array of `BinaryTreeNodeKey` or `N` (which represents the node type in the binary search tree) or
132
132
  * `null
@@ -208,7 +208,7 @@ class BST extends binary_tree_1.BinaryTree {
208
208
  /**
209
209
  * The function returns the first node in the binary tree that matches the given node property and
210
210
  * callback.
211
- * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter is used to specify the
211
+ * @param {ReturnType<C> | N} identifier - The `nodeProperty` parameter is used to specify the
212
212
  * property of the binary tree node that you want to search for. It can be either a specific key
213
213
  * value (`BinaryTreeNodeKey`) or a custom callback function (`MapCallback<N>`) that determines
214
214
  * whether a node matches the desired property.
@@ -223,9 +223,9 @@ class BST extends binary_tree_1.BinaryTree {
223
223
  * @returns either the first node that matches the given nodeProperty and callback, or null if no
224
224
  * matching node is found.
225
225
  */
226
- get(nodeProperty, callback = this._defaultCallbackByKey, beginRoot = this.root, iterationType = this.iterationType) {
226
+ get(identifier, callback = this._defaultCallbackByKey, beginRoot = this.root, iterationType = this.iterationType) {
227
227
  var _a;
228
- return (_a = this.getNodes(nodeProperty, callback, true, beginRoot, iterationType)[0]) !== null && _a !== void 0 ? _a : null;
228
+ return (_a = this.getNodes(identifier, callback, true, beginRoot, iterationType)[0]) !== null && _a !== void 0 ? _a : null;
229
229
  }
230
230
  /**
231
231
  * The function `lastKey` returns the key of the rightmost node if the comparison result is less
@@ -254,7 +254,7 @@ class BST extends binary_tree_1.BinaryTree {
254
254
  /**
255
255
  * The function `getNodes` retrieves nodes from a binary tree based on a given node property or key,
256
256
  * using either recursive or iterative traversal.
257
- * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter represents the property
257
+ * @param {ReturnType<C> | N} identifier - The `nodeProperty` parameter represents the property
258
258
  * of the binary tree node that you want to search for. It can be either a `BinaryTreeNodeKey` or a
259
259
  * generic type `N`.
260
260
  * @param callback - The `callback` parameter is a function that takes a node as input and returns a
@@ -272,14 +272,14 @@ class BST extends binary_tree_1.BinaryTree {
272
272
  * traverse the binary tree. It can have one of the following values:
273
273
  * @returns an array of nodes (N[]).
274
274
  */
275
- getNodes(nodeProperty, callback = this._defaultCallbackByKey, onlyOne = false, beginRoot = this.root, iterationType = this.iterationType) {
275
+ getNodes(identifier, callback = this._defaultCallbackByKey, onlyOne = false, beginRoot = this.root, iterationType = this.iterationType) {
276
276
  if (!beginRoot)
277
277
  return [];
278
278
  const ans = [];
279
279
  if (iterationType === types_1.IterationType.RECURSIVE) {
280
280
  const _traverse = (cur) => {
281
281
  const callbackResult = callback(cur);
282
- if (callbackResult === nodeProperty) {
282
+ if (callbackResult === identifier) {
283
283
  ans.push(cur);
284
284
  if (onlyOne)
285
285
  return;
@@ -288,9 +288,9 @@ class BST extends binary_tree_1.BinaryTree {
288
288
  return;
289
289
  // TODO potential bug
290
290
  if (callback === this._defaultCallbackByKey) {
291
- if (this._compare(cur.key, nodeProperty) === types_1.CP.gt)
291
+ if (this._compare(cur.key, identifier) === types_1.CP.gt)
292
292
  cur.left && _traverse(cur.left);
293
- if (this._compare(cur.key, nodeProperty) === types_1.CP.lt)
293
+ if (this._compare(cur.key, identifier) === types_1.CP.lt)
294
294
  cur.right && _traverse(cur.right);
295
295
  }
296
296
  else {
@@ -306,16 +306,16 @@ class BST extends binary_tree_1.BinaryTree {
306
306
  const cur = queue.shift();
307
307
  if (cur) {
308
308
  const callbackResult = callback(cur);
309
- if (callbackResult === nodeProperty) {
309
+ if (callbackResult === identifier) {
310
310
  ans.push(cur);
311
311
  if (onlyOne)
312
312
  return ans;
313
313
  }
314
314
  // TODO potential bug
315
315
  if (callback === this._defaultCallbackByKey) {
316
- if (this._compare(cur.key, nodeProperty) === types_1.CP.gt)
316
+ if (this._compare(cur.key, identifier) === types_1.CP.gt)
317
317
  cur.left && queue.push(cur.left);
318
- if (this._compare(cur.key, nodeProperty) === types_1.CP.lt)
318
+ if (this._compare(cur.key, identifier) === types_1.CP.lt)
319
319
  cur.right && queue.push(cur.right);
320
320
  }
321
321
  else {
@@ -337,7 +337,7 @@ class BST extends binary_tree_1.BinaryTree {
337
337
  * @param {CP} lesserOrGreater - The `lesserOrGreater` parameter is used to determine whether to
338
338
  * traverse nodes that are lesser than, greater than, or equal to the `targetNode`. It can take one
339
339
  * of the following values:
340
- * @param {N | BinaryTreeNodeKey | null} targetNode - The `targetNode` parameter in the
340
+ * @param {BinaryTreeNodeKey | N | null} targetNode - The `targetNode` parameter in the
341
341
  * `lesserOrGreaterTraverse` function is used to specify the node from which the traversal should
342
342
  * start. It can be either a reference to a specific node (`N`), the key of a node
343
343
  * (`BinaryTreeNodeKey`), or `null` to
@@ -6,7 +6,7 @@
6
6
  * @license MIT License
7
7
  */
8
8
  import type { BinaryTreeNodeKey, TreeMultisetNodeNested, TreeMultisetOptions } from '../../types';
9
- import { BinaryTreeDeletedResult, IterationType } from '../../types';
9
+ import { BinaryTreeDeletedResult, IterationType, MapCallback } from '../../types';
10
10
  import { IBinaryTree } from '../../interfaces';
11
11
  import { AVLTree, AVLTreeNode } from './avl-tree';
12
12
  export declare class TreeMultisetNode<V = any, FAMILY extends TreeMultisetNode<V, FAMILY> = TreeMultisetNodeNested<V>> extends AVLTreeNode<V, FAMILY> {
@@ -92,16 +92,20 @@ export declare class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = Tree
92
92
  /**
93
93
  * The `delete` function in a binary search tree deletes a node from the tree and returns the deleted
94
94
  * node along with the parent node that needs to be balanced.
95
- * @param {N | BinaryTreeNodeKey} nodeOrKey - The `nodeOrKey` parameter can be either a node object
96
- * (`N`) or a key value (`BinaryTreeNodeKey`). It represents the node or key that needs to be deleted
97
- * from the binary tree.
95
+ * @param {ReturnType<C>} identifier - The `identifier` parameter is either a
96
+ * `BinaryTreeNodeKey` or a generic type `N`. It represents the property of the node that we are
97
+ * searching for. It can be a specific key value or any other property of the node.
98
+ * @param callback - The `callback` parameter is a function that takes a node as input and returns a
99
+ * value. This value is compared with the `identifier` parameter to determine if the node should be
100
+ * included in the result. The `callback` parameter has a default value of
101
+ * `this._defaultCallbackByKey`
98
102
  * @param [ignoreCount=false] - A boolean flag indicating whether to ignore the count of the node
99
103
  * being deleted. If set to true, the count of the node will not be considered and the node will be
100
104
  * deleted regardless of its count. If set to false (default), the count of the node will be
101
105
  * decremented by 1 and
102
106
  * @returns The method `delete` returns an array of `BinaryTreeDeletedResult<N>` objects.
103
107
  */
104
- delete(nodeOrKey: N | BinaryTreeNodeKey, ignoreCount?: boolean): BinaryTreeDeletedResult<N>[];
108
+ delete<C extends MapCallback<N>>(identifier: ReturnType<C>, callback?: C, ignoreCount?: boolean): BinaryTreeDeletedResult<N>[];
105
109
  /**
106
110
  * The clear() function clears the contents of a data structure and sets the count to zero.
107
111
  */
@@ -245,20 +245,24 @@ class TreeMultiset extends avl_tree_1.AVLTree {
245
245
  /**
246
246
  * The `delete` function in a binary search tree deletes a node from the tree and returns the deleted
247
247
  * node along with the parent node that needs to be balanced.
248
- * @param {N | BinaryTreeNodeKey} nodeOrKey - The `nodeOrKey` parameter can be either a node object
249
- * (`N`) or a key value (`BinaryTreeNodeKey`). It represents the node or key that needs to be deleted
250
- * from the binary tree.
248
+ * @param {ReturnType<C>} identifier - The `identifier` parameter is either a
249
+ * `BinaryTreeNodeKey` or a generic type `N`. It represents the property of the node that we are
250
+ * searching for. It can be a specific key value or any other property of the node.
251
+ * @param callback - The `callback` parameter is a function that takes a node as input and returns a
252
+ * value. This value is compared with the `identifier` parameter to determine if the node should be
253
+ * included in the result. The `callback` parameter has a default value of
254
+ * `this._defaultCallbackByKey`
251
255
  * @param [ignoreCount=false] - A boolean flag indicating whether to ignore the count of the node
252
256
  * being deleted. If set to true, the count of the node will not be considered and the node will be
253
257
  * deleted regardless of its count. If set to false (default), the count of the node will be
254
258
  * decremented by 1 and
255
259
  * @returns The method `delete` returns an array of `BinaryTreeDeletedResult<N>` objects.
256
260
  */
257
- delete(nodeOrKey, ignoreCount = false) {
261
+ delete(identifier, callback = this._defaultCallbackByKey, ignoreCount = false) {
258
262
  const bstDeletedResult = [];
259
263
  if (!this.root)
260
264
  return bstDeletedResult;
261
- const curr = this.get(nodeOrKey);
265
+ const curr = this.get(identifier, callback);
262
266
  if (!curr)
263
267
  return bstDeletedResult;
264
268
  const parent = (curr === null || curr === void 0 ? void 0 : curr.parent) ? curr.parent : null;
@@ -1,7 +1,7 @@
1
1
  import { BinaryTreeNode } from '../data-structures';
2
- import { BinaryTreeDeletedResult, BinaryTreeNodeKey } from '../types';
2
+ import { BinaryTreeDeletedResult, BinaryTreeNodeKey, MapCallback } from '../types';
3
3
  export interface IBinaryTree<N extends BinaryTreeNode<N['val'], N>> {
4
4
  createNode(key: BinaryTreeNodeKey, val?: N['val']): N;
5
5
  add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val']): N | null | undefined;
6
- delete(nodeOrKey: N | BinaryTreeNodeKey): BinaryTreeDeletedResult<N>[];
6
+ delete<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C): BinaryTreeDeletedResult<N>[];
7
7
  }
@@ -1,6 +1,8 @@
1
+ import { BinaryTreeNodeKey } from './data-structures';
1
2
  export type Comparator<T> = (a: T, b: T) => number;
2
3
  export type DFSOrderPattern = 'pre' | 'in' | 'post';
3
4
  export type MapCallback<N, D = any> = (node: N) => D;
5
+ export type DefaultMapCallback<N, D = BinaryTreeNodeKey> = (node: N) => D;
4
6
  export type MapCallbackReturn<N> = ReturnType<MapCallback<N>>;
5
7
  export declare enum CP {
6
8
  lt = "lt",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "min-heap-typed",
3
- "version": "1.38.5",
3
+ "version": "1.38.6",
4
4
  "description": "Min Heap. Javascript & Typescript Data Structure.",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -131,6 +131,6 @@
131
131
  "typescript": "^4.9.5"
132
132
  },
133
133
  "dependencies": {
134
- "data-structure-typed": "^1.38.4"
134
+ "data-structure-typed": "^1.38.6"
135
135
  }
136
136
  }
@@ -8,6 +8,7 @@
8
8
  import {BST, BSTNode} from './bst';
9
9
  import type {AVLTreeNodeNested, AVLTreeOptions, BinaryTreeDeletedResult, BinaryTreeNodeKey} from '../../types';
10
10
  import {IBinaryTree} from '../../interfaces';
11
+ import {MapCallback} from '../../types';
11
12
 
12
13
  export class AVLTreeNode<V = any, FAMILY extends AVLTreeNode<V, FAMILY> = AVLTreeNodeNested<V>> extends BSTNode<
13
14
  V,
@@ -64,12 +65,20 @@ export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode> extends B
64
65
  /**
65
66
  * The function overrides the delete method of a binary tree and balances the tree after deleting a
66
67
  * node if necessary.
67
- * @param {N | BinaryTreeNodeKey} nodeOrKey - The `nodeOrKey` parameter can be either a node object
68
- * (`N`) or a key value (`BinaryTreeNodeKey`).
68
+ * @param {ReturnType<C>} identifier - The `identifier` parameter is either a
69
+ * `BinaryTreeNodeKey` or a generic type `N`. It represents the property of the node that we are
70
+ * searching for. It can be a specific key value or any other property of the node.
71
+ * @param callback - The `callback` parameter is a function that takes a node as input and returns a
72
+ * value. This value is compared with the `identifier` parameter to determine if the node should be
73
+ * included in the result. The `callback` parameter has a default value of
74
+ * `this._defaultCallbackByKey`
69
75
  * @returns The method is returning an array of `BinaryTreeDeletedResult<N>` objects.
70
76
  */
71
- override delete(nodeOrKey: N | BinaryTreeNodeKey): BinaryTreeDeletedResult<N>[] {
72
- const deletedResults = super.delete(nodeOrKey);
77
+ override delete<C extends MapCallback<N>>(
78
+ identifier: ReturnType<C>,
79
+ callback: C = this._defaultCallbackByKey as C
80
+ ): BinaryTreeDeletedResult<N>[] {
81
+ const deletedResults = super.delete(identifier, callback);
73
82
  for (const {needBalanced} of deletedResults) {
74
83
  if (needBalanced) {
75
84
  this._balancePath(needBalanced);
@@ -15,7 +15,7 @@ import type {
15
15
  MapCallback,
16
16
  MapCallbackReturn
17
17
  } from '../../types';
18
- import {BinaryTreeDeletedResult, DFSOrderPattern, FamilyPosition, IterationType} from '../../types';
18
+ import {BinaryTreeDeletedResult, DefaultMapCallback, DFSOrderPattern, FamilyPosition, IterationType} from '../../types';
19
19
  import {IBinaryTree} from '../../interfaces';
20
20
  import {trampoline} from '../../utils';
21
21
  import {Queue} from '../queue';
@@ -97,29 +97,17 @@ export class BinaryTreeNode<V = any, FAMILY extends BinaryTreeNode<V, FAMILY> =
97
97
  */
98
98
  get familyPosition(): FamilyPosition {
99
99
  const that = this as unknown as FAMILY;
100
- if (that.parent) {
101
- if (that.parent.left === that) {
102
- if (that.left || that.right) {
103
- return FamilyPosition.ROOT_LEFT;
104
- } else {
105
- return FamilyPosition.LEFT;
106
- }
107
- } else if (that.parent.right === that) {
108
- if (that.left || that.right) {
109
- return FamilyPosition.ROOT_RIGHT;
110
- } else {
111
- return FamilyPosition.RIGHT;
112
- }
113
- } else {
114
- return FamilyPosition.MAL_NODE;
115
- }
116
- } else {
117
- if (that.left || that.right) {
118
- return FamilyPosition.ROOT;
119
- } else {
120
- return FamilyPosition.ISOLATED;
121
- }
100
+ if (!this.parent) {
101
+ return this.left || this.right ? FamilyPosition.ROOT : FamilyPosition.ISOLATED;
102
+ }
103
+
104
+ if (this.parent.left === that) {
105
+ return this.left || this.right ? FamilyPosition.ROOT_LEFT : FamilyPosition.LEFT;
106
+ } else if (this.parent.right === that) {
107
+ return this.left || this.right ? FamilyPosition.ROOT_RIGHT : FamilyPosition.RIGHT;
122
108
  }
109
+
110
+ return FamilyPosition.MAL_NODE;
123
111
  }
124
112
  }
125
113
 
@@ -234,7 +222,8 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
234
222
  return;
235
223
  }
236
224
 
237
- const existNode = keyOrNode ? this.get(keyOrNode, this._defaultCallbackByKey) : undefined;
225
+ const key = typeof keyOrNode === 'number' ? keyOrNode : keyOrNode ? keyOrNode.key : undefined;
226
+ const existNode = key !== undefined ? this.get(key, this._defaultCallbackByKey) : undefined;
238
227
 
239
228
  if (this.root) {
240
229
  if (existNode) {
@@ -267,24 +256,18 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
267
256
  */
268
257
  addMany(keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], values?: N['val'][]): (N | null | undefined)[] {
269
258
  // TODO not sure addMany not be run multi times
270
- const inserted: (N | null | undefined)[] = [];
271
-
272
- for (let i = 0; i < keysOrNodes.length; i++) {
273
- const keyOrNode = keysOrNodes[i];
259
+ return keysOrNodes.map((keyOrNode, i) => {
274
260
  if (keyOrNode instanceof BinaryTreeNode) {
275
- inserted.push(this.add(keyOrNode.key, keyOrNode.val));
276
- continue;
261
+ return this.add(keyOrNode.key, keyOrNode.val);
277
262
  }
278
263
 
279
264
  if (keyOrNode === null) {
280
- inserted.push(this.add(null));
281
- continue;
265
+ return this.add(null);
282
266
  }
283
267
 
284
268
  const val = values?.[i];
285
- inserted.push(this.add(keyOrNode, val));
286
- }
287
- return inserted;
269
+ return this.add(keyOrNode, val);
270
+ });
288
271
  }
289
272
 
290
273
  /**
@@ -301,19 +284,33 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
301
284
  return keysOrNodes.length === this.addMany(keysOrNodes, data).length;
302
285
  }
303
286
 
287
+ delete<C extends MapCallback<N>>(identifier: ReturnType<C> | N): BinaryTreeDeletedResult<N>[];
288
+
289
+ delete<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C): BinaryTreeDeletedResult<N>[];
290
+
304
291
  /**
305
292
  * The `delete` function removes a node from a binary search tree and returns the deleted node along
306
293
  * with the parent node that needs to be balanced.
307
- * @param {N | BinaryTreeNodeKey} nodeOrKey - The `nodeOrKey` parameter can be either a node (`N`) or
308
294
  * a key (`BinaryTreeNodeKey`). If it is a key, the function will find the corresponding node in the
309
295
  * binary tree.
310
296
  * @returns an array of `BinaryTreeDeletedResult<N>` objects.
297
+ * @param {ReturnType<C>} identifier - The `identifier` parameter is either a
298
+ * `BinaryTreeNodeKey` or a generic type `N`. It represents the property of the node that we are
299
+ * searching for. It can be a specific key value or any other property of the node.
300
+ * @param callback - The `callback` parameter is a function that takes a node as input and returns a
301
+ * value. This value is compared with the `identifier` parameter to determine if the node should be
302
+ * included in the result. The `callback` parameter has a default value of
303
+ * `this._defaultCallbackByKey`, which
311
304
  */
312
- delete(nodeOrKey: N | BinaryTreeNodeKey): BinaryTreeDeletedResult<N>[] {
305
+ delete<C extends MapCallback<N>>(
306
+ identifier: ReturnType<C> | N,
307
+ callback: C = this._defaultCallbackByKey as C
308
+ ): BinaryTreeDeletedResult<N>[] {
313
309
  const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
314
310
  if (!this.root) return bstDeletedResult;
311
+ if (identifier instanceof BinaryTreeNode) callback = (node => node) as C;
315
312
 
316
- const curr: N | null = typeof nodeOrKey === 'number' ? this.get(nodeOrKey) : nodeOrKey;
313
+ const curr = this.get(identifier, callback);
317
314
  if (!curr) return bstDeletedResult;
318
315
 
319
316
  const parent: N | null = curr?.parent ? curr.parent : null;
@@ -354,16 +351,16 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
354
351
  /**
355
352
  * The function `getDepth` calculates the depth of a given node in a binary tree relative to a
356
353
  * specified root node.
357
- * @param {N | BinaryTreeNodeKey | null} distNode - The `distNode` parameter represents the node
354
+ * @param {BinaryTreeNodeKey | N | null} distNode - The `distNode` parameter represents the node
358
355
  * whose depth we want to find in the binary tree. It can be either a node object (`N`), a key value
359
356
  * of the node (`BinaryTreeNodeKey`), or `null`.
360
- * @param {N | BinaryTreeNodeKey | null} beginRoot - The `beginRoot` parameter represents the
357
+ * @param {BinaryTreeNodeKey | N | null} beginRoot - The `beginRoot` parameter represents the
361
358
  * starting node from which we want to calculate the depth. It can be either a node object or the key
362
359
  * of a node in the binary tree. If no value is provided for `beginRoot`, it defaults to the root
363
360
  * node of the binary tree.
364
361
  * @returns the depth of the `distNode` relative to the `beginRoot`.
365
362
  */
366
- getDepth(distNode: N | BinaryTreeNodeKey | null, beginRoot: N | BinaryTreeNodeKey | null = this.root): number {
363
+ getDepth(distNode: BinaryTreeNodeKey | N | null, beginRoot: BinaryTreeNodeKey | N | null = this.root): number {
367
364
  if (typeof distNode === 'number') distNode = this.get(distNode);
368
365
  if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
369
366
  let depth = 0;
@@ -380,7 +377,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
380
377
  /**
381
378
  * The `getHeight` function calculates the maximum height of a binary tree using either recursive or
382
379
  * iterative approach.
383
- * @param {N | BinaryTreeNodeKey | null} beginRoot - The `beginRoot` parameter represents the
380
+ * @param {BinaryTreeNodeKey | N | null} beginRoot - The `beginRoot` parameter represents the
384
381
  * starting node from which the height of the binary tree is calculated. It can be either a node
385
382
  * object (`N`), a key value of a node in the tree (`BinaryTreeNodeKey`), or `null` if no starting
386
383
  * node is specified. If `
@@ -389,7 +386,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
389
386
  * possible values:
390
387
  * @returns the height of the binary tree.
391
388
  */
392
- getHeight(beginRoot: N | BinaryTreeNodeKey | null = this.root, iterationType = this.iterationType): number {
389
+ getHeight(beginRoot: BinaryTreeNodeKey | N | null = this.root, iterationType = this.iterationType): number {
393
390
  if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
394
391
  if (!beginRoot) return -1;
395
392
 
@@ -491,18 +488,41 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
491
488
  return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
492
489
  }
493
490
 
491
+ getNodes<C extends MapCallback<N>>(identifier: ReturnType<C> | N): N[];
492
+
493
+ getNodes<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C): N[];
494
+
495
+ getNodes<C extends MapCallback<N>>(identifier: ReturnType<C> | N, onlyOne: boolean): N[];
496
+
497
+ getNodes<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C, onlyOne: boolean): N[];
498
+
499
+ getNodes<C extends MapCallback<N>>(
500
+ identifier: ReturnType<C> | N,
501
+ callback: C,
502
+ onlyOne: boolean,
503
+ beginRoot: N | null
504
+ ): N[];
505
+
506
+ getNodes<C extends MapCallback<N>>(
507
+ identifier: ReturnType<C> | N,
508
+ callback: C,
509
+ onlyOne: boolean,
510
+ beginRoot: N | null,
511
+ iterationType: IterationType
512
+ ): N[];
513
+
494
514
  /**
495
515
  * The function `getNodes` returns an array of nodes that match a given node property, using either
496
516
  * recursive or iterative traversal.
497
- * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter is either a
517
+ * @param {ReturnType<C>} identifier - The `identifier` parameter is either a
498
518
  * `BinaryTreeNodeKey` or a generic type `N`. It represents the property of the node that we are
499
519
  * searching for. It can be a specific key value or any other property of the node.
500
520
  * @param callback - The `callback` parameter is a function that takes a node as input and returns a
501
- * value. This value is compared with the `nodeProperty` parameter to determine if the node should be
521
+ * value. This value is compared with the `identifier` parameter to determine if the node should be
502
522
  * included in the result. The `callback` parameter has a default value of
503
523
  * `this._defaultCallbackByKey`, which
504
524
  * @param [onlyOne=false] - A boolean value indicating whether to stop searching after finding the
505
- * first node that matches the nodeProperty. If set to true, the function will return an array with
525
+ * first node that matches the identifier. If set to true, the function will return an array with
506
526
  * only one element (or an empty array if no matching node is found). If set to false (default), the
507
527
  * function will continue searching for all
508
528
  * @param {N | null} beginRoot - The `beginRoot` parameter is the starting node from which the
@@ -512,20 +532,20 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
512
532
  * traverse the binary tree. It can have two possible values:
513
533
  * @returns The function `getNodes` returns an array of nodes (`N[]`).
514
534
  */
515
- getNodes<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
516
- nodeProperty: BinaryTreeNodeKey | N,
535
+ getNodes<C extends MapCallback<N>>(
536
+ identifier: ReturnType<C> | N,
517
537
  callback: C = this._defaultCallbackByKey as C,
518
538
  onlyOne = false,
519
539
  beginRoot: N | null = this.root,
520
540
  iterationType = this.iterationType
521
541
  ): N[] {
522
542
  if (!beginRoot) return [];
523
-
543
+ if (identifier instanceof BinaryTreeNode) callback = (node => node) as C;
524
544
  const ans: N[] = [];
525
545
 
526
546
  if (iterationType === IterationType.RECURSIVE) {
527
547
  const _traverse = (cur: N) => {
528
- if (callback(cur) === nodeProperty) {
548
+ if (callback(cur) === identifier) {
529
549
  ans.push(cur);
530
550
  if (onlyOne) return;
531
551
  }
@@ -540,7 +560,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
540
560
  while (queue.size > 0) {
541
561
  const cur = queue.shift();
542
562
  if (cur) {
543
- if (callback(cur) === nodeProperty) {
563
+ if (callback(cur) === identifier) {
544
564
  ans.push(cur);
545
565
  if (onlyOne) return ans;
546
566
  }
@@ -553,9 +573,17 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
553
573
  return ans;
554
574
  }
555
575
 
576
+ has<C extends MapCallback<N>>(identifier: ReturnType<C> | N): boolean;
577
+
578
+ has<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C): boolean;
579
+
580
+ has<C extends MapCallback<N>>(identifier: ReturnType<C> | N, beginRoot: N | null): boolean;
581
+
582
+ has<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C, beginRoot: N | null): boolean;
583
+
556
584
  /**
557
585
  * The function checks if a binary tree has a node with a given property or key.
558
- * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter is the key or value of
586
+ * @param {BinaryTreeNodeKey | N} identifier - The `identifier` parameter is the key or value of
559
587
  * the node that you want to find in the binary tree. It can be either a `BinaryTreeNodeKey` or a
560
588
  * generic type `N`.
561
589
  * @param callback - The `callback` parameter is a function that is used to determine whether a node
@@ -570,19 +598,35 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
570
598
  * performed when searching for nodes in the binary tree. It can have one of the following values:
571
599
  * @returns a boolean value.
572
600
  */
573
- has<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
574
- nodeProperty: BinaryTreeNodeKey | N,
601
+ has<C extends MapCallback<N>>(
602
+ identifier: ReturnType<C> | N,
575
603
  callback: C = this._defaultCallbackByKey as C,
576
604
  beginRoot = this.root,
577
605
  iterationType = this.iterationType
578
606
  ): boolean {
607
+ if (identifier instanceof BinaryTreeNode) callback = (node => node) as C;
579
608
  // TODO may support finding node by value equal
580
- return this.getNodes(nodeProperty, callback, true, beginRoot, iterationType).length > 0;
609
+ return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
581
610
  }
582
611
 
612
+ get<C extends MapCallback<N>>(identifier: ReturnType<C> | N): N | null;
613
+
614
+ get<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C): N | null;
615
+
616
+ get<C extends MapCallback<N>>(identifier: ReturnType<C> | N, beginRoot: N | null): N | null;
617
+
618
+ get<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C, beginRoot: N | null): N | null;
619
+
620
+ get<C extends MapCallback<N>>(
621
+ identifier: ReturnType<C> | N,
622
+ callback: C,
623
+ beginRoot: N | null,
624
+ iterationType: IterationType
625
+ ): N | null;
626
+
583
627
  /**
584
628
  * The function `get` returns the first node in a binary tree that matches the given property or key.
585
- * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter is the key or value of
629
+ * @param {BinaryTreeNodeKey | N} identifier - The `identifier` parameter is the key or value of
586
630
  * the node that you want to find in the binary tree. It can be either a `BinaryTreeNodeKey` or `N`
587
631
  * type.
588
632
  * @param callback - The `callback` parameter is a function that is used to determine whether a node
@@ -595,14 +639,15 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
595
639
  * performed when searching for a node in the binary tree. It can have one of the following values:
596
640
  * @returns either the found node (of type N) or null if no node is found.
597
641
  */
598
- get<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
599
- nodeProperty: BinaryTreeNodeKey | N,
642
+ get<C extends MapCallback<N>>(
643
+ identifier: ReturnType<C> | N,
600
644
  callback: C = this._defaultCallbackByKey as C,
601
645
  beginRoot = this.root,
602
646
  iterationType = this.iterationType
603
647
  ): N | null {
648
+ if (identifier instanceof BinaryTreeNode) callback = (node => node) as C;
604
649
  // TODO may support finding node by value equal
605
- return this.getNodes(nodeProperty, callback, true, beginRoot, iterationType)[0] ?? null;
650
+ return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;
606
651
  }
607
652
 
608
653
  /**
@@ -631,7 +676,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
631
676
  /**
632
677
  * The function `getLeftMost` returns the leftmost node in a binary tree, either using recursive or
633
678
  * iterative traversal.
634
- * @param {N | BinaryTreeNodeKey | null} beginRoot - The `beginRoot` parameter is the starting point
679
+ * @param {BinaryTreeNodeKey | N | null} beginRoot - The `beginRoot` parameter is the starting point
635
680
  * for finding the leftmost node in a binary tree. It can be either a node object (`N`), a key value
636
681
  * of a node (`BinaryTreeNodeKey`), or `null` if the tree is empty.
637
682
  * @param iterationType - The `iterationType` parameter is used to determine the type of iteration to
@@ -639,7 +684,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
639
684
  * @returns The function `getLeftMost` returns the leftmost node (`N`) in a binary tree. If there is
640
685
  * no leftmost node, it returns `null`.
641
686
  */
642
- getLeftMost(beginRoot: N | BinaryTreeNodeKey | null = this.root, iterationType = this.iterationType): N | null {
687
+ getLeftMost(beginRoot: BinaryTreeNodeKey | N | null = this.root, iterationType = this.iterationType): N | null {
643
688
  if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
644
689
 
645
690
  if (!beginRoot) return beginRoot;
@@ -754,16 +799,16 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
754
799
  * subtree traversal. It takes a single argument, which is the current node being traversed, and
755
800
  * returns a value. The return values from each callback invocation will be collected and returned as
756
801
  * an array.
757
- * @param {N | BinaryTreeNodeKey | null} beginRoot - The `beginRoot` parameter is the starting point
802
+ * @param {BinaryTreeNodeKey | N | null} beginRoot - The `beginRoot` parameter is the starting point
758
803
  * for traversing the subtree. It can be either a node object, a key value of a node, or `null` to
759
804
  * start from the root of the tree.
760
805
  * @param iterationType - The `iterationType` parameter determines the type of traversal to be
761
806
  * performed on the binary tree. It can have two possible values:
762
807
  * @returns The function `subTreeTraverse` returns an array of `MapCallbackReturn<N>`.
763
808
  */
764
- subTreeTraverse<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
809
+ subTreeTraverse<C extends MapCallback<N>>(
765
810
  callback: C = this._defaultCallbackByKey as C,
766
- beginRoot: N | BinaryTreeNodeKey | null = this.root,
811
+ beginRoot: BinaryTreeNodeKey | N | null = this.root,
767
812
  iterationType = this.iterationType
768
813
  ): ReturnType<C>[] {
769
814
  if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
@@ -808,7 +853,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
808
853
  * iteration used in the depth-first search algorithm. It can have two possible values:
809
854
  * @returns The function `dfs` returns an array of `MapCallbackReturn<N>` values.
810
855
  */
811
- dfs<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
856
+ dfs<C extends MapCallback<N>>(
812
857
  callback: C = this._defaultCallbackByKey as C,
813
858
  pattern: DFSOrderPattern = 'in',
814
859
  beginRoot: N | null = this.root,
@@ -886,7 +931,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
886
931
  * breadth-first search. It takes a node of type `N` as its argument and returns a value of type
887
932
  * `BFSCallbackReturn<N>`. The default value for this parameter is `this._defaultCallbackByKey
888
933
  * @param {boolean} [withLevel=false] - The `withLevel` parameter is a boolean flag that determines
889
- * whether or not to include the level of each node in the callback function. If `withLevel` is set
934
+ * whether to include the level of each node in the callback function. If `withLevel` is set
890
935
  * to `true`, the level of each node will be passed as an argument to the callback function. If
891
936
  * `withLevel` is
892
937
  * @param {N | null} beginRoot - The `beginRoot` parameter is the starting node for the breadth-first
@@ -964,7 +1009,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
964
1009
  * `beginRoot` is `null`, an empty array will be returned.
965
1010
  * @returns The `morris` function returns an array of `MapCallbackReturn<N>` values.
966
1011
  */
967
- morris<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
1012
+ morris<C extends MapCallback<N>>(
968
1013
  callback: C = this._defaultCallbackByKey as C,
969
1014
  pattern: DFSOrderPattern = 'in',
970
1015
  beginRoot: N | null = this.root
@@ -1077,8 +1122,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
1077
1122
  * the tree's structure should be restored to its original state to maintain the tree's integrity.
1078
1123
  * This is because the purpose of the Morris algorithm is to save space rather than permanently alter the tree's shape.
1079
1124
  */
1080
-
1081
- protected _defaultCallbackByKey: (node: N) => number = node => node.key;
1125
+ protected _defaultCallbackByKey: DefaultMapCallback<N> = node => node.key;
1082
1126
 
1083
1127
  /**
1084
1128
  * The function `_addTo` adds a new node to a binary tree if there is an available position.