data-structure-typed 1.42.3 → 1.42.5
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/CHANGELOG.md +1 -1
- package/README.md +17 -17
- package/benchmark/report.html +12 -12
- package/benchmark/report.json +106 -106
- package/dist/cjs/src/data-structures/binary-tree/avl-tree.d.ts +2 -2
- package/dist/cjs/src/data-structures/binary-tree/avl-tree.js +5 -3
- package/dist/cjs/src/data-structures/binary-tree/avl-tree.js.map +1 -1
- package/dist/cjs/src/data-structures/binary-tree/binary-tree.d.ts +56 -52
- package/dist/cjs/src/data-structures/binary-tree/binary-tree.js +115 -53
- package/dist/cjs/src/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/src/data-structures/binary-tree/bst.d.ts +42 -15
- package/dist/cjs/src/data-structures/binary-tree/bst.js +77 -21
- package/dist/cjs/src/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/cjs/src/data-structures/binary-tree/index.d.ts +1 -1
- package/dist/cjs/src/data-structures/binary-tree/index.js +1 -1
- package/dist/cjs/src/data-structures/binary-tree/rb-tree.d.ts +28 -51
- package/dist/cjs/src/data-structures/binary-tree/rb-tree.js +148 -180
- package/dist/cjs/src/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/cjs/src/data-structures/binary-tree/{tree-multiset.d.ts → tree-multimap.d.ts} +20 -20
- package/dist/cjs/src/data-structures/binary-tree/{tree-multiset.js → tree-multimap.js} +35 -32
- package/dist/cjs/src/data-structures/binary-tree/tree-multimap.js.map +1 -0
- package/dist/cjs/src/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/cjs/src/types/data-structures/binary-tree/index.d.ts +1 -1
- package/dist/cjs/src/types/data-structures/binary-tree/index.js +1 -1
- package/dist/cjs/src/types/data-structures/binary-tree/rb-tree.d.ts +4 -0
- package/dist/cjs/src/types/data-structures/binary-tree/rb-tree.js +0 -5
- package/dist/cjs/src/types/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/cjs/src/types/data-structures/binary-tree/tree-multimap.d.ts +4 -0
- package/dist/cjs/src/types/data-structures/binary-tree/{tree-multiset.js → tree-multimap.js} +1 -1
- package/dist/cjs/src/types/data-structures/binary-tree/tree-multimap.js.map +1 -0
- package/dist/mjs/src/data-structures/binary-tree/avl-tree.d.ts +2 -2
- package/dist/mjs/src/data-structures/binary-tree/avl-tree.js +5 -3
- package/dist/mjs/src/data-structures/binary-tree/binary-tree.d.ts +56 -52
- package/dist/mjs/src/data-structures/binary-tree/binary-tree.js +115 -53
- package/dist/mjs/src/data-structures/binary-tree/bst.d.ts +42 -15
- package/dist/mjs/src/data-structures/binary-tree/bst.js +79 -21
- package/dist/mjs/src/data-structures/binary-tree/index.d.ts +1 -1
- package/dist/mjs/src/data-structures/binary-tree/index.js +1 -1
- package/dist/mjs/src/data-structures/binary-tree/rb-tree.d.ts +28 -51
- package/dist/mjs/src/data-structures/binary-tree/rb-tree.js +148 -184
- package/dist/mjs/src/data-structures/binary-tree/{tree-multiset.d.ts → tree-multimap.d.ts} +20 -20
- package/dist/mjs/src/data-structures/binary-tree/{tree-multiset.js → tree-multimap.js} +33 -31
- package/dist/mjs/src/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/mjs/src/types/data-structures/binary-tree/index.d.ts +1 -1
- package/dist/mjs/src/types/data-structures/binary-tree/index.js +1 -1
- package/dist/mjs/src/types/data-structures/binary-tree/rb-tree.d.ts +4 -0
- package/dist/mjs/src/types/data-structures/binary-tree/rb-tree.js +0 -5
- package/dist/mjs/src/types/data-structures/binary-tree/tree-multimap.d.ts +4 -0
- package/dist/umd/data-structure-typed.min.js +1 -1
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +5 -3
- package/src/data-structures/binary-tree/avl-tree.ts +5 -4
- package/src/data-structures/binary-tree/binary-tree.ts +201 -131
- package/src/data-structures/binary-tree/bst.ts +100 -34
- package/src/data-structures/binary-tree/index.ts +1 -1
- package/src/data-structures/binary-tree/rb-tree.ts +227 -236
- package/src/data-structures/binary-tree/{tree-multiset.ts → tree-multimap.ts} +38 -37
- package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
- package/src/types/data-structures/binary-tree/index.ts +1 -1
- package/src/types/data-structures/binary-tree/rb-tree.ts +5 -5
- package/src/types/data-structures/binary-tree/tree-multimap.ts +6 -0
- package/test/performance/data-structures/binary-tree/rb-tree.test.ts +2 -2
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +20 -1
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +12 -31
- package/test/unit/data-structures/binary-tree/bst.test.ts +3 -3
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +205 -159
- package/test/unit/data-structures/binary-tree/{tree-multiset.test.ts → tree-multimap.test.ts} +182 -182
- package/dist/cjs/src/data-structures/binary-tree/tree-multiset.js.map +0 -1
- package/dist/cjs/src/types/data-structures/binary-tree/tree-multiset.d.ts +0 -4
- package/dist/cjs/src/types/data-structures/binary-tree/tree-multiset.js.map +0 -1
- package/dist/mjs/src/types/data-structures/binary-tree/tree-multiset.d.ts +0 -4
- package/src/types/data-structures/binary-tree/tree-multiset.ts +0 -6
- /package/dist/mjs/src/types/data-structures/binary-tree/{tree-multiset.js → tree-multimap.js} +0 -0
- /package/test/performance/data-structures/binary-tree/{tree-multiset.test.ts → tree-multimap.test.ts} +0 -0
|
@@ -5,16 +5,13 @@
|
|
|
5
5
|
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
-
import { RBTNColor } from '../../types';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
color: number;
|
|
15
|
-
constructor(key: number, color?: RBTNColor);
|
|
8
|
+
import { BinaryTreeDeletedResult, BTNCallback, BTNKey, IterationType, RBTNColor, RBTreeNodeNested, RBTreeOptions } from '../../types';
|
|
9
|
+
import { BST, BSTNode } from "./bst";
|
|
10
|
+
import { IBinaryTree } from "../../interfaces";
|
|
11
|
+
export declare class RBTreeNode<V = any, N extends RBTreeNode<V, N> = RBTreeNodeNested<V>> extends BSTNode<V, N> {
|
|
12
|
+
color: RBTNColor;
|
|
13
|
+
constructor(key: BTNKey, value?: V, color?: RBTNColor);
|
|
16
14
|
}
|
|
17
|
-
export declare const NIL: RBTreeNode;
|
|
18
15
|
/**
|
|
19
16
|
* 1. Each node is either red or black.
|
|
20
17
|
* 2. The root node is always black.
|
|
@@ -22,95 +19,75 @@ export declare const NIL: RBTreeNode;
|
|
|
22
19
|
* 4. Red nodes must have black children.
|
|
23
20
|
* 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.
|
|
24
21
|
*/
|
|
25
|
-
export declare class RedBlackTree {
|
|
26
|
-
constructor();
|
|
27
|
-
protected _root:
|
|
28
|
-
get root():
|
|
22
|
+
export declare class RedBlackTree<V = any, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNested<V>>> extends BST<V, N> implements IBinaryTree<V, N> {
|
|
23
|
+
constructor(options?: RBTreeOptions);
|
|
24
|
+
protected _root: N;
|
|
25
|
+
get root(): N;
|
|
29
26
|
protected _size: number;
|
|
30
27
|
get size(): number;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* The `delete` function in TypeScript is used to remove a node with a specific key from a red-black
|
|
41
|
-
* tree.
|
|
42
|
-
* @param {number} key - The `node` parameter is of type `RBTreeNode` and represents the current
|
|
43
|
-
* node being processed in the delete operation.
|
|
44
|
-
* @returns The `delete` function does not return anything. It has a return type of `void`.
|
|
45
|
-
*/
|
|
46
|
-
delete(key: number): void;
|
|
47
|
-
isRealNode(node: RBTreeNode | null | undefined): node is RBTreeNode;
|
|
48
|
-
/**
|
|
49
|
-
* The function `getNode` is a recursive depth-first search algorithm that searches for a node with a
|
|
50
|
-
* given key in a red-black tree.
|
|
51
|
-
* @param {number} key - The key parameter is a number that represents the value we are searching for
|
|
52
|
-
* in the RBTree.
|
|
53
|
-
* @param beginRoot - The `beginRoot` parameter is an optional parameter that represents the starting
|
|
54
|
-
* point for the search in the binary search tree. If no value is provided for `beginRoot`, it
|
|
55
|
-
* defaults to the root of the binary search tree (`this.root`).
|
|
56
|
-
* @returns a RBTreeNode.
|
|
57
|
-
*/
|
|
58
|
-
getNode(key: number, beginRoot?: RBTreeNode): RBTreeNode;
|
|
28
|
+
NIL: N;
|
|
29
|
+
add(keyOrNode: BTNKey | N | null | undefined, value?: V): N | undefined;
|
|
30
|
+
createNode(key: BTNKey, value?: V, color?: RBTNColor): N;
|
|
31
|
+
delete<C extends BTNCallback<N>>(identifier: ReturnType<C> | null | undefined, callback?: C): BinaryTreeDeletedResult<N>[];
|
|
32
|
+
isNode(node: N | undefined): node is N;
|
|
33
|
+
getNode<C extends BTNCallback<N, BTNKey>>(identifier: BTNKey, callback?: C, beginRoot?: N | undefined, iterationType?: IterationType): N | undefined;
|
|
34
|
+
getNode<C extends BTNCallback<N, N>>(identifier: N | undefined, callback?: C, beginRoot?: N | undefined, iterationType?: IterationType): N | undefined;
|
|
35
|
+
getNode<C extends BTNCallback<N>>(identifier: ReturnType<C>, callback: C, beginRoot?: N | undefined, iterationType?: IterationType): N | undefined;
|
|
59
36
|
/**
|
|
60
37
|
* The function returns the leftmost node in a red-black tree.
|
|
61
38
|
* @param {RBTreeNode} node - The parameter "node" is of type RBTreeNode, which represents a node in
|
|
62
39
|
* a Red-Black Tree.
|
|
63
40
|
* @returns The leftmost node in the given RBTreeNode.
|
|
64
41
|
*/
|
|
65
|
-
getLeftMost(node?:
|
|
42
|
+
getLeftMost(node?: N): N;
|
|
66
43
|
/**
|
|
67
44
|
* The function returns the rightmost node in a red-black tree.
|
|
68
45
|
* @param {RBTreeNode} node - The parameter "node" is of type RBTreeNode.
|
|
69
46
|
* @returns the rightmost node in a red-black tree.
|
|
70
47
|
*/
|
|
71
|
-
getRightMost(node:
|
|
48
|
+
getRightMost(node: N): N;
|
|
72
49
|
/**
|
|
73
50
|
* The function returns the successor of a given node in a red-black tree.
|
|
74
51
|
* @param {RBTreeNode} x - RBTreeNode - The node for which we want to find the successor.
|
|
75
52
|
* @returns the successor of the given RBTreeNode.
|
|
76
53
|
*/
|
|
77
|
-
getSuccessor(x:
|
|
54
|
+
getSuccessor(x: N): N | undefined;
|
|
78
55
|
/**
|
|
79
56
|
* The function returns the predecessor of a given node in a red-black tree.
|
|
80
57
|
* @param {RBTreeNode} x - The parameter `x` is of type `RBTreeNode`, which represents a node in a
|
|
81
58
|
* Red-Black Tree.
|
|
82
59
|
* @returns the predecessor of the given RBTreeNode 'x'.
|
|
83
60
|
*/
|
|
84
|
-
getPredecessor(x:
|
|
61
|
+
getPredecessor(x: N): N;
|
|
85
62
|
clear(): void;
|
|
86
|
-
|
|
63
|
+
protected _setRoot(v: N): void;
|
|
87
64
|
/**
|
|
88
65
|
* The function performs a left rotation on a red-black tree node.
|
|
89
66
|
* @param {RBTreeNode} x - The parameter `x` is a RBTreeNode object.
|
|
90
67
|
*/
|
|
91
|
-
protected _leftRotate(x:
|
|
68
|
+
protected _leftRotate(x: N): void;
|
|
92
69
|
/**
|
|
93
70
|
* The function performs a right rotation on a red-black tree node.
|
|
94
71
|
* @param {RBTreeNode} x - x is a RBTreeNode, which represents the node that needs to be right
|
|
95
72
|
* rotated.
|
|
96
73
|
*/
|
|
97
|
-
protected _rightRotate(x:
|
|
74
|
+
protected _rightRotate(x: N): void;
|
|
98
75
|
/**
|
|
99
76
|
* The _fixDelete function is used to rebalance the Red-Black Tree after a node deletion.
|
|
100
77
|
* @param {RBTreeNode} x - The parameter `x` is of type `RBTreeNode`, which represents a node in a
|
|
101
78
|
* red-black tree.
|
|
102
79
|
*/
|
|
103
|
-
protected _fixDelete(x:
|
|
80
|
+
protected _fixDelete(x: N): void;
|
|
104
81
|
/**
|
|
105
82
|
* The function `_rbTransplant` replaces one node in a red-black tree with another node.
|
|
106
83
|
* @param {RBTreeNode} u - The parameter "u" represents a RBTreeNode object.
|
|
107
84
|
* @param {RBTreeNode} v - The parameter "v" is a RBTreeNode object.
|
|
108
85
|
*/
|
|
109
|
-
protected _rbTransplant(u:
|
|
86
|
+
protected _rbTransplant(u: N, v: N): void;
|
|
110
87
|
/**
|
|
111
88
|
* The `_fixInsert` function is used to fix the red-black tree after an insertion operation.
|
|
112
89
|
* @param {RBTreeNode} k - The parameter `k` is a RBTreeNode object, which represents a node in a
|
|
113
90
|
* red-black tree.
|
|
114
91
|
*/
|
|
115
|
-
protected _fixInsert(k:
|
|
92
|
+
protected _fixInsert(k: N): void;
|
|
116
93
|
}
|
|
@@ -7,20 +7,17 @@
|
|
|
7
7
|
* @license MIT License
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.RedBlackTree = exports.
|
|
10
|
+
exports.RedBlackTree = exports.RBTreeNode = void 0;
|
|
11
11
|
const types_1 = require("../../types");
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const bst_1 = require("./bst");
|
|
13
|
+
const binary_tree_1 = require("./binary-tree");
|
|
14
|
+
class RBTreeNode extends bst_1.BSTNode {
|
|
15
|
+
constructor(key, value, color = types_1.RBTNColor.BLACK) {
|
|
16
|
+
super(key, value);
|
|
16
17
|
this.color = color;
|
|
17
|
-
this.parent = null;
|
|
18
|
-
this.left = null;
|
|
19
|
-
this.right = null;
|
|
20
18
|
}
|
|
21
19
|
}
|
|
22
20
|
exports.RBTreeNode = RBTreeNode;
|
|
23
|
-
exports.NIL = new RBTreeNode(0);
|
|
24
21
|
/**
|
|
25
22
|
* 1. Each node is either red or black.
|
|
26
23
|
* 2. The root node is always black.
|
|
@@ -28,10 +25,12 @@ exports.NIL = new RBTreeNode(0);
|
|
|
28
25
|
* 4. Red nodes must have black children.
|
|
29
26
|
* 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.
|
|
30
27
|
*/
|
|
31
|
-
class RedBlackTree {
|
|
32
|
-
constructor() {
|
|
28
|
+
class RedBlackTree extends bst_1.BST {
|
|
29
|
+
constructor(options) {
|
|
30
|
+
super(options);
|
|
33
31
|
this._size = 0;
|
|
34
|
-
this.
|
|
32
|
+
this.NIL = new RBTreeNode(NaN);
|
|
33
|
+
this._root = this.NIL;
|
|
35
34
|
}
|
|
36
35
|
get root() {
|
|
37
36
|
return this._root;
|
|
@@ -39,31 +38,39 @@ class RedBlackTree {
|
|
|
39
38
|
get size() {
|
|
40
39
|
return this._size;
|
|
41
40
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
41
|
+
add(keyOrNode, value) {
|
|
42
|
+
let node;
|
|
43
|
+
if (typeof keyOrNode === 'number') {
|
|
44
|
+
node = this.createNode(keyOrNode, value, types_1.RBTNColor.RED);
|
|
45
|
+
}
|
|
46
|
+
else if (keyOrNode instanceof RBTreeNode) {
|
|
47
|
+
node = keyOrNode;
|
|
48
|
+
}
|
|
49
|
+
else if (keyOrNode === null) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
else if (keyOrNode === undefined) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
node.left = this.NIL;
|
|
59
|
+
node.right = this.NIL;
|
|
60
|
+
let y = undefined;
|
|
54
61
|
let x = this.root;
|
|
55
|
-
while (x !==
|
|
62
|
+
while (x !== this.NIL) {
|
|
56
63
|
y = x;
|
|
57
|
-
if (node.key < x.key) {
|
|
64
|
+
if (x && node.key < x.key) {
|
|
58
65
|
x = x.left;
|
|
59
66
|
}
|
|
60
67
|
else {
|
|
61
|
-
x = x.right;
|
|
68
|
+
x = x === null || x === void 0 ? void 0 : x.right;
|
|
62
69
|
}
|
|
63
70
|
}
|
|
64
71
|
node.parent = y;
|
|
65
|
-
if (y ===
|
|
66
|
-
this.
|
|
72
|
+
if (y === undefined) {
|
|
73
|
+
this._setRoot(node);
|
|
67
74
|
}
|
|
68
75
|
else if (node.key < y.key) {
|
|
69
76
|
y.left = node;
|
|
@@ -71,51 +78,50 @@ class RedBlackTree {
|
|
|
71
78
|
else {
|
|
72
79
|
y.right = node;
|
|
73
80
|
}
|
|
74
|
-
if (node.parent ===
|
|
81
|
+
if (node.parent === undefined) {
|
|
75
82
|
node.color = types_1.RBTNColor.BLACK;
|
|
76
83
|
this._size++;
|
|
77
84
|
return;
|
|
78
85
|
}
|
|
79
|
-
if (node.parent.parent ===
|
|
86
|
+
if (node.parent.parent === undefined) {
|
|
80
87
|
this._size++;
|
|
81
88
|
return;
|
|
82
89
|
}
|
|
83
90
|
this._fixInsert(node);
|
|
84
91
|
this._size++;
|
|
85
92
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
delete(key) {
|
|
93
|
+
createNode(key, value, color = types_1.RBTNColor.BLACK) {
|
|
94
|
+
return new RBTreeNode(key, value, color);
|
|
95
|
+
}
|
|
96
|
+
delete(identifier, callback = this.defaultOneParamCallback) {
|
|
97
|
+
const ans = [];
|
|
98
|
+
if (identifier === null)
|
|
99
|
+
return ans;
|
|
94
100
|
const helper = (node) => {
|
|
95
|
-
let z =
|
|
101
|
+
let z = this.NIL;
|
|
96
102
|
let x, y;
|
|
97
|
-
while (node !==
|
|
98
|
-
if (node
|
|
103
|
+
while (node !== this.NIL) {
|
|
104
|
+
if (node && callback(node) === identifier) {
|
|
99
105
|
z = node;
|
|
100
106
|
}
|
|
101
|
-
if (node
|
|
107
|
+
if (node && identifier && callback(node) <= identifier) {
|
|
102
108
|
node = node.right;
|
|
103
109
|
}
|
|
104
110
|
else {
|
|
105
|
-
node = node.left;
|
|
111
|
+
node = node === null || node === void 0 ? void 0 : node.left;
|
|
106
112
|
}
|
|
107
113
|
}
|
|
108
|
-
if (z ===
|
|
114
|
+
if (z === this.NIL) {
|
|
109
115
|
this._size--;
|
|
110
116
|
return;
|
|
111
117
|
}
|
|
112
118
|
y = z;
|
|
113
119
|
let yOriginalColor = y.color;
|
|
114
|
-
if (z.left ===
|
|
120
|
+
if (z.left === this.NIL) {
|
|
115
121
|
x = z.right;
|
|
116
122
|
this._rbTransplant(z, z.right);
|
|
117
123
|
}
|
|
118
|
-
else if (z.right ===
|
|
124
|
+
else if (z.right === this.NIL) {
|
|
119
125
|
x = z.left;
|
|
120
126
|
this._rbTransplant(z, z.left);
|
|
121
127
|
}
|
|
@@ -142,35 +148,32 @@ class RedBlackTree {
|
|
|
142
148
|
this._size--;
|
|
143
149
|
};
|
|
144
150
|
helper(this.root);
|
|
151
|
+
// TODO
|
|
152
|
+
return ans;
|
|
145
153
|
}
|
|
146
|
-
|
|
147
|
-
return node !==
|
|
154
|
+
isNode(node) {
|
|
155
|
+
return node !== this.NIL && node !== undefined;
|
|
148
156
|
}
|
|
149
157
|
/**
|
|
150
|
-
* The function `
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
* @param
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
+
* The function `get` returns the first node in a binary tree that matches the given property or key.
|
|
159
|
+
* @param {BTNKey | N} identifier - The `identifier` parameter is the key or value of
|
|
160
|
+
* the node that you want to find in the binary tree. It can be either a `BTNKey` or `N`
|
|
161
|
+
* type.
|
|
162
|
+
* @param callback - The `callback` parameter is a function that is used to determine whether a node
|
|
163
|
+
* matches the desired criteria. It takes a node as input and returns a boolean value indicating
|
|
164
|
+
* whether the node matches the criteria or not. The default callback function
|
|
165
|
+
* (`this.defaultOneParamCallback`) is used if no callback function is
|
|
166
|
+
* @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
|
|
167
|
+
* the root node from which the search should begin.
|
|
168
|
+
* @param iterationType - The `iterationType` parameter specifies the type of iteration to be
|
|
169
|
+
* performed when searching for a node in the binary tree. It can have one of the following values:
|
|
170
|
+
* @returns either the found node (of type N) or null if no node is found.
|
|
158
171
|
*/
|
|
159
|
-
getNode(
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
if (key < node.key)
|
|
166
|
-
return dfs(node.left);
|
|
167
|
-
return dfs(node.right);
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
return null;
|
|
171
|
-
}
|
|
172
|
-
};
|
|
173
|
-
return dfs(beginRoot);
|
|
172
|
+
getNode(identifier, callback = this.defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
|
|
173
|
+
var _a;
|
|
174
|
+
if (identifier instanceof binary_tree_1.BinaryTreeNode)
|
|
175
|
+
callback = (node => node);
|
|
176
|
+
return (_a = this.getNodes(identifier, callback, true, beginRoot, iterationType)[0]) !== null && _a !== void 0 ? _a : undefined;
|
|
174
177
|
}
|
|
175
178
|
/**
|
|
176
179
|
* The function returns the leftmost node in a red-black tree.
|
|
@@ -179,7 +182,7 @@ class RedBlackTree {
|
|
|
179
182
|
* @returns The leftmost node in the given RBTreeNode.
|
|
180
183
|
*/
|
|
181
184
|
getLeftMost(node = this.root) {
|
|
182
|
-
while (node.left !==
|
|
185
|
+
while (node.left !== undefined && node.left !== this.NIL) {
|
|
183
186
|
node = node.left;
|
|
184
187
|
}
|
|
185
188
|
return node;
|
|
@@ -190,7 +193,7 @@ class RedBlackTree {
|
|
|
190
193
|
* @returns the rightmost node in a red-black tree.
|
|
191
194
|
*/
|
|
192
195
|
getRightMost(node) {
|
|
193
|
-
while (node.right !==
|
|
196
|
+
while (node.right !== undefined && node.right !== this.NIL) {
|
|
194
197
|
node = node.right;
|
|
195
198
|
}
|
|
196
199
|
return node;
|
|
@@ -201,11 +204,11 @@ class RedBlackTree {
|
|
|
201
204
|
* @returns the successor of the given RBTreeNode.
|
|
202
205
|
*/
|
|
203
206
|
getSuccessor(x) {
|
|
204
|
-
if (x.right !==
|
|
207
|
+
if (x.right !== this.NIL) {
|
|
205
208
|
return this.getLeftMost(x.right);
|
|
206
209
|
}
|
|
207
210
|
let y = x.parent;
|
|
208
|
-
while (y !==
|
|
211
|
+
while (y !== this.NIL && y !== undefined && x === y.right) {
|
|
209
212
|
x = y;
|
|
210
213
|
y = y.parent;
|
|
211
214
|
}
|
|
@@ -218,95 +221,51 @@ class RedBlackTree {
|
|
|
218
221
|
* @returns the predecessor of the given RBTreeNode 'x'.
|
|
219
222
|
*/
|
|
220
223
|
getPredecessor(x) {
|
|
221
|
-
if (x.left !==
|
|
224
|
+
if (x.left !== this.NIL) {
|
|
222
225
|
return this.getRightMost(x.left);
|
|
223
226
|
}
|
|
224
227
|
let y = x.parent;
|
|
225
|
-
while (y !==
|
|
228
|
+
while (y !== this.NIL && x === y.left) {
|
|
226
229
|
x = y;
|
|
227
230
|
y = y.parent;
|
|
228
231
|
}
|
|
229
232
|
return y;
|
|
230
233
|
}
|
|
231
234
|
clear() {
|
|
232
|
-
this._root =
|
|
235
|
+
this._root = this.NIL;
|
|
233
236
|
this._size = 0;
|
|
234
237
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
};
|
|
242
|
-
const _displayAux = (node) => {
|
|
243
|
-
if (node === null) {
|
|
244
|
-
return [[], 0, 0, 0];
|
|
245
|
-
}
|
|
246
|
-
if (node.right === null && node.left === null) {
|
|
247
|
-
const line = `${node.key}`;
|
|
248
|
-
const width = line.length;
|
|
249
|
-
const height = 1;
|
|
250
|
-
const middle = Math.floor(width / 2);
|
|
251
|
-
return [[line], width, height, middle];
|
|
252
|
-
}
|
|
253
|
-
if (node.right === null) {
|
|
254
|
-
const [lines, n, p, x] = _displayAux(node.left);
|
|
255
|
-
const s = `${node.key}`;
|
|
256
|
-
const u = s.length;
|
|
257
|
-
const first_line = ' '.repeat(x + 1) + '_'.repeat(n - x - 1) + s;
|
|
258
|
-
const second_line = ' '.repeat(x) + '/' + ' '.repeat(n - x - 1 + u);
|
|
259
|
-
const shifted_lines = lines.map(line => line + ' '.repeat(u));
|
|
260
|
-
return [[first_line, second_line, ...shifted_lines], n + u, p + 2, n + Math.floor(u / 2)];
|
|
261
|
-
}
|
|
262
|
-
if (node.left === null) {
|
|
263
|
-
const [lines, n, p, u] = _displayAux(node.right);
|
|
264
|
-
const s = `${node.key}`;
|
|
265
|
-
const x = s.length;
|
|
266
|
-
const first_line = s + '_'.repeat(x) + ' '.repeat(n - x);
|
|
267
|
-
const second_line = ' '.repeat(u + x) + '\\' + ' '.repeat(n - x - 1);
|
|
268
|
-
const shifted_lines = lines.map(line => ' '.repeat(u) + line);
|
|
269
|
-
return [[first_line, second_line, ...shifted_lines], n + x, p + 2, Math.floor(u / 2)];
|
|
270
|
-
}
|
|
271
|
-
const [left, n, p, x] = _displayAux(node.left);
|
|
272
|
-
const [right, m, q, y] = _displayAux(node.right);
|
|
273
|
-
const s = `${node.key}`;
|
|
274
|
-
const u = s.length;
|
|
275
|
-
const first_line = ' '.repeat(x + 1) + '_'.repeat(n - x - 1) + s + '_'.repeat(y) + ' '.repeat(m - y);
|
|
276
|
-
const second_line = ' '.repeat(x) + '/' + ' '.repeat(n - x - 1 + u + y) + '\\' + ' '.repeat(m - y - 1);
|
|
277
|
-
if (p < q) {
|
|
278
|
-
left.push(...new Array(q - p).fill(' '.repeat(n)));
|
|
279
|
-
}
|
|
280
|
-
else if (q < p) {
|
|
281
|
-
right.push(...new Array(p - q).fill(' '.repeat(m)));
|
|
282
|
-
}
|
|
283
|
-
const zipped_lines = left.map((a, i) => a + ' '.repeat(u) + right[i]);
|
|
284
|
-
return [[first_line, second_line, ...zipped_lines], n + m + u, Math.max(p, q) + 2, n + Math.floor(u / 2)];
|
|
285
|
-
};
|
|
286
|
-
display(beginRoot);
|
|
238
|
+
_setRoot(v) {
|
|
239
|
+
if (v) {
|
|
240
|
+
v.parent = undefined;
|
|
241
|
+
}
|
|
242
|
+
this._root = v;
|
|
287
243
|
}
|
|
288
244
|
/**
|
|
289
245
|
* The function performs a left rotation on a red-black tree node.
|
|
290
246
|
* @param {RBTreeNode} x - The parameter `x` is a RBTreeNode object.
|
|
291
247
|
*/
|
|
292
248
|
_leftRotate(x) {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
y.left.
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
249
|
+
if (x.right) {
|
|
250
|
+
const y = x.right;
|
|
251
|
+
x.right = y.left;
|
|
252
|
+
if (y.left !== this.NIL) {
|
|
253
|
+
if (y.left)
|
|
254
|
+
y.left.parent = x;
|
|
255
|
+
}
|
|
256
|
+
y.parent = x.parent;
|
|
257
|
+
if (x.parent === undefined) {
|
|
258
|
+
this._setRoot(y);
|
|
259
|
+
}
|
|
260
|
+
else if (x === x.parent.left) {
|
|
261
|
+
x.parent.left = y;
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
x.parent.right = y;
|
|
265
|
+
}
|
|
266
|
+
y.left = x;
|
|
267
|
+
x.parent = y;
|
|
307
268
|
}
|
|
308
|
-
y.left = x;
|
|
309
|
-
x.parent = y;
|
|
310
269
|
}
|
|
311
270
|
/**
|
|
312
271
|
* The function performs a right rotation on a red-black tree node.
|
|
@@ -314,23 +273,26 @@ class RedBlackTree {
|
|
|
314
273
|
* rotated.
|
|
315
274
|
*/
|
|
316
275
|
_rightRotate(x) {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
y.right.
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
276
|
+
if (x.left) {
|
|
277
|
+
const y = x.left;
|
|
278
|
+
x.left = y.right;
|
|
279
|
+
if (y.right !== this.NIL) {
|
|
280
|
+
if (y.right)
|
|
281
|
+
y.right.parent = x;
|
|
282
|
+
}
|
|
283
|
+
y.parent = x.parent;
|
|
284
|
+
if (x.parent === undefined) {
|
|
285
|
+
this._setRoot(y);
|
|
286
|
+
}
|
|
287
|
+
else if (x === x.parent.right) {
|
|
288
|
+
x.parent.right = y;
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
x.parent.left = y;
|
|
292
|
+
}
|
|
293
|
+
y.right = x;
|
|
294
|
+
x.parent = y;
|
|
331
295
|
}
|
|
332
|
-
y.right = x;
|
|
333
|
-
x.parent = y;
|
|
334
296
|
}
|
|
335
297
|
/**
|
|
336
298
|
* The _fixDelete function is used to rebalance the Red-Black Tree after a node deletion.
|
|
@@ -340,7 +302,7 @@ class RedBlackTree {
|
|
|
340
302
|
_fixDelete(x) {
|
|
341
303
|
let s;
|
|
342
304
|
while (x !== this.root && x.color === types_1.RBTNColor.BLACK) {
|
|
343
|
-
if (x === x.parent.left) {
|
|
305
|
+
if (x.parent && x === x.parent.left) {
|
|
344
306
|
s = x.parent.right;
|
|
345
307
|
if (s.color === 1) {
|
|
346
308
|
s.color = types_1.RBTNColor.BLACK;
|
|
@@ -348,20 +310,23 @@ class RedBlackTree {
|
|
|
348
310
|
this._leftRotate(x.parent);
|
|
349
311
|
s = x.parent.right;
|
|
350
312
|
}
|
|
351
|
-
if (s.left !==
|
|
313
|
+
if (s.left !== undefined && s.left.color === types_1.RBTNColor.BLACK && s.right && s.right.color === types_1.RBTNColor.BLACK) {
|
|
352
314
|
s.color = types_1.RBTNColor.RED;
|
|
353
315
|
x = x.parent;
|
|
354
316
|
}
|
|
355
317
|
else {
|
|
356
|
-
if (s.right.color === types_1.RBTNColor.BLACK) {
|
|
357
|
-
s.left
|
|
318
|
+
if (s.right && s.right.color === types_1.RBTNColor.BLACK) {
|
|
319
|
+
if (s.left)
|
|
320
|
+
s.left.color = types_1.RBTNColor.BLACK;
|
|
358
321
|
s.color = types_1.RBTNColor.RED;
|
|
359
322
|
this._rightRotate(s);
|
|
360
323
|
s = x.parent.right;
|
|
361
324
|
}
|
|
362
|
-
s
|
|
325
|
+
if (s)
|
|
326
|
+
s.color = x.parent.color;
|
|
363
327
|
x.parent.color = types_1.RBTNColor.BLACK;
|
|
364
|
-
s
|
|
328
|
+
if (s && s.right)
|
|
329
|
+
s.right.color = types_1.RBTNColor.BLACK;
|
|
365
330
|
this._leftRotate(x.parent);
|
|
366
331
|
x = this.root;
|
|
367
332
|
}
|
|
@@ -374,20 +339,23 @@ class RedBlackTree {
|
|
|
374
339
|
this._rightRotate(x.parent);
|
|
375
340
|
s = x.parent.left;
|
|
376
341
|
}
|
|
377
|
-
if (s.right.color === types_1.RBTNColor.BLACK && s.right.color === types_1.RBTNColor.BLACK) {
|
|
342
|
+
if (s && s.right && s.right.color === types_1.RBTNColor.BLACK && s.right.color === types_1.RBTNColor.BLACK) {
|
|
378
343
|
s.color = types_1.RBTNColor.RED;
|
|
379
344
|
x = x.parent;
|
|
380
345
|
}
|
|
381
346
|
else {
|
|
382
|
-
if (s.left.color === types_1.RBTNColor.BLACK) {
|
|
383
|
-
s.right
|
|
347
|
+
if (s && s.left && s.left.color === types_1.RBTNColor.BLACK) {
|
|
348
|
+
if (s.right)
|
|
349
|
+
s.right.color = types_1.RBTNColor.BLACK;
|
|
384
350
|
s.color = types_1.RBTNColor.RED;
|
|
385
351
|
this._leftRotate(s);
|
|
386
352
|
s = x.parent.left;
|
|
387
353
|
}
|
|
388
|
-
s
|
|
354
|
+
if (s)
|
|
355
|
+
s.color = x.parent.color;
|
|
389
356
|
x.parent.color = types_1.RBTNColor.BLACK;
|
|
390
|
-
s
|
|
357
|
+
if (s && s.left)
|
|
358
|
+
s.left.color = types_1.RBTNColor.BLACK;
|
|
391
359
|
this._rightRotate(x.parent);
|
|
392
360
|
x = this.root;
|
|
393
361
|
}
|
|
@@ -401,8 +369,8 @@ class RedBlackTree {
|
|
|
401
369
|
* @param {RBTreeNode} v - The parameter "v" is a RBTreeNode object.
|
|
402
370
|
*/
|
|
403
371
|
_rbTransplant(u, v) {
|
|
404
|
-
if (u.parent ===
|
|
405
|
-
this.
|
|
372
|
+
if (u.parent === undefined) {
|
|
373
|
+
this._setRoot(v);
|
|
406
374
|
}
|
|
407
375
|
else if (u === u.parent.left) {
|
|
408
376
|
u.parent.left = v;
|
|
@@ -419,10 +387,10 @@ class RedBlackTree {
|
|
|
419
387
|
*/
|
|
420
388
|
_fixInsert(k) {
|
|
421
389
|
let u;
|
|
422
|
-
while (k.parent.color === 1) {
|
|
423
|
-
if (k.parent === k.parent.parent.right) {
|
|
390
|
+
while (k.parent && k.parent.color === 1) {
|
|
391
|
+
if (k.parent.parent && k.parent === k.parent.parent.right) {
|
|
424
392
|
u = k.parent.parent.left;
|
|
425
|
-
if (u.color === 1) {
|
|
393
|
+
if (u && u.color === 1) {
|
|
426
394
|
u.color = types_1.RBTNColor.BLACK;
|
|
427
395
|
k.parent.color = types_1.RBTNColor.BLACK;
|
|
428
396
|
k.parent.parent.color = types_1.RBTNColor.RED;
|
|
@@ -440,7 +408,7 @@ class RedBlackTree {
|
|
|
440
408
|
}
|
|
441
409
|
else {
|
|
442
410
|
u = k.parent.parent.right;
|
|
443
|
-
if (u.color === 1) {
|
|
411
|
+
if (u && u.color === 1) {
|
|
444
412
|
u.color = types_1.RBTNColor.BLACK;
|
|
445
413
|
k.parent.color = types_1.RBTNColor.BLACK;
|
|
446
414
|
k.parent.parent.color = types_1.RBTNColor.RED;
|