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.
- package/dist/data-structures/binary-tree/avl-tree.d.ts +9 -3
- package/dist/data-structures/binary-tree/avl-tree.js +9 -4
- package/dist/data-structures/binary-tree/binary-tree.d.ts +31 -79
- package/dist/data-structures/binary-tree/binary-tree.js +50 -59
- package/dist/data-structures/binary-tree/bst.d.ts +7 -7
- package/dist/data-structures/binary-tree/bst.js +13 -13
- package/dist/data-structures/binary-tree/tree-multiset.d.ts +9 -5
- package/dist/data-structures/binary-tree/tree-multiset.js +9 -5
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +12 -3
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +17 -4
- package/dist/data-structures/linked-list/singly-linked-list.js +2 -0
- package/dist/interfaces/binary-tree.d.ts +2 -2
- package/dist/types/helpers.d.ts +2 -0
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree.ts +13 -4
- package/src/data-structures/binary-tree/binary-tree.ts +113 -69
- package/src/data-structures/binary-tree/bst.ts +17 -17
- package/src/data-structures/binary-tree/rb-tree.ts +2 -2
- package/src/data-structures/binary-tree/tree-multiset.ts +14 -6
- package/src/data-structures/linked-list/doubly-linked-list.ts +2 -5
- package/src/data-structures/linked-list/singly-linked-list.ts +2 -7
- package/src/interfaces/binary-tree.ts +2 -2
- package/src/types/helpers.ts +4 -0
|
@@ -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 (
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
276
|
-
continue;
|
|
261
|
+
return this.add(keyOrNode.key, keyOrNode.val);
|
|
277
262
|
}
|
|
278
263
|
|
|
279
264
|
if (keyOrNode === null) {
|
|
280
|
-
|
|
281
|
-
continue;
|
|
265
|
+
return this.add(null);
|
|
282
266
|
}
|
|
283
267
|
|
|
284
268
|
const val = values?.[i];
|
|
285
|
-
|
|
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
|
|
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
|
|
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 {
|
|
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 {
|
|
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:
|
|
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 {
|
|
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:
|
|
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 {
|
|
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 `
|
|
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
|
|
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
|
|
516
|
-
|
|
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) ===
|
|
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) ===
|
|
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}
|
|
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
|
|
574
|
-
|
|
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(
|
|
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}
|
|
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
|
|
599
|
-
|
|
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(
|
|
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 {
|
|
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:
|
|
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 {
|
|
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
|
|
809
|
+
subTreeTraverse<C extends MapCallback<N>>(
|
|
765
810
|
callback: C = this._defaultCallbackByKey as C,
|
|
766
|
-
beginRoot:
|
|
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
|
|
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
|
|
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
|
|
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']][]}
|
|
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 {
|
|
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
|
|
242
|
-
|
|
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(
|
|
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 {
|
|
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
|
|
293
|
-
|
|
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 ===
|
|
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,
|
|
314
|
-
if (this._compare(cur.key,
|
|
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 ===
|
|
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,
|
|
335
|
-
if (this._compare(cur.key,
|
|
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 {
|
|
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
|
|
366
|
+
lesserOrGreaterTraverse<C extends MapCallback<N>>(
|
|
367
367
|
callback: C = this._defaultCallbackByKey as C,
|
|
368
368
|
lesserOrGreater: CP = CP.lt,
|
|
369
|
-
targetNode:
|
|
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(
|
|
209
|
-
// const node = this.get(
|
|
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 {
|
|
269
|
-
*
|
|
270
|
-
*
|
|
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
|
|
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(
|
|
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(
|
|
9
|
+
delete<C extends MapCallback<N>>(identifier: ReturnType<C> | N, callback: C): BinaryTreeDeletedResult<N>[];
|
|
10
10
|
}
|
package/src/types/helpers.ts
CHANGED
|
@@ -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 {
|