min-heap-typed 1.38.4 → 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.
@@ -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.
@@ -132,7 +132,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
132
132
  /**
133
133
  * The `addMany` function is used to efficiently add multiple nodes to a binary search tree while
134
134
  * maintaining balance.
135
- * @param {[BinaryTreeNodeKey | N, N['val']][]} arr - The `arr` parameter in the `addMany` function
135
+ * @param {[BinaryTreeNodeKey | N, N['val']][]} keysOrNodes - The `arr` parameter in the `addMany` function
136
136
  * represents an array of keys or nodes that need to be added to the binary search tree. It can be an
137
137
  * array of `BinaryTreeNodeKey` or `N` (which represents the node type in the binary search tree) or
138
138
  * `null
@@ -223,7 +223,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
223
223
  /**
224
224
  * The function returns the first node in the binary tree that matches the given node property and
225
225
  * callback.
226
- * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter is used to specify the
226
+ * @param {ReturnType<C> | N} identifier - The `nodeProperty` parameter is used to specify the
227
227
  * property of the binary tree node that you want to search for. It can be either a specific key
228
228
  * value (`BinaryTreeNodeKey`) or a custom callback function (`MapCallback<N>`) that determines
229
229
  * whether a node matches the desired property.
@@ -238,13 +238,13 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
238
238
  * @returns either the first node that matches the given nodeProperty and callback, or null if no
239
239
  * matching node is found.
240
240
  */
241
- override get<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
242
- nodeProperty: BinaryTreeNodeKey | N,
241
+ override get<C extends MapCallback<N>>(
242
+ identifier: ReturnType<C> | N,
243
243
  callback: C = this._defaultCallbackByKey as C,
244
244
  beginRoot = this.root,
245
245
  iterationType = this.iterationType
246
246
  ): N | null {
247
- return this.getNodes(nodeProperty, callback, true, beginRoot, iterationType)[0] ?? null;
247
+ return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;
248
248
  }
249
249
 
250
250
  /**
@@ -271,7 +271,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
271
271
  /**
272
272
  * The function `getNodes` retrieves nodes from a binary tree based on a given node property or key,
273
273
  * using either recursive or iterative traversal.
274
- * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter represents the property
274
+ * @param {ReturnType<C> | N} identifier - The `nodeProperty` parameter represents the property
275
275
  * of the binary tree node that you want to search for. It can be either a `BinaryTreeNodeKey` or a
276
276
  * generic type `N`.
277
277
  * @param callback - The `callback` parameter is a function that takes a node as input and returns a
@@ -289,8 +289,8 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
289
289
  * traverse the binary tree. It can have one of the following values:
290
290
  * @returns an array of nodes (N[]).
291
291
  */
