data-structure-typed 1.41.6 → 1.41.8

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.
Files changed (115) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +14 -11
  3. package/benchmark/report.html +14 -11
  4. package/benchmark/report.json +153 -202
  5. package/dist/cjs/src/data-structures/binary-tree/rb-tree.d.ts +5 -2
  6. package/dist/cjs/src/data-structures/binary-tree/rb-tree.js +15 -2
  7. package/dist/cjs/src/data-structures/binary-tree/rb-tree.js.map +1 -1
  8. package/dist/cjs/src/data-structures/graph/abstract-graph.js +5 -5
  9. package/dist/cjs/src/data-structures/graph/abstract-graph.js.map +1 -1
  10. package/dist/mjs/src/data-structures/binary-tree/rb-tree.d.ts +5 -2
  11. package/dist/mjs/src/data-structures/binary-tree/rb-tree.js +15 -2
  12. package/dist/mjs/src/data-structures/graph/abstract-graph.js +5 -5
  13. package/dist/umd/data-structure-typed.min.js +1 -1
  14. package/dist/umd/data-structure-typed.min.js.map +1 -1
  15. package/package.json +5 -5
  16. package/src/data-structures/binary-tree/binary-tree.ts +1 -1
  17. package/src/data-structures/binary-tree/bst.ts +1 -1
  18. package/src/data-structures/binary-tree/rb-tree.ts +18 -2
  19. package/src/data-structures/graph/abstract-graph.ts +6 -6
  20. package/test/config.ts +1 -0
  21. package/test/integration/avl-tree.test.ts +110 -0
  22. package/test/integration/bst.test.ts +385 -0
  23. package/test/integration/heap.test.js +16 -0
  24. package/test/integration/index.html +51 -0
  25. package/test/performance/data-structures/binary-tree/avl-tree.test.ts +36 -0
  26. package/test/performance/data-structures/binary-tree/binary-index-tree.test.ts +0 -0
  27. package/test/performance/data-structures/binary-tree/binary-tree.test.ts +45 -0
  28. package/test/performance/data-structures/binary-tree/bst.test.ts +36 -0
  29. package/test/performance/data-structures/binary-tree/overall.test.ts +0 -0
  30. package/test/performance/data-structures/binary-tree/rb-tree.test.ts +32 -0
  31. package/test/performance/data-structures/binary-tree/segment-tree.test.ts +0 -0
  32. package/test/performance/data-structures/binary-tree/tree-multiset.test.ts +0 -0
  33. package/test/performance/data-structures/graph/abstract-graph.test.ts +0 -0
  34. package/test/performance/data-structures/graph/directed-graph.test.ts +49 -0
  35. package/test/performance/data-structures/graph/map-graph.test.ts +0 -0
  36. package/test/performance/data-structures/graph/overall.test.ts +0 -0
  37. package/test/performance/data-structures/graph/undirected-graph.test.ts +0 -0
  38. package/test/performance/data-structures/hash/coordinate-map.test.ts +0 -0
  39. package/test/performance/data-structures/hash/coordinate-set.test.ts +0 -0
  40. package/test/performance/data-structures/hash/hash-map.test.ts +0 -0
  41. package/test/performance/data-structures/hash/hash-table.test.ts +0 -0
  42. package/test/performance/data-structures/heap/heap.test.ts +30 -0
  43. package/test/performance/data-structures/heap/max-heap.test.ts +0 -0
  44. package/test/performance/data-structures/heap/min-heap.test.ts +0 -0
  45. package/test/performance/data-structures/linked-list/doubly-linked-list.test.ts +40 -0
  46. package/test/performance/data-structures/linked-list/linked-list.test.ts +0 -0
  47. package/test/performance/data-structures/linked-list/singly-linked-list.test.ts +34 -0
  48. package/test/performance/data-structures/linked-list/skip-linked-list.test.ts +0 -0
  49. package/test/performance/data-structures/linked-list/skip-list.test.ts +0 -0
  50. package/test/performance/data-structures/matrix/matrix.test.ts +0 -0
  51. package/test/performance/data-structures/matrix/matrix2d.test.ts +0 -0
  52. package/test/performance/data-structures/matrix/navigator.test.ts +0 -0
  53. package/test/performance/data-structures/matrix/vector2d.test.ts +0 -0
  54. package/test/performance/data-structures/priority-queue/max-priority-queue.test.ts +19 -0
  55. package/test/performance/data-structures/priority-queue/min-priority-queue.test.ts +0 -0
  56. package/test/performance/data-structures/priority-queue/priority-queue.test.ts +0 -0
  57. package/test/performance/data-structures/queue/deque.test.ts +21 -0
  58. package/test/performance/data-structures/queue/queue.test.ts +25 -0
  59. package/test/performance/data-structures/stack/stack.test.ts +0 -0
  60. package/test/performance/data-structures/tree/tree.test.ts +0 -0
  61. package/test/performance/data-structures/trie/trie.test.ts +22 -0
  62. package/test/performance/reportor.ts +185 -0
  63. package/test/performance/types/index.ts +1 -0
  64. package/test/performance/types/reportor.ts +3 -0
  65. package/test/types/index.ts +1 -0
  66. package/test/types/utils/big-o.ts +1 -0
  67. package/test/types/utils/index.ts +2 -0
  68. package/test/types/utils/json2html.ts +1 -0
  69. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +269 -0
  70. package/test/unit/data-structures/binary-tree/binary-index-tree.test.ts +320 -0
  71. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +486 -0
  72. package/test/unit/data-structures/binary-tree/bst.test.ts +840 -0
  73. package/test/unit/data-structures/binary-tree/overall.test.ts +66 -0
  74. package/test/unit/data-structures/binary-tree/rb-tree.test.ts +435 -0
  75. package/test/unit/data-structures/binary-tree/segment-tree.test.ts +50 -0
  76. package/test/unit/data-structures/binary-tree/tree-multiset.test.ts +542 -0
  77. package/test/unit/data-structures/graph/abstract-graph.test.ts +100 -0
  78. package/test/unit/data-structures/graph/directed-graph.test.ts +564 -0
  79. package/test/unit/data-structures/graph/map-graph.test.ts +126 -0
  80. package/test/unit/data-structures/graph/overall.test.ts +49 -0
  81. package/test/unit/data-structures/graph/salty-edges.json +1 -0
  82. package/test/unit/data-structures/graph/salty-vertexes.json +1 -0
  83. package/test/unit/data-structures/graph/undirected-graph.test.ts +167 -0
  84. package/test/unit/data-structures/hash/coordinate-map.test.ts +74 -0
  85. package/test/unit/data-structures/hash/coordinate-set.test.ts +66 -0
  86. package/test/unit/data-structures/hash/hash-map.test.ts +103 -0
  87. package/test/unit/data-structures/hash/hash-table.test.ts +186 -0
  88. package/test/unit/data-structures/heap/heap.test.ts +254 -0
  89. package/test/unit/data-structures/heap/max-heap.test.ts +52 -0
  90. package/test/unit/data-structures/heap/min-heap.test.ts +52 -0
  91. package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +400 -0
  92. package/test/unit/data-structures/linked-list/linked-list.test.ts +8 -0
  93. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +474 -0
  94. package/test/unit/data-structures/linked-list/skip-linked-list.test.ts +13 -0
  95. package/test/unit/data-structures/linked-list/skip-list.test.ts +86 -0
  96. package/test/unit/data-structures/matrix/matrix.test.ts +54 -0
  97. package/test/unit/data-structures/matrix/matrix2d.test.ts +345 -0
  98. package/test/unit/data-structures/matrix/navigator.test.ts +244 -0
  99. package/test/unit/data-structures/matrix/vector2d.test.ts +171 -0
  100. package/test/unit/data-structures/priority-queue/max-priority-queue.test.ts +73 -0
  101. package/test/unit/data-structures/priority-queue/min-priority-queue.test.ts +63 -0
  102. package/test/unit/data-structures/priority-queue/priority-queue.test.ts +53 -0
  103. package/test/unit/data-structures/queue/deque.test.ts +410 -0
  104. package/test/unit/data-structures/queue/queue.test.ts +207 -0
  105. package/test/unit/data-structures/stack/stack.test.ts +67 -0
  106. package/test/unit/data-structures/tree/tree.test.ts +39 -0
  107. package/test/unit/data-structures/trie/trie.test.ts +825 -0
  108. package/test/utils/array.ts +5514 -0
  109. package/test/utils/big-o.ts +207 -0
  110. package/test/utils/console.ts +31 -0
  111. package/test/utils/index.ts +7 -0
  112. package/test/utils/is.ts +56 -0
  113. package/test/utils/json2html.ts +322 -0
  114. package/test/utils/number.ts +13 -0
  115. package/test/utils/string.ts +1 -0
