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,269 @@
|
|
|
1
|
+
import {AVLTree, AVLTreeNode, CP, IterationType} from '../../../../src';
|
|
2
|
+
|
|
3
|
+
describe('AVL Tree Test', () => {
|
|
4
|
+
it('should perform various operations on a AVL Tree', () => {
|
|
5
|
+
const arr = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
|
|
6
|
+
const tree = new AVLTree<number>();
|
|
7
|
+
|
|
8
|
+
for (const i of arr) tree.add(i, i);
|
|
9
|
+
|
|
10
|
+
const node6 = tree.getNode(6);
|
|
11
|
+
|
|
12
|
+
expect(node6 && tree.getHeight(node6)).toBe(3);
|
|
13
|
+
expect(node6 && tree.getDepth(node6)).toBe(1);
|
|
14
|
+
|
|
15
|
+
const getNodeById = tree.getNode(10);
|
|
16
|
+
expect(getNodeById?.key).toBe(10);
|
|
17
|
+
|
|
18
|
+
const getMinNodeByRoot = tree.getLeftMost();
|
|
19
|
+
expect(getMinNodeByRoot?.key).toBe(1);
|
|
20
|
+
|
|
21
|
+
const node15 = tree.getNode(15);
|
|
22
|
+
const getMinNodeBySpecificNode = node15 && tree.getLeftMost(node15);
|
|
23
|
+
expect(getMinNodeBySpecificNode?.key).toBe(12);
|
|
24
|
+
|
|
25
|
+
let subTreeSum = 0;
|
|
26
|
+
node15 && tree.subTreeTraverse(node => (subTreeSum += node.key), node15);
|
|
27
|
+
expect(subTreeSum).toBe(70);
|
|
28
|
+
|
|
29
|
+
let lesserSum = 0;
|
|
30
|
+
tree.lesserOrGreaterTraverse(node => (lesserSum += node.key), CP.lt, 10);
|
|
31
|
+
expect(lesserSum).toBe(45);
|
|
32
|
+
|
|
33
|
+
// node15 has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class.
|
|
34
|
+
expect(node15?.value).toBe(15);
|
|
35
|
+
|
|
36
|
+
const dfs = tree.dfs(node => node, 'in');
|
|
37
|
+
expect(dfs[0].key).toBe(1);
|
|
38
|
+
expect(dfs[dfs.length - 1].key).toBe(16);
|
|
39
|
+
|
|
40
|
+
tree.perfectlyBalance();
|
|
41
|
+
const bfs = tree.bfs(node => node);
|
|
42
|
+
expect(tree.isPerfectlyBalanced()).toBe(true);
|
|
43
|
+
expect(bfs[0].key).toBe(8);
|
|
44
|
+
expect(bfs[bfs.length - 1].key).toBe(16);
|
|
45
|
+
|
|
46
|
+
expect(tree.delete(11)[0].deleted?.key).toBe(11);
|
|
47
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
48
|
+
expect(node15 && tree.getHeight(node15)).toBe(2);
|
|
49
|
+
|
|
50
|
+
expect(tree.delete(1)[0].deleted?.key).toBe(1);
|
|
51
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
52
|
+
expect(tree.getHeight()).toBe(4);
|
|
53
|
+
|
|
54
|
+
expect(tree.delete(4)[0].deleted?.key).toBe(4);
|
|
55
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
56
|
+
expect(tree.getHeight()).toBe(4);
|
|
57
|
+
|
|
58
|
+
expect(tree.delete(10)[0].deleted?.key).toBe(10);
|
|
59
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
60
|
+
expect(tree.getHeight()).toBe(3);
|
|
61
|
+
|
|
62
|
+
expect(tree.delete(15)[0].deleted?.key).toBe(15);
|
|
63
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
64
|
+
|
|
65
|
+
expect(tree.getHeight()).toBe(3);
|
|
66
|
+
|
|
67
|
+
expect(tree.delete(5)[0].deleted?.key).toBe(5);
|
|
68
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
69
|
+
expect(tree.getHeight()).toBe(3);
|
|
70
|
+
|
|
71
|
+
expect(tree.delete(13)[0].deleted?.key).toBe(13);
|
|
72
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
73
|
+
expect(tree.getHeight()).toBe(3);
|
|
74
|
+
|
|
75
|
+
expect(tree.delete(3)[0].deleted?.key).toBe(3);
|
|
76
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
77
|
+
expect(tree.getHeight()).toBe(3);
|
|
78
|
+
|
|
79
|
+
expect(tree.delete(8)[0].deleted?.key).toBe(8);
|
|
80
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
81
|
+
expect(tree.getHeight()).toBe(3);
|
|
82
|
+
|
|
83
|
+
expect(tree.delete(6)[0].deleted?.key).toBe(6);
|
|
84
|
+
expect(tree.delete(6).length).toBe(0);
|
|
85
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
86
|
+
expect(tree.getHeight()).toBe(2);
|
|
87
|
+
|
|
88
|
+
expect(tree.delete(7)[0].deleted?.key).toBe(7);
|
|
89
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
90
|
+
expect(tree.getHeight()).toBe(2);
|
|
91
|
+
|
|
92
|
+
expect(tree.delete(9)[0].deleted?.key).toBe(9);
|
|
93
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
94
|
+
expect(tree.getHeight()).toBe(2);
|
|
95
|
+
expect(tree.delete(14)[0].deleted?.key).toBe(14);
|
|
96
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
97
|
+
expect(tree.getHeight()).toBe(1);
|
|
98
|
+
|
|
99
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
100
|
+
const lastBFSIds = tree.bfs();
|
|
101
|
+
expect(lastBFSIds[0]).toBe(12);
|
|
102
|
+
expect(lastBFSIds[1]).toBe(2);
|
|
103
|
+
expect(lastBFSIds[2]).toBe(16);
|
|
104
|
+
|
|
105
|
+
const lastBFSNodes = tree.bfs(node => node);
|
|
106
|
+
expect(lastBFSNodes[0].key).toBe(12);
|
|
107
|
+
expect(lastBFSNodes[1].key).toBe(2);
|
|
108
|
+
expect(lastBFSNodes[2].key).toBe(16);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('AVL Tree Test recursively', () => {
|
|
113
|
+
it('should perform various operations on a AVL Tree', () => {
|
|
114
|
+
const arr = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
|
|
115
|
+
const tree = new AVLTree<number>({iterationType: IterationType.RECURSIVE});
|
|
116
|
+
|
|
117
|
+
for (const i of arr) tree.add(i, i);
|
|
118
|
+
|
|
119
|
+
const node6 = tree.getNode(6);
|
|
120
|
+
|
|
121
|
+
expect(node6 && tree.getHeight(node6)).toBe(3);
|
|
122
|
+
expect(node6 && tree.getDepth(node6)).toBe(1);
|
|
123
|
+
|
|
124
|
+
const getNodeById = tree.getNode(10);
|
|
125
|
+
expect(getNodeById?.key).toBe(10);
|
|
126
|
+
|
|
127
|
+
const getMinNodeByRoot = tree.getLeftMost();
|
|
128
|
+
expect(getMinNodeByRoot?.key).toBe(1);
|
|
129
|
+
|
|
130
|
+
const node15 = tree.getNode(15);
|
|
131
|
+
const getMinNodeBySpecificNode = node15 && tree.getLeftMost(node15);
|
|
132
|
+
expect(getMinNodeBySpecificNode?.key).toBe(12);
|
|
133
|
+
|
|
134
|
+
let subTreeSum = 0;
|
|
135
|
+
node15 && tree.subTreeTraverse(node => (subTreeSum += node.key), node15);
|
|
136
|
+
expect(subTreeSum).toBe(70);
|
|
137
|
+
|
|
138
|
+
let lesserSum = 0;
|
|
139
|
+
tree.lesserOrGreaterTraverse(node => (lesserSum += node.key), CP.lt, 10);
|
|
140
|
+
expect(lesserSum).toBe(45);
|
|
141
|
+
|
|
142
|
+
// node15 has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class.
|
|
143
|
+
expect(node15?.value).toBe(15);
|
|
144
|
+
|
|
145
|
+
const dfs = tree.dfs(node => node, 'in');
|
|
146
|
+
expect(dfs[0].key).toBe(1);
|
|
147
|
+
expect(dfs[dfs.length - 1].key).toBe(16);
|
|
148
|
+
|
|
149
|
+
tree.perfectlyBalance();
|
|
150
|
+
const bfs = tree.bfs(node => node);
|
|
151
|
+
expect(tree.isPerfectlyBalanced()).toBe(true);
|
|
152
|
+
expect(bfs[0].key).toBe(8);
|
|
153
|
+
expect(bfs[bfs.length - 1].key).toBe(16);
|
|
154
|
+
|
|
155
|
+
expect(tree.delete(11)[0].deleted?.key).toBe(11);
|
|
156
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
157
|
+
expect(node15 && tree.getHeight(node15)).toBe(2);
|
|
158
|
+
|
|
159
|
+
expect(tree.delete(1)[0].deleted?.key).toBe(1);
|
|
160
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
161
|
+
expect(tree.getHeight()).toBe(4);
|
|
162
|
+
|
|
163
|
+
expect(tree.delete(4)[0].deleted?.key).toBe(4);
|
|
164
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
165
|
+
expect(tree.getHeight()).toBe(4);
|
|
166
|
+
|
|
167
|
+
expect(tree.delete(10)[0].deleted?.key).toBe(10);
|
|
168
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
169
|
+
expect(tree.getHeight()).toBe(3);
|
|
170
|
+
|
|
171
|
+
expect(tree.delete(15)[0].deleted?.key).toBe(15);
|
|
172
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
173
|
+
|
|
174
|
+
expect(tree.getHeight()).toBe(3);
|
|
175
|
+
|
|
176
|
+
expect(tree.delete(5)[0].deleted?.key).toBe(5);
|
|
177
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
178
|
+
expect(tree.getHeight()).toBe(3);
|
|
179
|
+
|
|
180
|
+
expect(tree.delete(13)[0].deleted?.key).toBe(13);
|
|
181
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
182
|
+
expect(tree.getHeight()).toBe(3);
|
|
183
|
+
|
|
184
|
+
expect(tree.delete(3)[0].deleted?.key).toBe(3);
|
|
185
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
186
|
+
expect(tree.getHeight()).toBe(3);
|
|
187
|
+
|
|
188
|
+
expect(tree.delete(8)[0].deleted?.key).toBe(8);
|
|
189
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
190
|
+
expect(tree.getHeight()).toBe(3);
|
|
191
|
+
|
|
192
|
+
expect(tree.delete(6)[0].deleted?.key).toBe(6);
|
|
193
|
+
expect(tree.delete(6).length).toBe(0);
|
|
194
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
195
|
+
expect(tree.getHeight()).toBe(2);
|
|
196
|
+
|
|
197
|
+
expect(tree.delete(7)[0].deleted?.key).toBe(7);
|
|
198
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
199
|
+
expect(tree.getHeight()).toBe(2);
|
|
200
|
+
|
|
201
|
+
expect(tree.delete(9)[0].deleted?.key).toBe(9);
|
|
202
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
203
|
+
expect(tree.getHeight()).toBe(2);
|
|
204
|
+
expect(tree.delete(14)[0].deleted?.key).toBe(14);
|
|
205
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
206
|
+
expect(tree.getHeight()).toBe(1);
|
|
207
|
+
|
|
208
|
+
expect(tree.isAVLBalanced()).toBe(true);
|
|
209
|
+
const lastBFSIds = tree.bfs();
|
|
210
|
+
expect(lastBFSIds[0]).toBe(12);
|
|
211
|
+
expect(lastBFSIds[1]).toBe(2);
|
|
212
|
+
expect(lastBFSIds[2]).toBe(16);
|
|
213
|
+
|
|
214
|
+
const lastBFSNodes = tree.bfs(node => node);
|
|
215
|
+
expect(lastBFSNodes[0].key).toBe(12);
|
|
216
|
+
expect(lastBFSNodes[1].key).toBe(2);
|
|
217
|
+
expect(lastBFSNodes[2].key).toBe(16);
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
describe('AVLTree APIs test', () => {
|
|
222
|
+
const avl = new AVLTree<{id: number; text: string}>();
|
|
223
|
+
beforeEach(() => {
|
|
224
|
+
avl.clear();
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it('add', () => {
|
|
228
|
+
avl.add(1);
|
|
229
|
+
const node2 = new AVLTreeNode(2);
|
|
230
|
+
avl.add(node2);
|
|
231
|
+
const node3 = new AVLTreeNode(3, {id: 3, text: 'text3'});
|
|
232
|
+
avl.add(node3);
|
|
233
|
+
avl.add(node3, {id: 3, text: 'text33'});
|
|
234
|
+
|
|
235
|
+
const bfsRes = avl.bfs(node => node.key);
|
|
236
|
+
expect(bfsRes[0]).toBe(2);
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
describe('AVLTree', () => {
|
|
241
|
+
it('should balance the tree using _balanceLR when nodes are added', () => {
|
|
242
|
+
const avlTree = new AVLTree();
|
|
243
|
+
avlTree.add(10, 'A');
|
|
244
|
+
avlTree.add(5, 'B');
|
|
245
|
+
avlTree.add(15, 'C');
|
|
246
|
+
avlTree.add(3, 'D');
|
|
247
|
+
avlTree.add(7, 'E');
|
|
248
|
+
|
|
249
|
+
// Adding nodes to trigger _balanceLR
|
|
250
|
+
avlTree.add(12, 'F');
|
|
251
|
+
|
|
252
|
+
// You can add more specific assertions to check the tree's balance and structure.
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it('should balance the tree using _balanceLR when nodes are deleted', () => {
|
|
256
|
+
const avlTree = new AVLTree();
|
|
257
|
+
avlTree.add(10, 'A');
|
|
258
|
+
avlTree.add(5, 'B');
|
|
259
|
+
avlTree.add(15, 'C');
|
|
260
|
+
avlTree.add(3, 'D');
|
|
261
|
+
avlTree.add(7, 'E');
|
|
262
|
+
avlTree.add(12, 'F');
|
|
263
|
+
|
|
264
|
+
// Deleting nodes to trigger _balanceLR
|
|
265
|
+
avlTree.delete(3);
|
|
266
|
+
|
|
267
|
+
// You can add more specific assertions to check the tree's balance and structure.
|
|
268
|
+
});
|
|
269
|
+
});
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import {BinaryIndexedTree} from '../../../../src';
|
|
2
|
+
// import {isDebugTest} from '../../../config';
|
|
3
|
+
|
|
4
|
+
// const isDebug = isDebugTest;
|
|
5
|
+
|
|
6
|
+
describe('BinaryIndexedTree simple', () => {
|
|
7
|
+
let bit: BinaryIndexedTree;
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
//Create a new BinaryIndexedTree instance before each test case
|
|
11
|
+
bit = new BinaryIndexedTree({frequency: 0, max: 10}); // Modify the value of max as needed
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('should initialize correctly', () => {
|
|
15
|
+
expect(bit.freq).toBe(0);
|
|
16
|
+
expect(bit.max).toBe(10);
|
|
17
|
+
expect(bit.freqMap).toEqual({0: 0}); // Modify the initialized record value according to the actual situation
|
|
18
|
+
// More initialization checks can be added
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should read a single value correctly', () => {
|
|
22
|
+
// Test the function of reading a single value
|
|
23
|
+
bit.writeSingle(5, 5); //Write test data
|
|
24
|
+
expect(bit.readSingle(5)).toBe(5); // Read and verify
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should update a value correctly', () => {
|
|
28
|
+
// Test the ability to update a single value
|
|
29
|
+
bit.writeSingle(5, 5); //Write test data
|
|
30
|
+
bit.update(5, 2); // update value
|
|
31
|
+
expect(bit.readSingle(5)).toBe(7); // Verify the updated value
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should find lower bound correctly', () => {
|
|
35
|
+
//Test the function of finding the lower bound
|
|
36
|
+
bit.writeSingle(2, 10);
|
|
37
|
+
bit.writeSingle(5, 20);
|
|
38
|
+
bit.writeSingle(8, 30);
|
|
39
|
+
expect(bit.lowerBound(15)).toBe(5); // Find and verify the lower bound
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should find upper bound correctly', () => {
|
|
43
|
+
//Test the function of finding the upper bound
|
|
44
|
+
bit.writeSingle(2, 10);
|
|
45
|
+
bit.writeSingle(5, 20);
|
|
46
|
+
bit.writeSingle(8, 30);
|
|
47
|
+
expect(bit.upperBound(25)).toBe(5); // Find and verify the upper bound
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('BinaryIndexedTree', () => {
|
|
52
|
+
const frequency = 999;
|
|
53
|
+
const max = 10;
|
|
54
|
+
let bit: BinaryIndexedTree;
|
|
55
|
+
|
|
56
|
+
beforeEach(function () {
|
|
57
|
+
bit = new BinaryIndexedTree({frequency, max});
|
|
58
|
+
});
|
|
59
|
+
it('should validate the index', function () {
|
|
60
|
+
expect(() => bit.readSingle(-1)).toThrow('Index out of range');
|
|
61
|
+
expect(() => bit.readSingle(10)).toThrow('Index out of range');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should read a single frequency correctly', function () {
|
|
65
|
+
for (let i = 0; i < max; i++) {
|
|
66
|
+
expect(bit.readSingle(i)).toBe(frequency);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
it('should validate the index', function () {
|
|
70
|
+
expect(() => bit.update(-1, 100)).toThrow('Index out of range');
|
|
71
|
+
expect(() => bit.update(10, 100)).toThrow('Index out of range');
|
|
72
|
+
});
|
|
73
|
+
it('should frequency and max', function () {
|
|
74
|
+
const frequency = 200;
|
|
75
|
+
const max = 1000;
|
|
76
|
+
const bit = new BinaryIndexedTree({frequency, max});
|
|
77
|
+
|
|
78
|
+
expect(bit.freq).toBe(frequency);
|
|
79
|
+
expect(bit.max).toBe(max);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should update the frequency with the given delta', function () {
|
|
83
|
+
for (let i = 0; i < max; i++) {
|
|
84
|
+
bit.update(i, i * 2);
|
|
85
|
+
}
|
|
86
|
+
for (let i = 0; i < max; i++) {
|
|
87
|
+
expect(bit.readSingle(i)).toBe(i * 2 + frequency);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
it('should validate the index', function () {
|
|
91
|
+
expect(() => bit.writeSingle(-1, 100)).toThrow('Index out of range');
|
|
92
|
+
expect(() => bit.writeSingle(10, 100)).toThrow('Index out of range');
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should writeSingle to be correctly invoked', function () {
|
|
96
|
+
for (let i = 0; i < max; i++) {
|
|
97
|
+
bit.writeSingle(i, i * 2);
|
|
98
|
+
}
|
|
99
|
+
for (let i = 0; i < max; i++) {
|
|
100
|
+
expect(bit.readSingle(i)).toBe(i * 2);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('should read the frequency', function () {
|
|
105
|
+
for (let c = 0; c <= max; c++) {
|
|
106
|
+
expect(bit.read(c)).toBe(c * frequency);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const values = [-5, 0, 5, 10, 95, 100, 1000];
|
|
111
|
+
it('should find the upper-bound index', function () {
|
|
112
|
+
loopUpperBoundTests(bit, values);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should find the lower-bound index', function () {
|
|
116
|
+
loopLowerBoundTests(bit, values);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
describe('designated values', function () {
|
|
121
|
+
const array = [1, 8, 6, 10, 7, 9, 0, 2, 6, 3];
|
|
122
|
+
const sumArray = (sum => array.map(value => (sum += value)))(0);
|
|
123
|
+
let bit: BinaryIndexedTree;
|
|
124
|
+
|
|
125
|
+
beforeEach(function () {
|
|
126
|
+
bit = new BinaryIndexedTree({max: array.length});
|
|
127
|
+
array.forEach((value, i) => bit.writeSingle(i, value));
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
describe('readSingle', function () {
|
|
131
|
+
it('should read a single frequency correctly', function () {
|
|
132
|
+
array.forEach((value, i) => {
|
|
133
|
+
expect(bit.readSingle(i)).toBe(array[i]);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
describe('update', function () {
|
|
139
|
+
it('should update the frequency with the given delta', function () {
|
|
140
|
+
array.forEach((value, i) => bit.update(i, value + i));
|
|
141
|
+
array.forEach((value, i) => {
|
|
142
|
+
expect(bit.readSingle(i)).toBe(array[i] * 2 + i);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe('writeSingle', function () {
|
|
148
|
+
it('should write a single frequency correctly', function () {
|
|
149
|
+
array.forEach((value, i) => bit.writeSingle(i, value + i));
|
|
150
|
+
array.forEach((value, i) => {
|
|
151
|
+
expect(bit.readSingle(i)).toBe(array[i] + i);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
describe('read', function () {
|
|
157
|
+
it('should read the cumulative frequency correctly', function () {
|
|
158
|
+
expect(bit.read(0)).toBe(0);
|
|
159
|
+
sumArray.forEach((sum, i) => {
|
|
160
|
+
expect(bit.read(i + 1)).toBe(sum);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const values = [-5, 0, 15, 25, 43, 53, 100];
|
|
166
|
+
|
|
167
|
+
describe('upperBound', function () {
|
|
168
|
+
it('should find the upper-bound index', function () {
|
|
169
|
+
loopUpperBoundTests(bit, values);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
describe('lowerBound', function () {
|
|
174
|
+
it('should find the lower-bound index', function () {
|
|
175
|
+
loopLowerBoundTests(bit, values);
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
describe('descending sequence', function () {
|
|
181
|
+
const array = [1, 8, -6, 10, 7, 9, 0, -2, 6, 3];
|
|
182
|
+
let bit: BinaryIndexedTree;
|
|
183
|
+
|
|
184
|
+
beforeEach(function () {
|
|
185
|
+
bit = new BinaryIndexedTree({max: array.length});
|
|
186
|
+
array.forEach((value, i) => bit.writeSingle(i, value));
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('should have a correct negativeCount property', function () {
|
|
190
|
+
expect(bit.negativeCount).toBe(2);
|
|
191
|
+
bit.update(2, 6);
|
|
192
|
+
expect(bit.negativeCount).toBe(1);
|
|
193
|
+
bit.update(7, 3);
|
|
194
|
+
expect(bit.negativeCount).toBe(0);
|
|
195
|
+
bit.update(8, -7);
|
|
196
|
+
expect(bit.negativeCount).toBe(1);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const values = [-5, 0, 15, 25, 43, 53, 100];
|
|
200
|
+
|
|
201
|
+
describe('upperBound', function () {
|
|
202
|
+
it('should validate the non-descending', function () {
|
|
203
|
+
expect(() => bit.upperBound(20)).toThrow('Must not be descending');
|
|
204
|
+
bit.update(2, 12);
|
|
205
|
+
bit.update(7, 4);
|
|
206
|
+
loopUpperBoundTests(bit, values);
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
describe('BinaryIndexedTree lowerBound', function () {
|
|
211
|
+
it('should validate the non-descending', function () {
|
|
212
|
+
expect(() => bit.lowerBound(20)).toThrow('Sequence is not non-descending');
|
|
213
|
+
bit.update(2, 12);
|
|
214
|
+
bit.update(7, 4);
|
|
215
|
+
loopLowerBoundTests(bit, values);
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
describe('BinaryIndexedTree additional tests', () => {
|
|
221
|
+
it('should handle read method correctly', () => {
|
|
222
|
+
const bit = new BinaryIndexedTree({max: 10});
|
|
223
|
+
bit.writeSingle(2, 10);
|
|
224
|
+
bit.writeSingle(5, 20);
|
|
225
|
+
bit.writeSingle(8, 30);
|
|
226
|
+
expect(bit.read(5)).toBe(10); // Ensure read method accumulates correctly
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it('should handle consecutive operations', () => {
|
|
230
|
+
const bit = new BinaryIndexedTree({max: 10});
|
|
231
|
+
bit.writeSingle(2, 10);
|
|
232
|
+
bit.update(2, 5);
|
|
233
|
+
expect(bit.readSingle(2)).toBe(15);
|
|
234
|
+
bit.writeSingle(5, 20);
|
|
235
|
+
expect(bit.readSingle(5)).toBe(20);
|
|
236
|
+
expect(bit.lowerBound(15)).toBe(2);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it('should handle frequent increment updates', () => {
|
|
240
|
+
const bit = new BinaryIndexedTree({max: 10});
|
|
241
|
+
for (let i = 0; i < 10; i++) {
|
|
242
|
+
bit.update(2, 5);
|
|
243
|
+
}
|
|
244
|
+
expect(bit.readSingle(2)).toBe(50);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('should handle edge cases', () => {
|
|
248
|
+
const bit = new BinaryIndexedTree({max: 10});
|
|
249
|
+
bit.writeSingle(9, 100);
|
|
250
|
+
expect(bit.readSingle(9)).toBe(100);
|
|
251
|
+
expect(bit.lowerBound(200)).toBe(10);
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
function loopUpperBoundTests(bit: BinaryIndexedTree, values: number[]) {
|
|
256
|
+
for (const value of values) {
|
|
257
|
+
const index = bit.upperBound(value);
|
|
258
|
+
if (index > 0) {
|
|
259
|
+
expect(bit.read(index)).toBeLessThanOrEqual(value);
|
|
260
|
+
} else {
|
|
261
|
+
expect(index).toBe(0);
|
|
262
|
+
}
|
|
263
|
+
if (index < bit.max) {
|
|
264
|
+
expect(bit.read(index + 1)).toBeGreaterThan(value);
|
|
265
|
+
} else {
|
|
266
|
+
expect(index).toBe(bit.max);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function loopLowerBoundTests(bit: BinaryIndexedTree, values: number[]) {
|
|
272
|
+
for (const value of values) {
|
|
273
|
+
const index = bit.lowerBound(value);
|
|
274
|
+
if (index > 0) {
|
|
275
|
+
expect(bit.read(index)).toBeLessThan(value);
|
|
276
|
+
} else {
|
|
277
|
+
expect(index).toBe(0);
|
|
278
|
+
}
|
|
279
|
+
if (index < bit.max) {
|
|
280
|
+
expect(bit.read(index + 1)).toBeGreaterThanOrEqual(value);
|
|
281
|
+
} else {
|
|
282
|
+
expect(index).toBe(bit.max);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
describe('', () => {
|
|
288
|
+
class NumArrayDC {
|
|
289
|
+
protected _tree: BinaryIndexedTree;
|
|
290
|
+
protected readonly _nums: number[];
|
|
291
|
+
|
|
292
|
+
constructor(nums: number[]) {
|
|
293
|
+
this._nums = nums;
|
|
294
|
+
this._tree = new BinaryIndexedTree({max: nums.length + 1});
|
|
295
|
+
for (let i = 0; i < nums.length; i++) {
|
|
296
|
+
this._tree.update(i + 1, nums[i]);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
update(index: number, value: number): void {
|
|
301
|
+
this._tree.update(index + 1, value - this._nums[index]);
|
|
302
|
+
this._nums[index] = value;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
sumRange(left: number, right: number): number {
|
|
306
|
+
return this._tree.getPrefixSum(right + 1) - this._tree.getPrefixSum(left);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
it('', () => {
|
|
311
|
+
const numArray = new NumArrayDC([1, 3, 5, 8, 2, 9, 4, 5, 8, 1, 3, 2]);
|
|
312
|
+
expect(numArray.sumRange(0, 8)).toBe(45);
|
|
313
|
+
expect(numArray.sumRange(0, 2)).toBe(9);
|
|
314
|
+
numArray.update(1, 2);
|
|
315
|
+
expect(numArray.sumRange(0, 2)).toBe(8);
|
|
316
|
+
expect(numArray.sumRange(3, 4)).toBe(10);
|
|
317
|
+
numArray.update(3, 2);
|
|
318
|
+
expect(numArray.sumRange(3, 4)).toBe(4);
|
|
319
|
+
});
|
|
320
|
+
});
|