data-structure-typed 1.40.0 → 1.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +8 -0
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +22 -2
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/bst.d.ts +1 -1
- package/dist/cjs/data-structures/binary-tree/bst.js +1 -1
- package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +95 -9
- package/dist/cjs/data-structures/binary-tree/rb-tree.js +379 -12
- package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/cjs/types/data-structures/binary-tree/rb-tree.d.ts +3 -7
- package/dist/cjs/types/data-structures/binary-tree/rb-tree.js +11 -6
- package/dist/cjs/types/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +8 -0
- package/dist/mjs/data-structures/binary-tree/binary-tree.js +22 -2
- package/dist/mjs/data-structures/binary-tree/bst.d.ts +1 -1
- package/dist/mjs/data-structures/binary-tree/bst.js +1 -1
- package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +95 -9
- package/dist/mjs/data-structures/binary-tree/rb-tree.js +384 -13
- package/dist/mjs/types/data-structures/binary-tree/rb-tree.d.ts +3 -7
- package/dist/mjs/types/data-structures/binary-tree/rb-tree.js +11 -6
- 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 -5
- package/src/data-structures/binary-tree/binary-tree.ts +23 -1
- package/src/data-structures/binary-tree/bst.ts +4 -4
- package/src/data-structures/binary-tree/rb-tree.ts +418 -350
- package/src/types/data-structures/binary-tree/rb-tree.ts +6 -6
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +215 -82
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {BinaryTreeOptions} from './binary-tree';
|
|
2
|
-
import {RBTreeNode} from '../../../data-structures';
|
|
1
|
+
// import {BinaryTreeOptions} from './binary-tree';
|
|
2
|
+
// import {RBTreeNode} from '../../../data-structures';
|
|
3
3
|
|
|
4
|
-
export enum
|
|
4
|
+
export enum RBTNColor { RED = 1, BLACK = 0}
|
|
5
5
|
|
|
6
|
-
export type RBTreeNodeNested<T> = RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
7
|
-
|
|
8
|
-
export type RBTreeOptions = BinaryTreeOptions & {}
|
|
6
|
+
// export type RBTreeNodeNested<T> = RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, RBTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
7
|
+
//
|
|
8
|
+
// export type RBTreeOptions = BinaryTreeOptions & {}
|
|
@@ -1,109 +1,242 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RedBlackTree, RBTreeNode } from '../../../../src';
|
|
2
|
+
import {getRandomInt} from "../../../utils";
|
|
2
3
|
|
|
3
|
-
describe('
|
|
4
|
-
|
|
5
|
-
const node = new RBTreeNode<number>(1);
|
|
6
|
-
expect(node).toBeInstanceOf(RBTreeNode);
|
|
7
|
-
});
|
|
4
|
+
describe('RedBlackTree', () => {
|
|
5
|
+
let tree: RedBlackTree;
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
tree = new RedBlackTree();
|
|
9
|
+
});
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
describe('insert and getNode', () => {
|
|
12
|
+
test('should insert and find a node in the tree', () => {
|
|
13
|
+
tree.insert(10);
|
|
14
|
+
tree.insert(20);
|
|
15
|
+
tree.insert(5);
|
|
16
|
+
|
|
17
|
+
expect(tree.getNode(10)).toBeInstanceOf(RBTreeNode);
|
|
18
|
+
expect(tree.getNode(20)).toBeInstanceOf(RBTreeNode);
|
|
19
|
+
expect(tree.getNode(5)).toBeInstanceOf(RBTreeNode);
|
|
20
|
+
expect(tree.getNode(15)).toBe(tree.NIL);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('should insert and find nodes with negative keys', () => {
|
|
24
|
+
tree.insert(-10);
|
|
25
|
+
tree.insert(-20);
|
|
26
|
+
|
|
27
|
+
expect(tree.getNode(-10)).toBeInstanceOf(RBTreeNode);
|
|
28
|
+
expect(tree.getNode(-20)).toBeInstanceOf(RBTreeNode);
|
|
29
|
+
});
|
|
15
30
|
});
|
|
16
31
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
32
|
+
describe('deleteNode', () => {
|
|
33
|
+
test('should delete a node from the tree', () => {
|
|
34
|
+
tree.insert(10);
|
|
35
|
+
tree.insert(20);
|
|
36
|
+
tree.insert(5);
|
|
37
|
+
tree.delete(20);
|
|
38
|
+
|
|
39
|
+
expect(tree.getNode(20)).toBe(tree.NIL);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('should handle deleting a non-existent node', () => {
|
|
43
|
+
tree.insert(10);
|
|
44
|
+
tree.insert(20);
|
|
45
|
+
tree.insert(5);
|
|
46
|
+
tree.delete(15);
|
|
20
47
|
|
|
21
|
-
|
|
22
|
-
|
|
48
|
+
expect(tree.getNode(15)).toBe(tree.NIL);
|
|
49
|
+
});
|
|
23
50
|
});
|
|
24
51
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
52
|
+
describe('minimum', () => {
|
|
53
|
+
test('should find the minimum node in the tree', () => {
|
|
54
|
+
tree.insert(10);
|
|
55
|
+
tree.insert(20);
|
|
56
|
+
tree.insert(5);
|
|
57
|
+
tree.insert(15);
|
|
58
|
+
tree.insert(3);
|
|
59
|
+
|
|
60
|
+
const minNode = tree.getLeftMost(tree.root);
|
|
61
|
+
expect(minNode.key).toBe(3);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('should handle an empty tree', () => {
|
|
65
|
+
const minNode = tree.getLeftMost(tree.root);
|
|
66
|
+
expect(minNode).toBe(tree.NIL);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('getRightMost', () => {
|
|
71
|
+
test('should find the getRightMost node in the tree', () => {
|
|
72
|
+
tree.insert(10);
|
|
73
|
+
tree.insert(20);
|
|
74
|
+
tree.insert(5);
|
|
75
|
+
tree.insert(15);
|
|
76
|
+
tree.insert(25);
|
|
77
|
+
|
|
78
|
+
const maxNode = tree.getRightMost(tree.root);
|
|
79
|
+
expect(maxNode.key).toBe(25);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('should handle an empty tree', () => {
|
|
83
|
+
const maxNode = tree.getRightMost(tree.root);
|
|
84
|
+
expect(maxNode).toBe(tree.NIL);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
28
87
|
|
|
29
|
-
|
|
88
|
+
describe('getSuccessor', () => {
|
|
89
|
+
test('should find the getSuccessor of a node', () => {
|
|
90
|
+
tree.insert(10);
|
|
91
|
+
tree.insert(20);
|
|
92
|
+
tree.insert(5);
|
|
93
|
+
tree.insert(15);
|
|
94
|
+
tree.insert(25);
|
|
95
|
+
|
|
96
|
+
const node = tree.getNode(15);
|
|
97
|
+
const successorNode = tree.getSuccessor(node);
|
|
98
|
+
|
|
99
|
+
expect(successorNode.key).toBe(20);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test('should handle a node with no getSuccessor', () => {
|
|
103
|
+
tree.insert(10);
|
|
104
|
+
tree.insert(5);
|
|
105
|
+
|
|
106
|
+
const node = tree.getNode(10);
|
|
107
|
+
const successorNode = tree.getSuccessor(node);
|
|
108
|
+
// TODO not sure if it should be null or tree.NIL
|
|
109
|
+
expect(successorNode).toBe(null);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
30
112
|
|
|
31
|
-
|
|
32
|
-
|
|
113
|
+
describe('getPredecessor', () => {
|
|
114
|
+
test('should find the getPredecessor of a node', () => {
|
|
115
|
+
tree.insert(10);
|
|
116
|
+
tree.insert(20);
|
|
117
|
+
tree.insert(5);
|
|
118
|
+
tree.insert(15);
|
|
119
|
+
tree.insert(25);
|
|
120
|
+
|
|
121
|
+
const node = tree.getNode(20);
|
|
122
|
+
const predecessorNode = tree.getPredecessor(node);
|
|
123
|
+
|
|
124
|
+
expect(predecessorNode.key).toBe(15);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('should handle a node with no getPredecessor', () => {
|
|
128
|
+
tree.insert(10);
|
|
129
|
+
tree.insert(20);
|
|
130
|
+
|
|
131
|
+
const node = tree.getNode(20);
|
|
132
|
+
const predecessorNode = tree.getPredecessor(node);
|
|
133
|
+
// TODO not sure if it should be tree.NIL or something else.
|
|
134
|
+
expect(predecessorNode).toBe(tree.getNode(10));
|
|
135
|
+
});
|
|
33
136
|
});
|
|
137
|
+
});
|
|
34
138
|
|
|
35
|
-
it('should set and get the right child correctly', () => {
|
|
36
|
-
const node1 = new RBTreeNode<number>(1);
|
|
37
|
-
const node2 = new RBTreeNode<number>(2);
|
|
38
139
|
|
|
39
|
-
|
|
140
|
+
describe('RedBlackTree', () => {
|
|
141
|
+
let tree: RedBlackTree;
|
|
40
142
|
|
|
41
|
-
|
|
42
|
-
|
|
143
|
+
beforeEach(() => {
|
|
144
|
+
tree = new RedBlackTree();
|
|
43
145
|
});
|
|
44
146
|
|
|
45
|
-
it('should
|
|
46
|
-
|
|
47
|
-
|
|
147
|
+
it('should insert nodes into the tree', () => {
|
|
148
|
+
tree.insert(10);
|
|
149
|
+
expect(tree.getNode(10)).toBeDefined();
|
|
150
|
+
tree.insert(20);
|
|
151
|
+
expect(tree.getNode(20)).toBeDefined();
|
|
152
|
+
tree.insert(5);
|
|
153
|
+
expect(tree.getNode(5)).toBeDefined();
|
|
154
|
+
});
|
|
48
155
|
|
|
49
|
-
|
|
156
|
+
it('should delete nodes from the tree', () => {
|
|
157
|
+
tree.insert(10);
|
|
158
|
+
tree.insert(20);
|
|
159
|
+
tree.insert(5);
|
|
160
|
+
tree.delete(20);
|
|
161
|
+
expect(tree.getNode(20)).toBe(tree.NIL);
|
|
162
|
+
});
|
|
50
163
|
|
|
51
|
-
|
|
52
|
-
|
|
164
|
+
it('should get the successor of a node', () => {
|
|
165
|
+
tree.insert(10);
|
|
166
|
+
tree.insert(20);
|
|
167
|
+
const node = tree.getNode(10);
|
|
168
|
+
const successor = tree.getSuccessor(node);
|
|
169
|
+
expect(successor?.key).toBe(20);
|
|
53
170
|
});
|
|
54
171
|
|
|
55
|
-
it('should
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
172
|
+
it('should get the predecessor of a node', () => {
|
|
173
|
+
tree.insert(10);
|
|
174
|
+
tree.insert(20);
|
|
175
|
+
const node = tree.getNode(20);
|
|
176
|
+
const predecessor = tree.getPredecessor(node);
|
|
177
|
+
expect(predecessor?.key).toBe(10);
|
|
178
|
+
});
|
|
59
179
|
|
|
60
|
-
|
|
61
|
-
|
|
180
|
+
it('should rotate nodes to the left', () => {
|
|
181
|
+
tree.insert(10);
|
|
182
|
+
tree.insert(20);
|
|
183
|
+
tree.insert(5);
|
|
184
|
+
const node = tree.getNode(10);
|
|
185
|
+
tree.insert(15);
|
|
186
|
+
// Verify that rotation has occurred
|
|
187
|
+
expect(node.left.key).toBe(5);
|
|
188
|
+
expect(node.right.key).toBe(20);
|
|
189
|
+
});
|
|
62
190
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
191
|
+
it('should rotate nodes to the right', () => {
|
|
192
|
+
tree.insert(10);
|
|
193
|
+
tree.insert(20);
|
|
194
|
+
tree.insert(5);
|
|
195
|
+
const node = tree.getNode(20);
|
|
196
|
+
tree.insert(25);
|
|
197
|
+
// Verify that rotation has occurred
|
|
198
|
+
expect(node.left.key).toBe(0);
|
|
199
|
+
expect(node.right.key).toBe(25);
|
|
66
200
|
});
|
|
67
|
-
});
|
|
68
201
|
|
|
69
|
-
|
|
70
|
-
|
|
202
|
+
it('should fix the tree after deletion', () => {
|
|
203
|
+
tree.insert(10);
|
|
204
|
+
tree.insert(20);
|
|
205
|
+
tree.insert(5);
|
|
206
|
+
tree.insert(15);
|
|
207
|
+
tree.delete(15);
|
|
208
|
+
// Verify that the tree is still valid
|
|
209
|
+
// You can add assertions to check the Red-Black Tree properties
|
|
210
|
+
});
|
|
71
211
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
tree.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
// expect(tree.has(3)).toBe(false);
|
|
102
|
-
//
|
|
103
|
-
// // Perform in-order traversal to check if the tree is still balanced
|
|
104
|
-
// const inOrderTraverse: number[] = tree.DFS('in');
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
// expect(inOrderTraverse).toEqual([2, 4, 5, 6, 7, 8]);
|
|
212
|
+
it('should fix the tree after insertion', () => {
|
|
213
|
+
for (let i = 0; i < 1000; i++) {
|
|
214
|
+
tree.insert(getRandomInt(-100, 1000));
|
|
215
|
+
tree.delete(getRandomInt(-100, 1000));
|
|
216
|
+
}
|
|
217
|
+
tree.insert(1);
|
|
218
|
+
tree.insert(2);
|
|
219
|
+
tree.insert(5);
|
|
220
|
+
tree.insert(15);
|
|
221
|
+
tree.insert(25);
|
|
222
|
+
tree.insert(10);
|
|
223
|
+
tree.insert(8);
|
|
224
|
+
tree.insert(28);
|
|
225
|
+
tree.insert(111);
|
|
226
|
+
tree.insert(12);
|
|
227
|
+
tree.delete(2);
|
|
228
|
+
tree.insert(22);
|
|
229
|
+
tree.insert(50);
|
|
230
|
+
tree.insert(155);
|
|
231
|
+
tree.insert(225);
|
|
232
|
+
tree.insert(7);
|
|
233
|
+
tree.delete(15);
|
|
234
|
+
tree.insert(23);
|
|
235
|
+
tree.insert(33);
|
|
236
|
+
tree.insert(15);
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
// Verify that the tree is still a valid Red-Black Tree
|
|
240
|
+
// You can add assertions to check the Red-Black Tree properties
|
|
108
241
|
});
|
|
109
242
|
});
|