@@ -0,0 +1,185 @@
1
+ import * as Benchmark from 'benchmark';
2
+ import * as path from 'path';
3
+ import * as fs from 'fs';
4
+ import * as fastGlob from 'fast-glob';
5
+ import {Color, numberFix, render} from '../utils';
6
+ import {PerformanceTest} from './types';
7
+
8
+ const reportDistPath = 'benchmark';
9
+ const testDir = path.join(__dirname, 'data-structures');
10
+ const testFiles = fastGlob.sync(path.join(testDir, '**', '*.test.ts'));
11
+
12
+ const report: {[key: string]: any} = {};
13
+
14
+ let completedCount = 0;
15
+
16
+ const performanceTests: PerformanceTest[] = [];
17
+ const {GREEN, BOLD, END, YELLOW, GRAY, CYAN, BG_YELLOW} = Color;
18
+
19
+ testFiles.forEach((file: string) => {
20
+ const testName = path.basename(file, '.test.ts');
21
+ const testFunction = require(file);
22
+ const {suite} = testFunction;
23
+ if (suite) performanceTests.push({testName, suite, file});
24
+ });
25
+
26
+ const composeReport = () => {
27
+ if (!fs.existsSync(reportDistPath)) fs.mkdirSync(reportDistPath, {recursive: true});
28
+
29
+ const filePath = path.join(reportDistPath, 'report.json');
30
+ const htmlFilePath = path.join(reportDistPath, 'report.html');
31
+ fs.writeFileSync(filePath, JSON.stringify(report, null, 2));
32
+ let html = `<!DOCTYPE html>
33
+ <html lang="en">
34
+ <head>
35
+ <meta charset="UTF-8">
36
+ <title>performance of data-structure-typed</title>
37
+ <style>
38
+ *{
39
+ box-sizing: border-box;
40
+ }
41
+ #json-to-html {
42
+ padding: 0 10px 20px;
43
+ }
44
+
45
+ .json-to-html-label {
46
+ font-size: 2rem;
47
+ margin: 2rem 0 0 3px;
48
+ }
49
+ .content table {
50
+ width: 100%;
51
+ table-layout: fixed;
52
+ border-collapse: collapse;
53
+ margin-top: 10px;
54
+ font-size: 16px;
55
+ }
56
+
57
+ .content table th,
58
+ .content table td {
59
+ padding: 8px 12px;
60
+ text-align: left;
61
+ border: 1px solid #ddd;
62
+ }
63
+
64
+ .content table th {
65
+ background-color: #f2f2f2;
66
+ font-weight: bold;
67
+ }
68
+
69
+ .content table tr:nth-child(odd) {
70
+ background-color: #ffffff;
71
+ }
72
+ </style>
73
+ </head>
74
+ <body>
75
+ <div id="json-to-html">`;
76
+ let htmlTables = '';
77
+ for (const r in report) {
78
+ if (report.hasOwnProperty(r)) {
79
+ htmlTables += render(report[r].testName, report[r].benchmarks, {
80
+ plainHtml: true,
81
+ '<>': 'table',
82
+ html: [
83
+ {
84
+ '<>': 'tr',
85
+ html: [
86
+ {'<>': 'td', html: '${name}'},
87
+ {'<>': 'td', html: '${periodMS}'},
88
+ {'<>': 'td', html: '${mean}'}
89
+ ]
90
+ }
91
+ ]
92
+ });
93
+ }
94
+ }
95
+ htmlTables += `
96
+
97
+ `;
98
+ html += htmlTables;
99
+ html += `</div>
100
+ </body>
101
+ </html>`;
102
+ replaceMarkdownContent(
103
+ '[//]: # (Start of Replace Section)', // Start tag
104
+ '[//]: # (End of Replace Section)', // end identifier
105
+ htmlTables // New content to be inserted
106
+ );
107
+ fs.writeFileSync(htmlFilePath, html);
108
+ console.log(`Performance ${BOLD}${GREEN}report${END} file generated`);
109
+ };
110
+ function replaceMarkdownContent(startMarker: string, endMarker: string, newText: string) {
111
+ const parentDirectory = path.resolve(__dirname, '../..'); // The path to the parent directory
112
+ const filePath = path.join(parentDirectory, 'README.md'); // Path to README.md file
113
+ fs.readFile(filePath, 'utf8', (err, data) => {
114
+ if (err) {
115
+ console.error(`Unable to read ${filePath}:`, err);
116
+ return;
117
+ }
118
+
119
+ // Find the start and end markers in the content
120
+ const startIndex = data.indexOf(startMarker);
121
+ const endIndex = data.indexOf(endMarker, startIndex + 1);
122
+
123
+ if (startIndex === -1 || endIndex === -1) {
124
+ console.error('Unable to find start or end marker');
125
+ return;
126
+ }
127
+
128
+ // Replace the old content with the new text
129
+ const updatedMarkdown = data.slice(0, startIndex + startMarker.length) + '\n' + newText + data.slice(endIndex);
130
+
131
+ // Try writing the modified content back to the file
132
+ fs.writeFile(filePath, updatedMarkdown, 'utf8', err => {
133
+ if (err) {
134
+ console.error(`Unable to write to ${filePath}:`, err);
135
+ } else {
136
+ console.log(`The content has been successfully replaced in ${filePath}!`);
137
+ }
138
+ });
139
+ });
140
+ }
141
+
142
+ performanceTests.forEach(item => {
143
+ const {suite, testName, file} = item;
144
+ const relativeFilePath = path.relative(__dirname, file);
145
+ const directory = path.dirname(relativeFilePath);
146
+ const fileName = path.basename(relativeFilePath);
147
+ console.log(`${BG_YELLOW} Running ${END} ${GRAY}${directory}/${END}${CYAN}${fileName}${END}`);
148
+
149
+ if (suite) {
150
+ let runTime = 0;
151
+ suite
152
+ .on('complete', function (this: Benchmark.Suite) {
153
+ completedCount++;
154
+ report[testName] = {};
155
+ report[testName].benchmarks = this.map((benchmark: Benchmark) => {
156
+ runTime += benchmark.times.elapsed;
157
+ return {
158
+ 'test name': benchmark.name,
159
+ 'time taken (ms)': numberFix(benchmark.times.period * 1000, 2),
160
+ 'executions per sec': numberFix(benchmark.hz, 2),
161
+ // 'executed times': numberFix(benchmark.count, 0),
162
+ // 'sample mean (secs)': numberFix(benchmark.stats.mean, 2),
163
+ 'sample deviation': numberFix(benchmark.stats.deviation, 2)
164
+ };
165
+ });
166
+
167
+ report[testName].testName = testName;
168
+ const isDone = completedCount === performanceTests.length;
169
+ runTime = Number(runTime.toFixed(2));
170
+ const isTimeWarn = runTime > 120;
171
+ console.log(
172
+ // `Files: ${GREEN}${testFileCount}${END} `,
173
+ // `Suites: ${GREEN}${performanceTests.length}${END} `,
174
+ `Suites Progress: ${isDone ? GREEN : YELLOW}${completedCount}${END}/${isDone ? GREEN : YELLOW}${
175
+ performanceTests.length
176
+ }${END}`,
177
+ `Time: ${isTimeWarn ? YELLOW : GREEN}${runTime}s${END}`
178
+ );
179
+ if (isDone) {
180
+ composeReport();
181
+ }
182
+ })
183
+ .run({async: false});
184
+ }
185
+ });
@@ -0,0 +1 @@
1
+ export * from './reportor';
@@ -0,0 +1,3 @@
1
+ import * as Benchmark from 'benchmark';
2
+
3
+ export type PerformanceTest = {testName: string; suite: Benchmark.Suite; file: string};
@@ -0,0 +1 @@
1
+ export * from './utils';
@@ -0,0 +1 @@
1
+ export type AnyFunction = (...args: any[]) => any;
@@ -0,0 +1,2 @@
1
+ export * from './big-o';
2
+ export * from './json2html';
@@ -0,0 +1 @@
1
+ export type Json2htmlOptions = {plainHtml?: boolean} & Partial<{[key: string]: any}>;
@@ -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
+ });