@@ -81,7 +81,7 @@ void test_tree_traversal_with_subtrees() {
81
81
82
82
// build trees
83
83
auto child1 = main_tree.add_child (main_tree.get_root (), 2 );
84
- main_tree.add_child (main_tree.get_root (), 3 ); // child2
84
+ main_tree.add_child (main_tree.get_root (), 3 ); // No need to store child2
85
85
86
86
sub_tree.add_child (sub_tree.get_root (), 11 );
87
87
sub_tree.add_child (sub_tree.get_root (), 12 );
@@ -92,27 +92,187 @@ void test_tree_traversal_with_subtrees() {
92
92
// test traversal with subtree following
93
93
int count = 0 ;
94
94
std::vector<int > visited_values;
95
- std::cout << " Starting traversal...\n " ;
96
95
97
96
auto range = main_tree.pre_order (main_tree.get_root (), true );
98
97
for (auto it = range.begin (); it != range.end (); ++it) {
99
- int value = it.get_data ();
100
- visited_values.push_back (value);
101
- std::cout << " Visiting node with value: " << value << std::endl;
98
+ visited_values.push_back (it.get_data ());
102
99
count++;
103
- if (count > 10 ) { // Safety check
104
- std::cout << " Possible infinite loop detected\n " ;
105
- break ;
106
- }
107
100
}
108
101
109
102
// should visit: 1, 2, 10, 11, 12, 3
110
103
I (count == 6 , " Pre-order traversal with subtrees should visit 6 nodes" );
111
- I (visited_values == std::vector<int >{1 , 2 , 10 , 11 , 12 , 3 },
104
+
105
+ std::vector<int > expected = {1 , 2 , 10 , 11 , 12 , 3 };
106
+ I (visited_values == expected,
112
107
" Pre-order traversal with subtrees should visit nodes in the correct order" );
113
108
}
114
109
110
+ void test_complex_forest_operations () {
111
+ hhds::Forest<int > forest;
112
+
113
+ // create multiple trees
114
+ auto main_tree_ref = forest.create_tree (1 );
115
+ auto sub_tree1_ref = forest.create_tree (1000 );
116
+ auto sub_tree2_ref = forest.create_tree (2000 );
117
+ auto sub_tree3_ref = forest.create_tree (3000 );
118
+
119
+ auto & main_tree = forest.get_tree (main_tree_ref);
120
+ auto & sub_tree1 = forest.get_tree (sub_tree1_ref);
121
+ auto & sub_tree2 = forest.get_tree (sub_tree2_ref);
122
+ auto & sub_tree3 = forest.get_tree (sub_tree3_ref);
123
+
124
+ // build tree structures
125
+ std::vector<hhds::Tree_pos> main_nodes;
126
+ std::vector<hhds::Tree_pos> sub1_nodes;
127
+ std::vector<hhds::Tree_pos> sub2_nodes;
128
+ std::vector<hhds::Tree_pos> sub3_nodes;
129
+
130
+ // create a deep main tree with multiple branches
131
+ main_nodes.push_back (main_tree.get_root ());
132
+ for (int i = 0 ; i < 100 ; ++i) {
133
+ auto parent = main_nodes[i / 3 ];
134
+ auto new_node = main_tree.add_child (parent, i + 2 );
135
+ main_nodes.push_back (new_node);
136
+ }
137
+
138
+ // create wide sub_tree1 with many siblings
139
+ sub1_nodes.push_back (sub_tree1.get_root ());
140
+ auto sub1_parent = sub_tree1.get_root ();
141
+ for (int i = 0 ; i < 50 ; ++i) {
142
+ auto new_node = sub_tree1.add_child (sub1_parent, 1100 + i);
143
+ sub1_nodes.push_back (new_node);
144
+ }
145
+
146
+ // create balanced sub_tree2
147
+ sub2_nodes.push_back (sub_tree2.get_root ());
148
+ for (int i = 0 ; i < 32 ; ++i) {
149
+ auto parent = sub2_nodes[i];
150
+ auto left = sub_tree2.add_child (parent, 2100 + i*2 );
151
+ auto right = sub_tree2.add_child (parent, 2100 + i*2 + 1 );
152
+ sub2_nodes.push_back (left);
153
+ sub2_nodes.push_back (right);
154
+ }
155
+
156
+ // create deep chain in sub_tree3
157
+ sub3_nodes.push_back (sub_tree3.get_root ());
158
+ auto current = sub_tree3.get_root ();
159
+ for (int i = 0 ; i < 100 ; ++i) {
160
+ auto new_node = sub_tree3.add_child (current, 3100 + i);
161
+ sub3_nodes.push_back (new_node);
162
+ current = new_node;
163
+ }
164
+
165
+ // create complex reference patterns
166
+ for (int i = 0 ; i < main_nodes.size (); i += 10 ) {
167
+ main_tree.add_subtree_ref (main_nodes[i], sub_tree1_ref);
168
+ }
169
+
170
+ for (int i = 0 ; i < sub1_nodes.size (); i += 5 ) {
171
+ sub_tree1.add_subtree_ref (sub1_nodes[i], sub_tree2_ref);
172
+ }
173
+
174
+ for (int i = 0 ; i < sub2_nodes.size (); i += 3 ) {
175
+ sub_tree2.add_subtree_ref (sub2_nodes[i], sub_tree3_ref);
176
+ }
177
+
178
+ // test reference counting
179
+ bool deleted = forest.delete_tree (sub_tree3_ref);
180
+ I (!deleted, " Should not be able to delete heavily referenced tree" );
181
+
182
+ // test traversal with subtree references
183
+ int node_count = 0 ;
184
+ std::set<int > unique_values;
185
+
186
+ auto range = main_tree.pre_order (main_tree.get_root (), true );
187
+ for (auto it = range.begin (); it != range.end (); ++it) {
188
+ node_count++;
189
+ unique_values.insert (it.get_data ());
190
+
191
+ I (node_count <= 10000 , " Possible infinite loop in traversal" );
192
+ }
193
+
194
+ I (node_count > 500 , " Should visit at least 500 nodes in large tree traversal" );
195
+ I (unique_values.size () > 200 , " Should see at least 200 unique values" );
196
+
197
+ // tst bulk deletions
198
+ for (int i = main_nodes.size () - 1 ; i >= 0 ; i -= 10 ) {
199
+ if (i < main_nodes.size ()) {
200
+ main_tree.delete_leaf (main_nodes[i]);
201
+ }
202
+ }
203
+
204
+ // verify reference counts
205
+ deleted = forest.delete_tree (sub_tree1_ref);
206
+ I (!deleted, " Should still not be able to delete referenced tree" );
207
+ }
208
+
209
+ void test_edge_cases () {
210
+ hhds::Forest<int > forest;
211
+
212
+ // test creation of more trees
213
+ std::vector<hhds::Tree_pos> tree_refs;
214
+ for (int i = 0 ; i < 5 ; ++i) {
215
+ auto ref = forest.create_tree (i);
216
+ tree_refs.push_back (ref);
217
+
218
+ auto & tree = forest.get_tree (ref);
219
+ I (tree.get_data (tree.get_root ()) == i, " Tree creation verification failed" );
220
+ }
221
+
222
+ // create chain of references with two children per tree
223
+ for (size_t i = 0 ; i < tree_refs.size () - 1 ; ++i) {
224
+ auto & current_tree = forest.get_tree (tree_refs[i]);
225
+ auto root = current_tree.get_root ();
226
+ I (current_tree.get_data (root) == i, " Root data verification failed" );
227
+
228
+ for (int j = 0 ; j < 2 ; ++j) {
229
+ auto child = current_tree.add_child (root, i * 10 + j);
230
+ I (current_tree.get_data (child) == i * 10 + j, " Child creation verification failed" );
231
+ I (current_tree.is_leaf (child), " New node should be a leaf" );
232
+
233
+ if (j == 0 ) {
234
+ current_tree.add_subtree_ref (child, tree_refs[(i + 1 ) % tree_refs.size ()]);
235
+ }
236
+ }
237
+ }
238
+
239
+ // create single circular reference
240
+ auto & last_tree = forest.get_tree (tree_refs.back ());
241
+ auto last_child = last_tree.add_child (last_tree.get_root (), 100 );
242
+ I (last_tree.get_data (last_child) == 100 , " Last child creation verification failed" );
243
+ last_tree.add_subtree_ref (last_child, tree_refs[0 ]);
244
+
245
+ // add a few more leaf nodes to existing trees
246
+ for (size_t i = 0 ; i < tree_refs.size (); i += 2 ) { // Every other tree
247
+ auto & tree = forest.get_tree (tree_refs[i]);
248
+ tree.add_child (tree.get_root (), i * 20 );
249
+ }
250
+
251
+ // test traversal
252
+ int count = 0 ;
253
+ std::set<int > unique_values;
254
+ auto & first_tree = forest.get_tree (tree_refs[0 ]);
255
+
256
+ for (auto it = first_tree.pre_order (first_tree.get_root (), true ).begin ();
257
+ it != first_tree.pre_order (first_tree.get_root (), true ).end (); ++it) {
258
+ count++;
259
+ unique_values.insert (it.get_data ());
260
+ I (count <= 32 , " Traversal count exceeded expected maximum" );
261
+ }
262
+
263
+ I (count > 5 , " Should visit at least 5 nodes in traversal" );
264
+ I (unique_values.size () > 3 , " Should see at least 3 unique values" );
265
+
266
+ // try to delete trees
267
+ for (auto ref : tree_refs) {
268
+ bool deleted = forest.delete_tree (ref);
269
+ I (!deleted, " Should not be able to delete referenced trees" );
270
+ }
271
+ }
272
+
115
273
int main () {
274
+ std::cout << " \n Starting forest correctness tests...\n\n " ;
275
+
116
276
test_basic_forest_operations ();
117
277
std::cout << " Basic forest operations test passed\n " ;
118
278
@@ -122,5 +282,15 @@ int main() {
122
282
test_tree_traversal_with_subtrees ();
123
283
std::cout << " Tree traversal with subtrees test passed\n " ;
124
284
285
+ std::cout << " \n Starting large-scale tests...\n " ;
286
+
287
+ test_complex_forest_operations ();
288
+ std::cout << " Complex forest operations test passed\n " ;
289
+
290
+ test_edge_cases ();
291
+ std::cout << " Edge cases test passed\n " ;
292
+
293
+ std::cout << " \n All forest correctness tests passed successfully!\n " ;
294
+
125
295
return 0 ;
126
296
}
0 commit comments