data-structure-typed 1.41.6 → 1.41.7
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 +11 -11
- package/benchmark/report.html +11 -11
- package/benchmark/report.json +111 -111
- package/dist/cjs/src/data-structures/graph/abstract-graph.js +5 -5
- package/dist/cjs/src/data-structures/graph/abstract-graph.js.map +1 -1
- package/dist/mjs/src/data-structures/graph/abstract-graph.js +5 -5
- 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/graph/abstract-graph.ts +6 -6
- package/test/config.ts +1 -0
- package/test/integration/avl-tree.test.ts +110 -0
- package/test/integration/bst.test.ts +385 -0
- package/test/integration/heap.test.js +16 -0
- package/test/integration/index.html +51 -0
- package/test/performance/data-structures/binary-tree/avl-tree.test.ts +36 -0
- package/test/performance/data-structures/binary-tree/binary-index-tree.test.ts +0 -0
- package/test/performance/data-structures/binary-tree/binary-tree.test.ts +45 -0
- package/test/performance/data-structures/binary-tree/bst.test.ts +36 -0
- package/test/performance/data-structures/binary-tree/overall.test.ts +0 -0
- package/test/performance/data-structures/binary-tree/rb-tree.test.ts +0 -0
- package/test/performance/data-structures/binary-tree/segment-tree.test.ts +0 -0
- package/test/performance/data-structures/binary-tree/tree-multiset.test.ts +0 -0
- package/test/performance/data-structures/graph/abstract-graph.test.ts +0 -0
- package/test/performance/data-structures/graph/directed-graph.test.ts +49 -0
- package/test/performance/data-structures/graph/map-graph.test.ts +0 -0
- package/test/performance/data-structures/graph/overall.test.ts +0 -0
- package/test/performance/data-structures/graph/undirected-graph.test.ts +0 -0
- package/test/performance/data-structures/hash/coordinate-map.test.ts +0 -0
- package/test/performance/data-structures/hash/coordinate-set.test.ts +0 -0
- package/test/performance/data-structures/hash/hash-map.test.ts +0 -0
- package/test/performance/data-structures/hash/hash-table.test.ts +0 -0
- package/test/performance/data-structures/heap/heap.test.ts +30 -0
- package/test/performance/data-structures/heap/max-heap.test.ts +0 -0
- package/test/performance/data-structures/heap/min-heap.test.ts +0 -0
- package/test/performance/data-structures/linked-list/doubly-linked-list.test.ts +40 -0
- package/test/performance/data-structures/linked-list/linked-list.test.ts +0 -0
- package/test/performance/data-structures/linked-list/singly-linked-list.test.ts +34 -0
- package/test/performance/data-structures/linked-list/skip-linked-list.test.ts +0 -0
- package/test/performance/data-structures/linked-list/skip-list.test.ts +0 -0
- package/test/performance/data-structures/matrix/matrix.test.ts +0 -0
- package/test/performance/data-structures/matrix/matrix2d.test.ts +0 -0
- package/test/performance/data-structures/matrix/navigator.test.ts +0 -0
- package/test/performance/data-structures/matrix/vector2d.test.ts +0 -0
- package/test/performance/data-structures/priority-queue/max-priority-queue.test.ts +19 -0
- package/test/performance/data-structures/priority-queue/min-priority-queue.test.ts +0 -0
- package/test/performance/data-structures/priority-queue/priority-queue.test.ts +0 -0
- package/test/performance/data-structures/queue/deque.test.ts +21 -0
- package/test/performance/data-structures/queue/queue.test.ts +25 -0
- package/test/performance/data-structures/stack/stack.test.ts +0 -0
- package/test/performance/data-structures/tree/tree.test.ts +0 -0
- package/test/performance/data-structures/trie/trie.test.ts +22 -0
- package/test/performance/reportor.ts +186 -0
- package/test/performance/types/index.ts +1 -0
- package/test/performance/types/reportor.ts +3 -0
- package/test/types/index.ts +1 -0
- package/test/types/utils/big-o.ts +1 -0
- package/test/types/utils/index.ts +2 -0
- package/test/types/utils/json2html.ts +1 -0
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +269 -0
- package/test/unit/data-structures/binary-tree/binary-index-tree.test.ts +320 -0
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +486 -0
- package/test/unit/data-structures/binary-tree/bst.test.ts +840 -0
- package/test/unit/data-structures/binary-tree/overall.test.ts +66 -0
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +435 -0
- package/test/unit/data-structures/binary-tree/segment-tree.test.ts +50 -0
- package/test/unit/data-structures/binary-tree/tree-multiset.test.ts +542 -0
- package/test/unit/data-structures/graph/abstract-graph.test.ts +100 -0
- package/test/unit/data-structures/graph/directed-graph.test.ts +564 -0
- package/test/unit/data-structures/graph/map-graph.test.ts +126 -0
- package/test/unit/data-structures/graph/overall.test.ts +49 -0
- package/test/unit/data-structures/graph/salty-edges.json +1 -0
- package/test/unit/data-structures/graph/salty-vertexes.json +1 -0
- package/test/unit/data-structures/graph/undirected-graph.test.ts +168 -0
- package/test/unit/data-structures/hash/coordinate-map.test.ts +74 -0
- package/test/unit/data-structures/hash/coordinate-set.test.ts +66 -0
- package/test/unit/data-structures/hash/hash-map.test.ts +103 -0
- package/test/unit/data-structures/hash/hash-table.test.ts +186 -0
- package/test/unit/data-structures/heap/heap.test.ts +254 -0
- package/test/unit/data-structures/heap/max-heap.test.ts +52 -0
- package/test/unit/data-structures/heap/min-heap.test.ts +52 -0
- package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +400 -0
- package/test/unit/data-structures/linked-list/linked-list.test.ts +8 -0
- package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +474 -0
- package/test/unit/data-structures/linked-list/skip-linked-list.test.ts +13 -0
- package/test/unit/data-structures/linked-list/skip-list.test.ts +86 -0
- package/test/unit/data-structures/matrix/matrix.test.ts +54 -0
- package/test/unit/data-structures/matrix/matrix2d.test.ts +345 -0
- package/test/unit/data-structures/matrix/navigator.test.ts +244 -0
- package/test/unit/data-structures/matrix/vector2d.test.ts +171 -0
- package/test/unit/data-structures/priority-queue/max-priority-queue.test.ts +73 -0
- package/test/unit/data-structures/priority-queue/min-priority-queue.test.ts +63 -0
- package/test/unit/data-structures/priority-queue/priority-queue.test.ts +53 -0
- package/test/unit/data-structures/queue/deque.test.ts +410 -0
- package/test/unit/data-structures/queue/queue.test.ts +207 -0
- package/test/unit/data-structures/stack/stack.test.ts +67 -0
- package/test/unit/data-structures/tree/tree.test.ts +39 -0
- package/test/unit/data-structures/trie/trie.test.ts +825 -0
- package/test/utils/array.ts +5514 -0
- package/test/utils/big-o.ts +207 -0
- package/test/utils/console.ts +31 -0
- package/test/utils/index.ts +7 -0
- package/test/utils/is.ts +56 -0
- package/test/utils/json2html.ts +322 -0
- package/test/utils/number.ts +13 -0
- package/test/utils/string.ts +1 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import {AVLTree, BST} from '../../../../src';
|
|
2
|
+
|
|
3
|
+
describe('Overall BinaryTree Test', () => {
|
|
4
|
+
it('should perform various operations on BinaryTree', () => {
|
|
5
|
+
const bst = new BST();
|
|
6
|
+
bst.add(11);
|
|
7
|
+
bst.add(3);
|
|
8
|
+
bst.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5], undefined, false);
|
|
9
|
+
bst.size === 16; // true
|
|
10
|
+
expect(bst.size).toBe(16); // true
|
|
11
|
+
bst.has(6); // true
|
|
12
|
+
expect(bst.has(6)).toBe(true); // true
|
|
13
|
+
bst.getHeight(6) === 2; // true
|
|
14
|
+
bst.getHeight() === 5; // true
|
|
15
|
+
bst.getDepth(6) === 3; // true
|
|
16
|
+
expect(bst.getHeight(6)).toBe(2); // true
|
|
17
|
+
expect(bst.getHeight()).toBe(5); // true
|
|
18
|
+
expect(bst.getDepth(6)).toBe(3); // true
|
|
19
|
+
const leftMost = bst.getLeftMost();
|
|
20
|
+
leftMost?.key === 1; // true
|
|
21
|
+
expect(leftMost?.key).toBe(1);
|
|
22
|
+
bst.delete(6);
|
|
23
|
+
bst.getNode(6); // null
|
|
24
|
+
expect(bst.getNode(6)).toBeNull();
|
|
25
|
+
bst.isAVLBalanced(); // true or false
|
|
26
|
+
expect(bst.isAVLBalanced()).toBe(true);
|
|
27
|
+
const bfsIDs: number[] = [];
|
|
28
|
+
bst.bfs(node => bfsIDs.push(node.key));
|
|
29
|
+
bfsIDs[0] === 11; // true
|
|
30
|
+
expect(bfsIDs[0]).toBe(11);
|
|
31
|
+
|
|
32
|
+
const objBST = new BST<{key: number; keyA: number}>();
|
|
33
|
+
objBST.add(11, {key: 11, keyA: 11});
|
|
34
|
+
objBST.add(3, {key: 3, keyA: 3});
|
|
35
|
+
|
|
36
|
+
objBST.addMany(
|
|
37
|
+
[15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5],
|
|
38
|
+
[
|
|
39
|
+
{key: 15, keyA: 15},
|
|
40
|
+
{key: 1, keyA: 1},
|
|
41
|
+
{key: 8, keyA: 8},
|
|
42
|
+
{key: 13, keyA: 13},
|
|
43
|
+
{key: 16, keyA: 16},
|
|
44
|
+
{key: 2, keyA: 2},
|
|
45
|
+
{key: 6, keyA: 6},
|
|
46
|
+
{key: 9, keyA: 9},
|
|
47
|
+
{key: 12, keyA: 12},
|
|
48
|
+
{key: 14, keyA: 14},
|
|
49
|
+
{key: 4, keyA: 4},
|
|
50
|
+
{key: 7, keyA: 7},
|
|
51
|
+
{key: 10, keyA: 10},
|
|
52
|
+
{key: 5, keyA: 5}
|
|
53
|
+
]
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
objBST.delete(11);
|
|
57
|
+
|
|
58
|
+
const avlTree = new AVLTree();
|
|
59
|
+
avlTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]);
|
|
60
|
+
avlTree.isAVLBalanced(); // true
|
|
61
|
+
expect(avlTree.isAVLBalanced()).toBe(true); // true
|
|
62
|
+
avlTree.delete(10);
|
|
63
|
+
avlTree.isAVLBalanced(); // true
|
|
64
|
+
expect(avlTree.isAVLBalanced()).toBe(true); // true
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
import {NIL, RBTNColor, RBTreeNode, RedBlackTree} from '../../../../src';
|
|
2
|
+
import {getRandomInt} from '../../../utils';
|
|
3
|
+
import {isDebugTest} from '../../../config';
|
|
4
|
+
|
|
5
|
+
const isDebug = isDebugTest;
|
|
6
|
+
|
|
7
|
+
describe('RedBlackTree', () => {
|
|
8
|
+
let tree: RedBlackTree;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
tree = new RedBlackTree();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
describe('insert and getNode', () => {
|
|
15
|
+
test('should insert and find a node in the tree', () => {
|
|
16
|
+
tree.insert(10);
|
|
17
|
+
tree.insert(20);
|
|
18
|
+
tree.insert(5);
|
|
19
|
+
|
|
20
|
+
expect(tree.getNode(10)).toBeInstanceOf(RBTreeNode);
|
|
21
|
+
expect(tree.getNode(20)).toBeInstanceOf(RBTreeNode);
|
|
22
|
+
expect(tree.getNode(5)).toBeInstanceOf(RBTreeNode);
|
|
23
|
+
expect(tree.getNode(15)).toBe(null);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('should insert and find nodes with negative keys', () => {
|
|
27
|
+
tree.insert(-10);
|
|
28
|
+
tree.insert(-20);
|
|
29
|
+
|
|
30
|
+
expect(tree.getNode(-10)).toBeInstanceOf(RBTreeNode);
|
|
31
|
+
expect(tree.getNode(-20)).toBeInstanceOf(RBTreeNode);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe('deleteNode', () => {
|
|
36
|
+
test('should delete a node from the tree', () => {
|
|
37
|
+
tree.insert(10);
|
|
38
|
+
tree.insert(20);
|
|
39
|
+
tree.insert(5);
|
|
40
|
+
tree.delete(20);
|
|
41
|
+
|
|
42
|
+
expect(tree.getNode(20)).toBe(null);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('should handle deleting a non-existent node', () => {
|
|
46
|
+
tree.insert(10);
|
|
47
|
+
tree.insert(20);
|
|
48
|
+
tree.insert(5);
|
|
49
|
+
tree.delete(15);
|
|
50
|
+
|
|
51
|
+
expect(tree.getNode(15)).toBe(null);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('minimum', () => {
|
|
56
|
+
test('should find the minimum node in the tree', () => {
|
|
57
|
+
tree.insert(10);
|
|
58
|
+
tree.insert(20);
|
|
59
|
+
tree.insert(5);
|
|
60
|
+
tree.insert(15);
|
|
61
|
+
tree.insert(3);
|
|
62
|
+
|
|
63
|
+
const minNode = tree.getLeftMost(tree.root);
|
|
64
|
+
expect(minNode.key).toBe(3);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('should handle an empty tree', () => {
|
|
68
|
+
const minNode = tree.getLeftMost(tree.root);
|
|
69
|
+
expect(minNode).toBe(NIL);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe('getRightMost', () => {
|
|
74
|
+
test('should find the getRightMost node in the tree', () => {
|
|
75
|
+
tree.insert(10);
|
|
76
|
+
tree.insert(20);
|
|
77
|
+
tree.insert(5);
|
|
78
|
+
tree.insert(15);
|
|
79
|
+
tree.insert(25);
|
|
80
|
+
|
|
81
|
+
const maxNode = tree.getRightMost(tree.root);
|
|
82
|
+
expect(maxNode.key).toBe(25);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test('should handle an empty tree', () => {
|
|
86
|
+
const maxNode = tree.getRightMost(tree.root);
|
|
87
|
+
expect(maxNode).toBe(NIL);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
describe('getSuccessor', () => {
|
|
92
|
+
test('should find the getSuccessor of a node', () => {
|
|
93
|
+
tree.insert(10);
|
|
94
|
+
tree.insert(20);
|
|
95
|
+
tree.insert(5);
|
|
96
|
+
tree.insert(15);
|
|
97
|
+
tree.insert(25);
|
|
98
|
+
|
|
99
|
+
const node = tree.getNode(15);
|
|
100
|
+
const successorNode = tree.getSuccessor(node);
|
|
101
|
+
|
|
102
|
+
expect(successorNode.key).toBe(20);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test('should handle a node with no getSuccessor', () => {
|
|
106
|
+
tree.insert(10);
|
|
107
|
+
tree.insert(5);
|
|
108
|
+
|
|
109
|
+
const node = tree.getNode(10);
|
|
110
|
+
const successorNode = tree.getSuccessor(node);
|
|
111
|
+
// TODO not sure if it should be null or NIL
|
|
112
|
+
expect(successorNode).toBe(null);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe('getPredecessor', () => {
|
|
117
|
+
test('should find the getPredecessor of a node', () => {
|
|
118
|
+
tree.insert(10);
|
|
119
|
+
tree.insert(20);
|
|
120
|
+
tree.insert(5);
|
|
121
|
+
tree.insert(15);
|
|
122
|
+
tree.insert(25);
|
|
123
|
+
|
|
124
|
+
const node = tree.getNode(20);
|
|
125
|
+
const predecessorNode = tree.getPredecessor(node);
|
|
126
|
+
|
|
127
|
+
expect(predecessorNode.key).toBe(15);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test('should handle a node with no getPredecessor', () => {
|
|
131
|
+
tree.insert(10);
|
|
132
|
+
tree.insert(20);
|
|
133
|
+
|
|
134
|
+
const node = tree.getNode(20);
|
|
135
|
+
const predecessorNode = tree.getPredecessor(node);
|
|
136
|
+
// TODO not sure if it should be NIL or something else.
|
|
137
|
+
expect(predecessorNode).toBe(tree.getNode(10));
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
describe('RedBlackTree', () => {
|
|
143
|
+
let tree: RedBlackTree;
|
|
144
|
+
|
|
145
|
+
beforeEach(() => {
|
|
146
|
+
tree = new RedBlackTree();
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('should insert nodes into the tree', () => {
|
|
150
|
+
tree.insert(10);
|
|
151
|
+
expect(tree.getNode(10)).toBeDefined();
|
|
152
|
+
tree.insert(20);
|
|
153
|
+
expect(tree.getNode(20)).toBeDefined();
|
|
154
|
+
tree.insert(5);
|
|
155
|
+
expect(tree.getNode(5)).toBeDefined();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('should delete nodes from the tree', () => {
|
|
159
|
+
tree.insert(10);
|
|
160
|
+
tree.insert(20);
|
|
161
|
+
tree.insert(5);
|
|
162
|
+
tree.delete(20);
|
|
163
|
+
expect(tree.getNode(20)).toBe(null);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('should get the successor of a node', () => {
|
|
167
|
+
tree.insert(10);
|
|
168
|
+
tree.insert(20);
|
|
169
|
+
const node = tree.getNode(10);
|
|
170
|
+
const successor = tree.getSuccessor(node);
|
|
171
|
+
expect(successor?.key).toBe(20);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('should get the predecessor of a node', () => {
|
|
175
|
+
tree.insert(10);
|
|
176
|
+
tree.insert(20);
|
|
177
|
+
const node = tree.getNode(20);
|
|
178
|
+
const predecessor = tree.getPredecessor(node);
|
|
179
|
+
expect(predecessor?.key).toBe(10);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('should rotate nodes to the left', () => {
|
|
183
|
+
tree.insert(10);
|
|
184
|
+
tree.insert(20);
|
|
185
|
+
tree.insert(5);
|
|
186
|
+
const node = tree.getNode(10);
|
|
187
|
+
tree.insert(15);
|
|
188
|
+
// Verify that rotation has occurred
|
|
189
|
+
expect(node.left.key).toBe(5);
|
|
190
|
+
expect(node.right.key).toBe(20);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('should rotate nodes to the right', () => {
|
|
194
|
+
tree.insert(10);
|
|
195
|
+
tree.insert(20);
|
|
196
|
+
tree.insert(5);
|
|
197
|
+
const node = tree.getNode(20);
|
|
198
|
+
tree.insert(25);
|
|
199
|
+
// Verify that rotation has occurred
|
|
200
|
+
expect(node.left.key).toBe(0);
|
|
201
|
+
expect(node.right.key).toBe(25);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it('should all node attributes fully conform to the red-black tree standards.', () => {
|
|
205
|
+
tree.insert(10);
|
|
206
|
+
tree.insert(20);
|
|
207
|
+
tree.insert(5);
|
|
208
|
+
tree.insert(15);
|
|
209
|
+
tree.insert(21);
|
|
210
|
+
tree.insert(6);
|
|
211
|
+
tree.insert(2);
|
|
212
|
+
|
|
213
|
+
let node10F = tree.getNode(10);
|
|
214
|
+
let node20F = tree.getNode(20);
|
|
215
|
+
let node5F = tree.getNode(5);
|
|
216
|
+
let node15F = tree.getNode(15);
|
|
217
|
+
let node21F = tree.getNode(21);
|
|
218
|
+
let node6F = tree.getNode(6);
|
|
219
|
+
let node2F = tree.getNode(2);
|
|
220
|
+
expect(node10F.key).toBe(10);
|
|
221
|
+
expect(node10F.color).toBe(RBTNColor.BLACK);
|
|
222
|
+
expect(node10F.left).toBe(node5F);
|
|
223
|
+
expect(node10F.right).toBe(node20F);
|
|
224
|
+
expect(node10F.parent).toBe(null);
|
|
225
|
+
expect(node20F.key).toBe(20);
|
|
226
|
+
expect(node20F.color).toBe(RBTNColor.BLACK);
|
|
227
|
+
expect(node20F.left).toBe(node15F);
|
|
228
|
+
expect(node20F.right).toBe(node21F);
|
|
229
|
+
expect(node20F.parent).toBe(node10F);
|
|
230
|
+
expect(node5F.key).toBe(5);
|
|
231
|
+
expect(node5F.color).toBe(RBTNColor.BLACK);
|
|
232
|
+
expect(node5F.left).toBe(node2F);
|
|
233
|
+
expect(node5F.right).toBe(node6F);
|
|
234
|
+
expect(node5F.parent).toBe(node10F);
|
|
235
|
+
expect(node15F.key).toBe(15);
|
|
236
|
+
expect(node15F.color).toBe(RBTNColor.RED);
|
|
237
|
+
expect(node15F.left).toBe(NIL);
|
|
238
|
+
expect(node15F.right).toBe(NIL);
|
|
239
|
+
expect(node15F.parent).toBe(node20F);
|
|
240
|
+
expect(node21F.key).toBe(21);
|
|
241
|
+
expect(node21F.color).toBe(RBTNColor.RED);
|
|
242
|
+
expect(node21F.left).toBe(NIL);
|
|
243
|
+
expect(node21F.right).toBe(NIL);
|
|
244
|
+
expect(node21F.parent).toBe(node20F);
|
|
245
|
+
expect(node6F.key).toBe(6);
|
|
246
|
+
expect(node6F.color).toBe(RBTNColor.RED);
|
|
247
|
+
expect(node6F.left).toBe(NIL);
|
|
248
|
+
expect(node6F.right).toBe(NIL);
|
|
249
|
+
expect(node6F.parent).toBe(node5F);
|
|
250
|
+
expect(node2F.key).toBe(2);
|
|
251
|
+
expect(node2F.color).toBe(RBTNColor.RED);
|
|
252
|
+
expect(node2F.left).toBe(NIL);
|
|
253
|
+
expect(node2F.right).toBe(NIL);
|
|
254
|
+
expect(node2F.parent).toBe(node5F);
|
|
255
|
+
expect(node15F.key).toBe(15);
|
|
256
|
+
expect(node15F.color).toBe(RBTNColor.RED);
|
|
257
|
+
expect(node15F.left).toBe(NIL);
|
|
258
|
+
expect(node15F.right).toBe(NIL);
|
|
259
|
+
expect(node15F.parent).toBe(node20F);
|
|
260
|
+
tree.delete(5);
|
|
261
|
+
node10F = tree.getNode(10);
|
|
262
|
+
node20F = tree.getNode(20);
|
|
263
|
+
node5F = tree.getNode(5);
|
|
264
|
+
node15F = tree.getNode(15);
|
|
265
|
+
node21F = tree.getNode(21);
|
|
266
|
+
node6F = tree.getNode(6);
|
|
267
|
+
node2F = tree.getNode(2);
|
|
268
|
+
expect(node10F.key).toBe(10);
|
|
269
|
+
expect(node10F.color).toBe(RBTNColor.BLACK);
|
|
270
|
+
expect(node10F.left).toBe(node6F);
|
|
271
|
+
expect(node10F.right).toBe(node20F);
|
|
272
|
+
expect(node10F.parent).toBe(null);
|
|
273
|
+
expect(node20F.key).toBe(20);
|
|
274
|
+
expect(node20F.color).toBe(RBTNColor.BLACK);
|
|
275
|
+
expect(node20F.left).toBe(node15F);
|
|
276
|
+
expect(node20F.right).toBe(node21F);
|
|
277
|
+
expect(node20F.parent).toBe(node10F);
|
|
278
|
+
expect(node5F).toBe(null);
|
|
279
|
+
expect(node15F.key).toBe(15);
|
|
280
|
+
expect(node15F.color).toBe(RBTNColor.RED);
|
|
281
|
+
expect(node15F.left).toBe(NIL);
|
|
282
|
+
expect(node15F.right).toBe(NIL);
|
|
283
|
+
expect(node15F.parent).toBe(node20F);
|
|
284
|
+
expect(node21F.key).toBe(21);
|
|
285
|
+
expect(node21F.color).toBe(RBTNColor.RED);
|
|
286
|
+
expect(node21F.left).toBe(NIL);
|
|
287
|
+
expect(node21F.right).toBe(NIL);
|
|
288
|
+
expect(node21F.parent).toBe(node20F);
|
|
289
|
+
expect(node6F.key).toBe(6);
|
|
290
|
+
expect(node6F.color).toBe(RBTNColor.BLACK);
|
|
291
|
+
expect(node6F.left).toBe(node2F);
|
|
292
|
+
expect(node6F.right).toBe(NIL);
|
|
293
|
+
expect(node6F.parent).toBe(node10F);
|
|
294
|
+
expect(node2F.key).toBe(2);
|
|
295
|
+
expect(node2F.color).toBe(RBTNColor.RED);
|
|
296
|
+
expect(node2F.left).toBe(NIL);
|
|
297
|
+
expect(node2F.right).toBe(NIL);
|
|
298
|
+
expect(node2F.parent).toBe(node6F);
|
|
299
|
+
expect(node15F.key).toBe(15);
|
|
300
|
+
expect(node15F.color).toBe(RBTNColor.RED);
|
|
301
|
+
expect(node15F.left).toBe(NIL);
|
|
302
|
+
expect(node15F.right).toBe(NIL);
|
|
303
|
+
expect(node15F.parent).toBe(node20F);
|
|
304
|
+
tree.delete(20);
|
|
305
|
+
node10F = tree.getNode(10);
|
|
306
|
+
node20F = tree.getNode(20);
|
|
307
|
+
node5F = tree.getNode(5);
|
|
308
|
+
node15F = tree.getNode(15);
|
|
309
|
+
node21F = tree.getNode(21);
|
|
310
|
+
node6F = tree.getNode(6);
|
|
311
|
+
node2F = tree.getNode(2);
|
|
312
|
+
expect(node10F.key).toBe(10);
|
|
313
|
+
expect(node10F.color).toBe(RBTNColor.BLACK);
|
|
314
|
+
expect(node10F.left).toBe(node6F);
|
|
315
|
+
expect(node10F.right).toBe(node21F);
|
|
316
|
+
expect(node10F.parent).toBe(null);
|
|
317
|
+
expect(node20F).toBe(null);
|
|
318
|
+
expect(node5F).toBe(null);
|
|
319
|
+
expect(node15F.key).toBe(15);
|
|
320
|
+
expect(node15F.color).toBe(RBTNColor.RED);
|
|
321
|
+
expect(node15F.left).toBe(NIL);
|
|
322
|
+
expect(node15F.right).toBe(NIL);
|
|
323
|
+
expect(node15F.parent).toBe(node21F);
|
|
324
|
+
expect(node21F.key).toBe(21);
|
|
325
|
+
expect(node21F.color).toBe(RBTNColor.BLACK);
|
|
326
|
+
expect(node21F.left).toBe(node15F);
|
|
327
|
+
expect(node21F.right).toBe(NIL);
|
|
328
|
+
expect(node21F.parent).toBe(node10F);
|
|
329
|
+
expect(node6F.key).toBe(6);
|
|
330
|
+
expect(node6F.color).toBe(RBTNColor.BLACK);
|
|
331
|
+
expect(node6F.left).toBe(node2F);
|
|
332
|
+
expect(node6F.right).toBe(NIL);
|
|
333
|
+
expect(node6F.parent).toBe(node10F);
|
|
334
|
+
expect(node2F.key).toBe(2);
|
|
335
|
+
expect(node2F.color).toBe(RBTNColor.RED);
|
|
336
|
+
expect(node2F.left).toBe(NIL);
|
|
337
|
+
expect(node2F.right).toBe(NIL);
|
|
338
|
+
expect(node2F.parent).toBe(node6F);
|
|
339
|
+
expect(node15F.key).toBe(15);
|
|
340
|
+
expect(node15F.color).toBe(RBTNColor.RED);
|
|
341
|
+
expect(node15F.left).toBe(NIL);
|
|
342
|
+
expect(node15F.right).toBe(NIL);
|
|
343
|
+
expect(node15F.parent).toBe(node21F);
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
it('should fix the tree after insertion', () => {
|
|
347
|
+
tree.insert(1);
|
|
348
|
+
tree.insert(2);
|
|
349
|
+
tree.insert(5);
|
|
350
|
+
tree.insert(15);
|
|
351
|
+
const node15F = tree.getNode(15);
|
|
352
|
+
expect(node15F.left).toBe(NIL);
|
|
353
|
+
expect(node15F.right).toBe(NIL);
|
|
354
|
+
expect(node15F.parent).toBe(tree.getNode(5));
|
|
355
|
+
|
|
356
|
+
tree.insert(25);
|
|
357
|
+
tree.insert(10);
|
|
358
|
+
tree.insert(8);
|
|
359
|
+
tree.insert(28);
|
|
360
|
+
tree.insert(111);
|
|
361
|
+
tree.insert(12);
|
|
362
|
+
tree.delete(2);
|
|
363
|
+
tree.insert(22);
|
|
364
|
+
tree.insert(50);
|
|
365
|
+
tree.insert(155);
|
|
366
|
+
tree.insert(225);
|
|
367
|
+
const node225F = tree.getNode(225);
|
|
368
|
+
expect(node225F.left).toBe(NIL);
|
|
369
|
+
expect(node225F.right).toBe(NIL);
|
|
370
|
+
expect(node225F.parent.key).toBe(155);
|
|
371
|
+
tree.insert(7);
|
|
372
|
+
|
|
373
|
+
const node15S = tree.getNode(15);
|
|
374
|
+
expect(node15S.left.key).toBe(8);
|
|
375
|
+
expect(node15S.right.key).toBe(28);
|
|
376
|
+
expect(node15S).toBe(tree.root);
|
|
377
|
+
expect(node15S.parent).toBe(null);
|
|
378
|
+
tree.delete(15);
|
|
379
|
+
expect(tree.root.key).toBe(22);
|
|
380
|
+
expect(tree.root.parent).toBe(null);
|
|
381
|
+
|
|
382
|
+
const node15T = tree.getNode(15);
|
|
383
|
+
expect(node15T).toBe(null);
|
|
384
|
+
|
|
385
|
+
tree.insert(23);
|
|
386
|
+
tree.insert(33);
|
|
387
|
+
tree.insert(15);
|
|
388
|
+
|
|
389
|
+
const nodeLM = tree.getLeftMost();
|
|
390
|
+
expect(nodeLM.key).toBe(1);
|
|
391
|
+
|
|
392
|
+
const node50 = tree.getNode(50);
|
|
393
|
+
expect(node50.key).toBe(50);
|
|
394
|
+
expect(node50.left.key).toBe(33);
|
|
395
|
+
expect(node50.right).toBe(NIL);
|
|
396
|
+
const node15Fo = tree.getNode(15);
|
|
397
|
+
|
|
398
|
+
expect(node15Fo.key).toBe(15);
|
|
399
|
+
expect(node15Fo.left).toBe(NIL);
|
|
400
|
+
const node225S = tree.getNode(225);
|
|
401
|
+
expect(node225S.left).toBe(NIL);
|
|
402
|
+
expect(node225S.right).toBe(NIL);
|
|
403
|
+
expect(node225S.parent.key).toBe(155);
|
|
404
|
+
expect(tree.getNode(0)).toBe(null);
|
|
405
|
+
tree.insert(1);
|
|
406
|
+
tree.insert(2);
|
|
407
|
+
tree.insert(3);
|
|
408
|
+
tree.insert(4);
|
|
409
|
+
tree.insert(5);
|
|
410
|
+
tree.insert(6);
|
|
411
|
+
tree.insert(7);
|
|
412
|
+
tree.insert(8);
|
|
413
|
+
tree.insert(9);
|
|
414
|
+
tree.insert(10);
|
|
415
|
+
tree.insert(11);
|
|
416
|
+
tree.insert(12);
|
|
417
|
+
tree.insert(13);
|
|
418
|
+
tree.insert(14);
|
|
419
|
+
tree.insert(15);
|
|
420
|
+
tree.insert(16);
|
|
421
|
+
tree.insert(17);
|
|
422
|
+
tree.insert(18);
|
|
423
|
+
tree.insert(19);
|
|
424
|
+
tree.insert(110);
|
|
425
|
+
|
|
426
|
+
isDebug && tree.print();
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
it('should fix the tree after insertion and deletion', () => {
|
|
430
|
+
for (let i = 0; i < 100; i++) {
|
|
431
|
+
tree.insert(getRandomInt(-100, 1000));
|
|
432
|
+
tree.delete(getRandomInt(-100, 1000));
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {SegmentTree} from '../../../../src';
|
|
2
|
+
|
|
3
|
+
describe('SegmentTree', () => {
|
|
4
|
+
let segmentTree: SegmentTree;
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
// Create an example SegmentTree for testing
|
|
8
|
+
const values = [1, 2, 3, 4, 5];
|
|
9
|
+
segmentTree = new SegmentTree(values);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('should build a valid segment tree', () => {
|
|
13
|
+
// Check if the root node's sum is correct
|
|
14
|
+
expect(segmentTree.root?.sum).toBe(15);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('should update a node in the segment tree', () => {
|
|
18
|
+
// Update a node value
|
|
19
|
+
segmentTree.updateNode(2, 10);
|
|
20
|
+
|
|
21
|
+
// Check if the sum of the root node is correct after the update
|
|
22
|
+
expect(segmentTree.root?.sum).toBe(22);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should query sum by range correctly', () => {
|
|
26
|
+
// Check if the sum within a specific range is correct
|
|
27
|
+
expect(segmentTree.querySumByRange(1, 3)).toBe(9); // 2 + 3 + 4 = 9
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should handle edge cases for querySumByRange', () => {
|
|
31
|
+
// Check behavior when the range goes beyond boundaries
|
|
32
|
+
expect(segmentTree.querySumByRange(0, 4)).toBe(15); // Valid range, should return sum of the specified range
|
|
33
|
+
expect(segmentTree.querySumByRange(3, 2)).toBe(NaN); // End index is less than start index, should return NaN
|
|
34
|
+
expect(segmentTree.querySumByRange(0, 10)).toBe(NaN); // Beyond upper bound, should return NaN
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should handle an empty input array', () => {
|
|
38
|
+
// Check behavior when dealing with an empty input array
|
|
39
|
+
const emptySegmentTree = new SegmentTree([]);
|
|
40
|
+
expect(emptySegmentTree.root).toBe(null);
|
|
41
|
+
expect(emptySegmentTree.querySumByRange(0, 2)).toBe(0); // Sum of an empty array should be 0
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should handle a single-element input array', () => {
|
|
45
|
+
// Check behavior when the input array contains a single element
|
|
46
|
+
const singleElementSegmentTree = new SegmentTree([42]);
|
|
47
|
+
expect(singleElementSegmentTree.root?.sum).toBe(42);
|
|
48
|
+
expect(singleElementSegmentTree.querySumByRange(0, 0)).toBe(42); // Range covering the only element should return that element's value
|
|
49
|
+
});
|
|
50
|
+
});
|