292
- override getNodes<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
293
- nodeProperty: BinaryTreeNodeKey | N,
292
+ override getNodes<C extends MapCallback<N>>(
293
+ identifier: ReturnType<C> | N,
294
294
  callback: C = this._defaultCallbackByKey as C,
295
295
  onlyOne = false,
296
296
  beginRoot: N | null = this.root,
@@ -302,7 +302,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
302
302
  if (iterationType === IterationType.RECURSIVE) {
303
303
  const _traverse = (cur: N) => {
304
304
  const callbackResult = callback(cur);
305
- if (callbackResult === nodeProperty) {
305
+ if (callbackResult === identifier) {
306
306
  ans.push(cur);
307
307
  if (onlyOne) return;
308
308
  }
@@ -310,8 +310,8 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
310
310
  if (!cur.left && !cur.right) return;
311
311
  // TODO potential bug
312
312
  if (callback === this._defaultCallbackByKey) {
313
- if (this._compare(cur.key, nodeProperty as number) === CP.gt) cur.left && _traverse(cur.left);
314
- if (this._compare(cur.key, nodeProperty as number) === CP.lt) cur.right && _traverse(cur.right);
313
+ if (this._compare(cur.key, identifier as number) === CP.gt) cur.left && _traverse(cur.left);
314
+ if (this._compare(cur.key, identifier as number) === CP.lt) cur.right && _traverse(cur.right);
315
315
  } else {
316
316
  cur.left && _traverse(cur.left);
317
317
  cur.right && _traverse(cur.right);
@@ -325,14 +325,14 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
325
325
  const cur = queue.shift();
326
326
  if (cur) {
327
327
  const callbackResult = callback(cur);
328
- if (callbackResult === nodeProperty) {
328
+ if (callbackResult === identifier) {
329
329
  ans.push(cur);
330
330
  if (onlyOne) return ans;
331
331
  }
332
332
  // TODO potential bug
333
333
  if (callback === this._defaultCallbackByKey) {
334
- if (this._compare(cur.key, nodeProperty as number) === CP.gt) cur.left && queue.push(cur.left);
335
- if (this._compare(cur.key, nodeProperty as number) === CP.lt) cur.right && queue.push(cur.right);
334
+ if (this._compare(cur.key, identifier as number) === CP.gt) cur.left && queue.push(cur.left);
335
+ if (this._compare(cur.key, identifier as number) === CP.lt) cur.right && queue.push(cur.right);
336
336
  } else {
337
337
  cur.left && queue.push(cur.left);
338
338
  cur.right && queue.push(cur.right);
@@ -355,7 +355,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
355
355
  * @param {CP} lesserOrGreater - The `lesserOrGreater` parameter is used to determine whether to
356
356
  * traverse nodes that are lesser than, greater than, or equal to the `targetNode`. It can take one
357
357
  * of the following values:
358
- * @param {N | BinaryTreeNodeKey | null} targetNode - The `targetNode` parameter in the
358
+ * @param {BinaryTreeNodeKey | N | null} targetNode - The `targetNode` parameter in the
359
359
  * `lesserOrGreaterTraverse` function is used to specify the node from which the traversal should
360
360
  * start. It can be either a reference to a specific node (`N`), the key of a node
361
361
  * (`BinaryTreeNodeKey`), or `null` to
@@ -363,10 +363,10 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
363
363
  * done recursively or iteratively. It can have two possible values:
364
364
  * @returns The function `lesserOrGreaterTraverse` returns an array of `MapCallbackReturn<N>`.
365
365
  */
366
- lesserOrGreaterTraverse<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
366
+ lesserOrGreaterTraverse<C extends MapCallback<N>>(
367
367
  callback: C = this._defaultCallbackByKey as C,
368
368
  lesserOrGreater: CP = CP.lt,
369
- targetNode: N | BinaryTreeNodeKey | null = this.root,
369
+ targetNode: BinaryTreeNodeKey | N | null = this.root,
370
370
  iterationType = this.iterationType
371
371
  ): ReturnType<C>[] {
372
372
  if (typeof targetNode === 'number') targetNode = this.get(targetNode);
@@ -205,8 +205,8 @@ export class RBTree<N extends RBTreeNode<N['val'], N> = RBTreeNode> extends BST<
205
205
  // node.right = null;
206
206
  // }
207
207
  //
208
- // override delete(nodeOrKey: BinaryTreeNodeKey | N): BinaryTreeDeletedResult<N>[] {
209
- // const node = this.get(nodeOrKey);
208
+ // override delete(keyOrNode: BinaryTreeNodeKey | N): BinaryTreeDeletedResult<N>[] {
209
+ // const node = this.get(keyOrNode);
210
210
  // const result: BinaryTreeDeletedResult<N>[] = [{deleted: undefined, needBalanced: null}];
211
211
  // if (!node) return result; // Node does not exist
212
212
  //
@@ -6,7 +6,7 @@
6
6
  * @license MIT License
7
7
  */
8
8
  import type {BinaryTreeNodeKey, TreeMultisetNodeNested, TreeMultisetOptions} from '../../types';
9
- import {BinaryTreeDeletedResult, CP, FamilyPosition, IterationType} from '../../types';
9
+ import {BinaryTreeDeletedResult, CP, FamilyPosition, IterationType, MapCallback} from '../../types';
10
10
  import {IBinaryTree} from '../../interfaces';
11
11
  import {AVLTree, AVLTreeNode} from './avl-tree';
12
12
 
@@ -265,20 +265,28 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
265
265
  /**
266
266
  * The `delete` function in a binary search tree deletes a node from the tree and returns the deleted
267
267
  * node along with the parent node that needs to be balanced.
268
- * @param {N | BinaryTreeNodeKey} nodeOrKey - The `nodeOrKey` parameter can be either a node object
269
- * (`N`) or a key value (`BinaryTreeNodeKey`). It represents the node or key that needs to be deleted
270
- * from the binary tree.
268
+ * @param {ReturnType<C>} identifier - The `identifier` parameter is either a
269
+ * `BinaryTreeNodeKey` or a generic type `N`. It represents the property of the node that we are
270
+ * searching for. It can be a specific key value or any other property of the node.
271
+ * @param callback - The `callback` parameter is a function that takes a node as input and returns a
272
+ * value. This value is compared with the `identifier` parameter to determine if the node should be
273
+ * included in the result. The `callback` parameter has a default value of
274
+ * `this._defaultCallbackByKey`
271
275
  * @param [ignoreCount=false] - A boolean flag indicating whether to ignore the count of the node
272
276
  * being deleted. If set to true, the count of the node will not be considered and the node will be
273
277
  * deleted regardless of its count. If set to false (default), the count of the node will be
274
278
  * decremented by 1 and
275
279
  * @returns The method `delete` returns an array of `BinaryTreeDeletedResult<N>` objects.
276
280
  */
277
- override delete(nodeOrKey: N | BinaryTreeNodeKey, ignoreCount = false): BinaryTreeDeletedResult<N>[] {
281
+ override delete<C extends MapCallback<N>>(
282
+ identifier: ReturnType<C>,
283
+ callback: C = this._defaultCallbackByKey as C,
284
+ ignoreCount = false
285
+ ): BinaryTreeDeletedResult<N>[] {
278
286
  const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
279
287
  if (!this.root) return bstDeletedResult;
280
288
 
281
- const curr: N | null = this.get(nodeOrKey);
289
+ const curr: N | null = this.get(identifier, callback);
282
290
  if (!curr) return bstDeletedResult;
283
291
 
284
292
  const parent: N | null = curr?.parent ? curr.parent : null;
@@ -266,7 +266,7 @@ export class DoublyLinkedList<E = any> {
266
266
  * @returns The function `findNodeByValue` returns a `DoublyLinkedListNode<E>` if a node with the specified value `val`
267
267
  * is found in the linked list. If no such node is found, it returns `null`.
268
268
  */
269
- findNode(val: E): DoublyLinkedListNode<E> | null {
269
+ findNode(val: E | null): DoublyLinkedListNode<E> | null {
270
270
  let current = this.head;
271
271
 
272
272
  while (current) {
@@ -341,7 +341,7 @@ export class DoublyLinkedList<E = any> {
341
341
  * @returns The `delete` method returns a boolean value. It returns `true` if the value or node was successfully
342
342
  * deleted from the doubly linked list, and `false` if the value or node was not found in the list.
343
343
  */
344
- delete(valOrNode: E | DoublyLinkedListNode<E>): boolean {
344
+ delete(valOrNode: E | DoublyLinkedListNode<E> | null): boolean {
345
345
  let node: DoublyLinkedListNode<E> | null;
346
346
 
347
347
  if (valOrNode instanceof DoublyLinkedListNode) {
@@ -594,9 +594,6 @@ export class DoublyLinkedList<E = any> {
594
594
  return false;
595
595
  }
596
596
 
597
- insertBefore(existingValueOrNode: E, newValue: E): boolean;
598
- insertBefore(existingValueOrNode: DoublyLinkedListNode<E>, newValue: E): boolean;
599
-
600
597
  /**
601
598
  * The `insertBefore` function inserts a new value before an existing value or node in a doubly linked list.
602
599
  * @param {E | DoublyLinkedListNode<E>} existingValueOrNode - The existing value or node in the doubly linked list
@@ -214,9 +214,6 @@ export class SinglyLinkedList<E = any> {
214
214
  return removedNode!.val;
215
215
  }
216
216
 
217
- delete(valueOrNode: E): boolean;
218
- delete(valueOrNode: SinglyLinkedListNode<E>): boolean;
219
-
220
217
  /**
221
218
  * The delete function removes a node with a specific value from a singly linked list.
222
219
  * @param {E | SinglyLinkedListNode<E>} valueOrNode - The `valueOrNode` parameter can accept either a value of type `E`
@@ -224,7 +221,8 @@ export class SinglyLinkedList<E = any> {
224
221
  * @returns The `delete` method returns a boolean value. It returns `true` if the value or node is found and
225
222
  * successfully deleted from the linked list, and `false` if the value or node is not found in the linked list.
226
223
  */
227
- delete(valueOrNode: E | SinglyLinkedListNode<E>): boolean {
224
+ delete(valueOrNode: E | SinglyLinkedListNode<E> | null | undefined): boolean {
225
+ if (!valueOrNode) return false;
228
226
  let value: E;
229
227
  if (valueOrNode instanceof SinglyLinkedListNode) {
230
228
  value = valueOrNode.val;
@@ -397,9 +395,6 @@ export class SinglyLinkedList<E = any> {
397
395
  return null;
398
396
  }
399
397
 
400
- insertBefore(existingValue: E, newValue: E): boolean;
401
- insertBefore(existingValue: SinglyLinkedListNode<E>, newValue: E): boolean;
402
-
403
398
  /**
404
399
  * The `insertBefore` function inserts a new value before an existing value in a singly linked list.
405
400
  * @param {E | SinglyLinkedListNode<E>} existingValueOrNode - The existing value or node that you want to insert the
@@ -1,10 +1,10 @@
1
1
  import {BinaryTreeNode} from '../data-structures';
2
- import {BinaryTreeDeletedResult, BinaryTreeNodeKey} from '../types';
2
+ import {BinaryTreeDeletedResult, BinaryTreeNodeKey, MapCallback} from '../types';
3
3
 
4
4
  export interface IBinaryTree<N extends BinaryTreeNode<N['val'], N>> {
5
5
  createNode(key: BinaryTreeNodeKey, val?: N['val']): N;
6
6
 
7
7
  add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val']): N | null | undefined;
8
8
 
9
- delete(nodeOrKey: N | BinaryTreeNodeKey): BinaryTreeDeletedResult<N>[];
9
+ delete<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C): BinaryTreeDeletedResult<N>[];
10
10
  }
@@ -1,9 +1,13 @@
1
+ import {BinaryTreeNodeKey} from './data-structures';
2
+
1
3
  export type Comparator<T> = (a: T, b: T) => number;
2
4
 
3
5
  export type DFSOrderPattern = 'pre' | 'in' | 'post';
4
6
 
5
7
  export type MapCallback<N, D = any> = (node: N) => D;
6
8
 
9
+ export type DefaultMapCallback<N, D = BinaryTreeNodeKey> = (node: N) => D;
10
+
7
11
  export type MapCallbackReturn<N> = ReturnType<MapCallback<N>>;
8
12
 
9
13
  export enum CP {