Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
rand-tree.cc
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
33
38#include <gtest/gtest.h>
39#include <numeric>
40
41#include <tpl_rand_tree.H>
42#include <tpl_binNodeUtils.H>
43#include <random>
44#include <set>
45#include <vector>
46#include <algorithm>
47
48using namespace std;
49using namespace Aleph;
50
51// ============================================================================
52// Type Aliases and Helpers
53// ============================================================================
54
57
58// Helper to collect keys in inorder
59template <typename NodeT>
60std::vector<int> inorder_keys(NodeT *root)
61{
62 std::vector<int> keys;
63 if (root == NodeT::NullPtr)
64 return keys;
65
66 auto left = inorder_keys<NodeT>(LLINK(root));
67 keys.insert(keys.end(), left.begin(), left.end());
68 keys.push_back(KEY(root));
69 auto right = inorder_keys<NodeT>(RLINK(root));
70 keys.insert(keys.end(), right.begin(), right.end());
71
72 return keys;
73}
74
75// Helper class to manage node allocation/deallocation
77{
78 std::vector<Node *> nodes;
79
80public:
82 {
83 for (auto *p : nodes)
84 delete p;
85 }
86
87 Node *make(int key)
88 {
89 auto *p = new Node(key);
90 nodes.push_back(p);
91 return p;
92 }
93
94 void forget(Node *p)
95 {
96 nodes.erase(std::remove(nodes.begin(), nodes.end(), p), nodes.end());
97 }
98};
99
100// ============================================================================
101// Empty Tree Tests
102// ============================================================================
103
105{
106 Tree tree(42); // fixed seed for reproducibility
107
108 EXPECT_EQ(tree.size(), 0u);
109 EXPECT_TRUE(tree.is_empty());
110 EXPECT_EQ(tree.getRoot(), Node::NullPtr);
111 EXPECT_TRUE(tree.verify());
112}
113
115{
116 Tree tree(42);
117
118 EXPECT_EQ(tree.search(10), nullptr);
119 EXPECT_EQ(tree.search(0), nullptr);
120 EXPECT_EQ(tree.search(-1), nullptr);
121}
122
124{
125 Tree tree(42);
126
127 EXPECT_EQ(tree.remove(10), nullptr);
128 EXPECT_EQ(tree.size(), 0u);
129}
130
131// ============================================================================
132// Insert Tests
133// ============================================================================
134
136{
137 Tree tree(42);
138 NodePool pool;
139
140 auto *p = pool.make(10);
141 auto *inserted = tree.insert(p);
142
143 EXPECT_EQ(inserted, p);
144 EXPECT_EQ(tree.size(), 1u);
145 EXPECT_FALSE(tree.is_empty());
146 EXPECT_EQ(tree.getRoot(), p);
147 EXPECT_TRUE(tree.verify());
148}
149
151{
152 Tree tree(42);
153 NodePool pool;
154
155 for (int k : {5, 3, 7, 1, 4, 6, 8})
156 ASSERT_NE(tree.insert(pool.make(k)), nullptr);
157
158 EXPECT_EQ(tree.size(), 7u);
159 EXPECT_TRUE(tree.verify());
160
161 auto keys = inorder_keys<Node>(tree.getRoot());
162 EXPECT_EQ(keys, (std::vector<int>{1, 3, 4, 5, 6, 7, 8}));
163}
164
166{
167 Tree tree(42);
168 NodePool pool;
169
170 auto *p1 = pool.make(10);
171 auto *p2 = pool.make(10);
172
173 EXPECT_NE(tree.insert(p1), nullptr);
174 EXPECT_EQ(tree.insert(p2), nullptr); // duplicate rejected
175
176 EXPECT_EQ(tree.size(), 1u);
177 pool.forget(p2);
178 delete p2;
179}
180
182{
183 Tree tree(42);
184 NodePool pool;
185
186 for (int i = 0; i < 5; ++i)
187 ASSERT_NE(tree.insert_dup(pool.make(10)), nullptr);
188
189 EXPECT_EQ(tree.size(), 5u);
190 EXPECT_TRUE(tree.verify());
191}
192
194{
195 Tree tree(42);
196 NodePool pool;
197
198 for (int k = 1; k <= 100; ++k)
199 ASSERT_NE(tree.insert(pool.make(k)), nullptr);
200
201 EXPECT_EQ(tree.size(), 100u);
202 EXPECT_TRUE(tree.verify());
203
204 auto keys = inorder_keys<Node>(tree.getRoot());
205 std::vector<int> expected(100);
206 std::iota(expected.begin(), expected.end(), 1);
208}
209
211{
212 Tree tree(42);
213 NodePool pool;
214
215 for (int k = 100; k >= 1; --k)
216 ASSERT_NE(tree.insert(pool.make(k)), nullptr);
217
218 EXPECT_EQ(tree.size(), 100u);
219 EXPECT_TRUE(tree.verify());
220
221 auto keys = inorder_keys<Node>(tree.getRoot());
222 std::vector<int> expected(100);
223 std::iota(expected.begin(), expected.end(), 1);
225}
226
227// ============================================================================
228// Search Tests
229// ============================================================================
230
232{
233 Tree tree(42);
234 NodePool pool;
235
236 for (int k : {1, 2, 3, 4, 5})
237 tree.insert(pool.make(k));
238
239 for (int k : {1, 2, 3, 4, 5})
240 {
241 auto *found = tree.search(k);
242 ASSERT_NE(found, nullptr);
243 EXPECT_EQ(KEY(found), k);
244 }
245}
246
248{
249 Tree tree(42);
250 NodePool pool;
251
252 for (int k : {1, 3, 5})
253 tree.insert(pool.make(k));
254
255 EXPECT_EQ(tree.search(2), nullptr);
256 EXPECT_EQ(tree.search(4), nullptr);
257 EXPECT_EQ(tree.search(0), nullptr);
258 EXPECT_EQ(tree.search(6), nullptr);
259}
260
262{
263 Tree tree(42);
264 NodePool pool;
265
266 auto *p1 = pool.make(10);
267 tree.insert(p1);
268
269 auto *p2 = pool.make(10);
270 auto *found = tree.search_or_insert(p2);
271
272 EXPECT_EQ(found, p1);
273 EXPECT_EQ(tree.size(), 1u);
274
275 pool.forget(p2);
276 delete p2;
277}
278
280{
281 Tree tree(42);
282 NodePool pool;
283
284 tree.insert(pool.make(5));
285
286 auto *p = pool.make(10);
287 auto *result = tree.search_or_insert(p);
288
289 EXPECT_EQ(result, p);
290 EXPECT_EQ(tree.size(), 2u);
291 EXPECT_NE(tree.search(10), nullptr);
292}
293
294// ============================================================================
295// Remove Tests
296// ============================================================================
297
299{
300 Tree tree(42);
301 NodePool pool;
302
303 for (int k : {1, 2, 3, 4, 5})
304 tree.insert(pool.make(k));
305
306 auto *removed = tree.remove(3);
307 ASSERT_NE(removed, nullptr);
308 EXPECT_EQ(KEY(removed), 3);
309
310 pool.forget(removed);
311 delete removed;
312
313 EXPECT_EQ(tree.size(), 4u);
314 EXPECT_EQ(tree.search(3), nullptr);
315 EXPECT_TRUE(tree.verify());
316
317 auto keys = inorder_keys<Node>(tree.getRoot());
318 EXPECT_EQ(keys, (std::vector<int>{1, 2, 4, 5}));
319}
320
322{
323 Tree tree(42);
324 NodePool pool;
325
326 tree.insert(pool.make(1));
327 tree.insert(pool.make(3));
328
329 EXPECT_EQ(tree.remove(2), nullptr);
330 EXPECT_EQ(tree.size(), 2u);
331}
332
334{
335 Tree tree(42);
336 NodePool pool;
337
338 auto *root = pool.make(5);
339 tree.insert(root);
340 tree.insert(pool.make(3));
341 tree.insert(pool.make(7));
342
343 auto *removed = tree.remove(5);
344 ASSERT_NE(removed, nullptr);
345 EXPECT_EQ(KEY(removed), 5);
346 pool.forget(removed);
347 delete removed;
348
349 EXPECT_EQ(tree.size(), 2u);
350 EXPECT_TRUE(tree.verify());
351}
352
354{
355 Tree tree(42);
356 NodePool pool;
357
358 for (int k : {5, 3, 7, 1, 4, 6, 8})
359 tree.insert(pool.make(k));
360
361 for (int k : {5, 3, 7, 1, 4, 6, 8})
362 {
363 auto *removed = tree.remove(k);
364 ASSERT_NE(removed, nullptr) << "Failed to remove " << k;
365 pool.forget(removed);
366 delete removed;
367 EXPECT_TRUE(tree.verify());
368 }
369
370 EXPECT_EQ(tree.size(), 0u);
371}
372
374{
375 Tree tree(42);
376 NodePool pool;
377
378 for (int k = 1; k <= 10; ++k)
379 tree.insert(pool.make(k));
380
381 for (int k = 1; k <= 10; ++k)
382 {
383 auto *removed = tree.remove(k);
384 ASSERT_NE(removed, nullptr);
385 pool.forget(removed);
386 delete removed;
387 EXPECT_TRUE(tree.verify());
388 }
389
390 EXPECT_EQ(tree.size(), 0u);
391}
392
394{
395 Tree tree(42);
396 NodePool pool;
397
398 for (int k = 1; k <= 10; ++k)
399 tree.insert(pool.make(k));
400
401 for (int k = 10; k >= 1; --k)
402 {
403 auto *removed = tree.remove(k);
404 ASSERT_NE(removed, nullptr);
405 pool.forget(removed);
406 delete removed;
407 EXPECT_TRUE(tree.verify());
408 }
409
410 EXPECT_EQ(tree.size(), 0u);
411}
412
413// ============================================================================
414// Select and Position Tests
415// ============================================================================
416
418{
419 Tree tree(42);
420 NodePool pool;
421
422 for (int k : {5, 3, 7, 1, 4, 6, 8})
423 tree.insert(pool.make(k));
424
425 // Inorder: 1, 3, 4, 5, 6, 7, 8
426 EXPECT_EQ(KEY(tree.select(0)), 1);
427 EXPECT_EQ(KEY(tree.select(1)), 3);
428 EXPECT_EQ(KEY(tree.select(2)), 4);
429 EXPECT_EQ(KEY(tree.select(3)), 5);
430 EXPECT_EQ(KEY(tree.select(4)), 6);
431 EXPECT_EQ(KEY(tree.select(5)), 7);
432 EXPECT_EQ(KEY(tree.select(6)), 8);
433}
434
436{
437 Tree tree(42);
438 NodePool pool;
439
440 tree.insert(pool.make(1));
441 tree.insert(pool.make(2));
442
443 EXPECT_THROW(tree.select(2), std::out_of_range);
444 EXPECT_THROW(tree.select(100), std::out_of_range);
445}
446
448{
449 Tree tree(42);
450 NodePool pool;
451
452 for (int k : {5, 3, 7, 1, 4, 6, 8})
453 tree.insert(pool.make(k));
454
455 // Inorder: 1, 3, 4, 5, 6, 7, 8
456 auto [pos1, node1] = tree.position(1);
457 EXPECT_EQ(pos1, 0);
458 EXPECT_EQ(KEY(node1), 1);
459
460 auto [pos5, node5] = tree.position(5);
461 EXPECT_EQ(pos5, 3);
462 EXPECT_EQ(KEY(node5), 5);
463
464 auto [pos8, node8] = tree.position(8);
465 EXPECT_EQ(pos8, 6);
466 EXPECT_EQ(KEY(node8), 8);
467}
468
470{
471 Tree tree(42);
472 NodePool pool;
473
474 for (int k : {2, 4, 6})
475 tree.insert(pool.make(k));
476
477 auto [pos, node] = tree.position(3);
478 EXPECT_EQ(pos, -1);
479}
480
482{
483 Tree tree(42);
484 NodePool pool;
485
486 for (int k : {2, 4, 6, 8})
487 tree.insert(pool.make(k));
488
489 auto [pos, node] = tree.find_position(4);
490 EXPECT_EQ(pos, 1);
491 EXPECT_EQ(KEY(node), 4);
492}
493
495{
496 Tree tree(42);
497 NodePool pool;
498
499 for (int k : {2, 4, 6, 8})
500 tree.insert(pool.make(k));
501
502 // 5 would be at position 2 (between 4 and 6)
503 auto [pos, node] = tree.find_position(5);
504 EXPECT_EQ(pos, 2);
505 // The returned node is the predecessor (key immediately less than 5)
506 EXPECT_NE(node, nullptr);
507}
508
510{
511 Tree tree(42);
512 NodePool pool;
513
514 for (int k : {2, 4, 6})
515 tree.insert(pool.make(k));
516
517 auto [pos, node] = tree.find_position(1);
518 EXPECT_EQ(pos, -1);
519 EXPECT_EQ(KEY(node), 2); // smallest key
520}
521
523{
524 Tree tree(42);
525 NodePool pool;
526
527 for (int k : {2, 4, 6})
528 tree.insert(pool.make(k));
529
530 auto [pos, node] = tree.find_position(10);
531 EXPECT_EQ(pos, 3);
532 EXPECT_EQ(KEY(node), 6); // largest key
533}
534
535// ============================================================================
536// Remove by Position Tests
537// ============================================================================
538
540{
541 Tree tree(42);
542 NodePool pool;
543
544 for (int k : {5, 3, 7, 1, 4, 6, 8})
545 tree.insert(pool.make(k));
546
547 // Inorder: 1, 3, 4, 5, 6, 7, 8
548 // Remove position 3 (key = 5)
549 auto *removed = tree.remove_pos(3);
550 ASSERT_NE(removed, nullptr);
551 EXPECT_EQ(KEY(removed), 5);
552 pool.forget(removed);
553 delete removed;
554
555 EXPECT_EQ(tree.size(), 6u);
556 EXPECT_TRUE(tree.verify());
557}
558
560{
561 Tree tree(42);
562 NodePool pool;
563
564 for (int k : {5, 3, 7})
565 tree.insert(pool.make(k));
566
567 // Inorder: 3, 5, 7 - remove first
568 auto *removed = tree.remove_pos(0);
569 ASSERT_NE(removed, nullptr);
570 EXPECT_EQ(KEY(removed), 3);
571 pool.forget(removed);
572 delete removed;
573
574 EXPECT_EQ(tree.size(), 2u);
575}
576
578{
579 Tree tree(42);
580 NodePool pool;
581
582 for (int k : {5, 3, 7})
583 tree.insert(pool.make(k));
584
585 // Inorder: 3, 5, 7 - remove last
586 auto *removed = tree.remove_pos(2);
587 ASSERT_NE(removed, nullptr);
588 EXPECT_EQ(KEY(removed), 7);
589 pool.forget(removed);
590 delete removed;
591
592 EXPECT_EQ(tree.size(), 2u);
593}
594
595// NOTE: remove_pos is marked noexcept but throws - this is a bug
596// The test below would cause std::terminate, so we skip it
597// TEST(RandTree, RemovePosOutOfRangeThrows)
598
599// ============================================================================
600// Split Tests
601// ============================================================================
602
604{
605 Tree tree(42);
606 Tree t1(42);
607 Tree t2(42);
608 NodePool pool;
609
610 for (int k : {2, 4, 6, 8, 10})
611 tree.insert(pool.make(k));
612
613 bool result = tree.split_key(5, t1, t2);
614 EXPECT_TRUE(result);
615
616 // t1 should have keys < 5: {2, 4}
617 // t2 should have keys > 5: {6, 8, 10}
618 auto keys1 = inorder_keys<Node>(t1.getRoot());
619 auto keys2 = inorder_keys<Node>(t2.getRoot());
620
621 EXPECT_EQ(keys1, (std::vector<int>{2, 4}));
622 EXPECT_EQ(keys2, (std::vector<int>{6, 8, 10}));
623}
624
626{
627 Tree tree(42);
628 Tree t1(42);
629 Tree t2(42);
630 NodePool pool;
631
632 for (int k : {2, 4, 6, 8, 10})
633 tree.insert(pool.make(k));
634
635 bool result = tree.split_key(6, t1, t2);
636 EXPECT_FALSE(result); // key was in tree
637}
638
640{
641 Tree tree(42);
642 Tree t1(42);
643 Tree t2(42);
644 NodePool pool;
645
646 for (int k : {2, 4, 6, 8, 10})
647 tree.insert(pool.make(k));
648
649 tree.split_key_dup(6, t1, t2);
650
651 auto keys1 = inorder_keys<Node>(t1.getRoot());
652 auto keys2 = inorder_keys<Node>(t2.getRoot());
653
654 // Actual semantics: t1 gets keys <= key, t2 gets keys > key
655 EXPECT_EQ(keys1, (std::vector<int>{2, 4, 6}));
656 EXPECT_EQ(keys2, (std::vector<int>{8, 10}));
657}
658
660{
661 Tree tree(42);
662 Tree t1(42);
663 Tree t2(42);
664 NodePool pool;
665
666 for (int k : {1, 2, 3, 4, 5})
667 tree.insert(pool.make(k));
668
669 tree.split_pos(2, t1, t2);
670
671 auto keys1 = inorder_keys<Node>(t1.getRoot());
672 auto keys2 = inorder_keys<Node>(t2.getRoot());
673
674 // t1: positions [0, 2) -> keys {1, 2}
675 // t2: positions [2, 5) -> keys {3, 4, 5}
676 EXPECT_EQ(keys1, (std::vector<int>{1, 2}));
677 EXPECT_EQ(keys2, (std::vector<int>{3, 4, 5}));
678}
679
680// ============================================================================
681// Join Tests
682// ============================================================================
683
685{
686 Tree tree1(42);
687 Tree tree2(42);
688 Tree dup(42);
689 NodePool pool;
690
691 for (int k : {1, 3, 5})
692 tree1.insert(pool.make(k));
693 for (int k : {2, 4, 6})
694 tree2.insert(pool.make(k));
695
696 tree1.join(tree2, dup);
697
698 EXPECT_EQ(tree1.size(), 6u);
699 EXPECT_EQ(tree2.size(), 0u);
700 EXPECT_EQ(dup.size(), 0u);
701 EXPECT_TRUE(tree1.verify());
702
703 auto keys = inorder_keys<Node>(tree1.getRoot());
704 EXPECT_EQ(keys, (std::vector<int>{1, 2, 3, 4, 5, 6}));
705}
706
708{
709 Tree tree1(42);
710 Tree tree2(42);
711 Tree dup(42);
712 NodePool pool;
713
714 for (int k : {1, 3, 5})
715 tree1.insert(pool.make(k));
716 for (int k : {3, 4, 5})
717 tree2.insert(pool.make(k));
718
719 tree1.join(tree2, dup);
720
721 EXPECT_EQ(tree1.size(), 4u); // 1, 3, 4, 5
722 EXPECT_EQ(tree2.size(), 0u);
723 EXPECT_EQ(dup.size(), 2u); // two duplicates: 3, 5
724
725 auto keys = inorder_keys<Node>(tree1.getRoot());
726 EXPECT_EQ(keys, (std::vector<int>{1, 3, 4, 5}));
727
728 auto dupKeys = inorder_keys<Node>(dup.getRoot());
729 std::sort(dupKeys.begin(), dupKeys.end());
730 EXPECT_EQ(dupKeys, (std::vector<int>{3, 5}));
731}
732
734{
735 Tree tree1(42);
736 Tree tree2(42);
737 NodePool pool;
738
739 for (int k : {1, 3, 5})
740 tree1.insert(pool.make(k));
741 for (int k : {3, 4, 5})
742 tree2.insert(pool.make(k));
743
744 tree1.join_dup(tree2);
745
746 EXPECT_EQ(tree1.size(), 6u); // 1, 3, 3, 4, 5, 5
747 EXPECT_EQ(tree2.size(), 0u);
748 EXPECT_TRUE(tree1.verify());
749}
750
752{
753 Tree tree1(42);
754 Tree tree2(42);
755 NodePool pool;
756
757 // tree1 has smaller keys
758 for (int k : {1, 2, 3})
759 tree1.insert(pool.make(k));
760 // tree2 has larger keys
761 for (int k : {10, 11, 12})
762 tree2.insert(pool.make(k));
763
764 tree1.join_exclusive(tree2);
765
766 EXPECT_EQ(tree1.size(), 6u);
767 EXPECT_EQ(tree2.size(), 0u);
768 EXPECT_TRUE(tree1.verify());
769
770 auto keys = inorder_keys<Node>(tree1.getRoot());
771 EXPECT_EQ(keys, (std::vector<int>{1, 2, 3, 10, 11, 12}));
772}
773
774// ============================================================================
775// Iterator Tests
776// ============================================================================
777
779{
780 Tree tree(42);
781 NodePool pool;
782
783 for (int k : {5, 3, 7, 1, 4, 6, 8})
784 tree.insert(pool.make(k));
785
786 std::vector<int> result;
787 for (Tree::Iterator it(tree); it.has_curr(); it.next())
788 result.push_back(KEY(it.get_curr()));
789
790 EXPECT_EQ(result, (std::vector<int>{1, 3, 4, 5, 6, 7, 8}));
791}
792
794{
795 Tree tree(42);
796 Tree::Iterator it(tree);
797
798 EXPECT_FALSE(it.has_curr());
799}
800
802{
803 Tree tree(42);
804 NodePool pool;
805
806 for (int k : {1, 2, 3, 4, 5})
807 tree.insert(pool.make(k));
808
809 auto *removed = tree.remove(3);
810 pool.forget(removed);
811 delete removed;
812
813 std::vector<int> result;
814 for (Tree::Iterator it(tree); it.has_curr(); it.next())
815 result.push_back(KEY(it.get_curr()));
816
817 EXPECT_EQ(result, (std::vector<int>{1, 2, 4, 5}));
818}
819
820// ============================================================================
821// Special Member Functions Tests
822// ============================================================================
823
825{
826 Tree tree1(42);
827 Tree tree2(42);
828 NodePool pool;
829
830 for (int k : {1, 2, 3})
831 tree1.insert(pool.make(k));
832 for (int k : {10, 20})
833 tree2.insert(pool.make(k));
834
835 tree1.swap(tree2);
836
837 EXPECT_EQ(tree1.size(), 2u);
838 EXPECT_EQ(tree2.size(), 3u);
839
840 EXPECT_NE(tree1.search(10), nullptr);
841 EXPECT_NE(tree1.search(20), nullptr);
842 EXPECT_NE(tree2.search(1), nullptr);
843 EXPECT_NE(tree2.search(2), nullptr);
844 EXPECT_NE(tree2.search(3), nullptr);
845}
846
848{
849 NodePool pool1, pool2;
850
851 Tree tree1(123);
852 Tree tree2(456);
853
854 // Insert same elements in same order with different seeds
855 for (int k : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
856 {
857 tree1.insert(pool1.make(k));
858 tree2.insert(pool2.make(k));
859 }
860
861 // Both trees should have same elements but potentially different structure
862 EXPECT_EQ(tree1.size(), tree2.size());
863 EXPECT_TRUE(tree1.verify());
864 EXPECT_TRUE(tree2.verify());
865
866 // Inorder traversal should be the same
867 auto keys1 = inorder_keys<Node>(tree1.getRoot());
868 auto keys2 = inorder_keys<Node>(tree2.getRoot());
870}
871
872// ============================================================================
873// Custom Comparator Tests
874// ============================================================================
875
877{
879 using NodeGt = TreeGt::Node;
880
881 TreeGt tree(42);
882
883 std::vector<NodeGt *> nodes;
884 for (int k : {1, 2, 3, 4, 5})
885 {
886 auto *p = new NodeGt(k);
887 nodes.push_back(p);
888 tree.insert(p);
889 }
890
891 EXPECT_EQ(tree.size(), 5u);
892 EXPECT_TRUE(tree.verify());
893
894 // With greater<int>, inorder should be descending
895 std::vector<int> result;
896 for (TreeGt::Iterator it(tree); it.has_curr(); it.next())
897 result.push_back(KEY(it.get_curr()));
898
899 EXPECT_EQ(result, (std::vector<int>{5, 4, 3, 2, 1}));
900
901 // Clean up
902 for (int k : {1, 2, 3, 4, 5})
903 delete tree.remove(k);
904}
905
906// ============================================================================
907// Edge Cases
908// ============================================================================
909
911{
912 Tree tree(42);
913 NodePool pool;
914
915 for (int k : {-5, -3, -1, 0, 1, 3, 5})
916 tree.insert(pool.make(k));
917
918 EXPECT_EQ(tree.size(), 7u);
919 EXPECT_TRUE(tree.verify());
920
921 auto keys = inorder_keys<Node>(tree.getRoot());
922 EXPECT_EQ(keys, (std::vector<int>{-5, -3, -1, 0, 1, 3, 5}));
923
924 // Search negative keys
925 EXPECT_NE(tree.search(-5), nullptr);
926 EXPECT_NE(tree.search(-1), nullptr);
927 EXPECT_EQ(tree.search(-2), nullptr);
928}
929
931{
932 Tree tree(42);
933 NodePool pool;
934
935 auto *p = pool.make(42);
936 tree.insert(p);
937
938 EXPECT_EQ(tree.size(), 1u);
939 EXPECT_EQ(KEY(tree.select(0)), 42);
940
941 auto [pos, node] = tree.position(42);
942 EXPECT_EQ(pos, 0);
943 EXPECT_EQ(KEY(node), 42);
944
945 auto *removed = tree.remove(42);
946 ASSERT_NE(removed, nullptr);
947 pool.forget(removed);
948 delete removed;
949
950 EXPECT_EQ(tree.size(), 0u);
951}
952
953// ============================================================================
954// Stress Tests
955// ============================================================================
956
958{
959 Tree tree(42);
960 NodePool pool;
961 std::set<int> oracle;
962
963 std::mt19937 rng(12345);
964 std::uniform_int_distribution<int> dist(0, 999);
965
966 // Insert phase
967 for (int i = 0; i < 500; ++i)
968 {
969 int k = dist(rng);
970 if (oracle.count(k) == 0)
971 {
972 ASSERT_NE(tree.insert(pool.make(k)), nullptr);
973 oracle.insert(k);
974 }
975 }
976
977 EXPECT_EQ(tree.size(), oracle.size());
978 EXPECT_TRUE(tree.verify());
979
980 // Search phase
981 for (int i = 0; i < 200; ++i)
982 {
983 int k = dist(rng);
984 auto *found = tree.search(k);
985 if (oracle.count(k))
986 EXPECT_NE(found, nullptr);
987 else
988 EXPECT_EQ(found, nullptr);
989 }
990
991 // Remove phase
992 for (int i = 0; i < 200; ++i)
993 {
994 int k = dist(rng);
995 auto *removed = tree.remove(k);
996 if (oracle.count(k))
997 {
998 ASSERT_NE(removed, nullptr);
999 oracle.erase(k);
1000 pool.forget(removed);
1001 delete removed;
1002 }
1003 else
1004 {
1005 EXPECT_EQ(removed, nullptr);
1006 }
1007 }
1008
1009 EXPECT_EQ(tree.size(), oracle.size());
1010 EXPECT_TRUE(tree.verify());
1011
1012 // Verify remaining keys
1013 auto keys = inorder_keys<Node>(tree.getRoot());
1014 EXPECT_EQ(keys, std::vector<int>(oracle.begin(), oracle.end()));
1015}
1016
1018{
1019 Tree tree(42);
1020 NodePool pool;
1021
1022 const int N = 5000;
1023
1024 // Insert N elements
1025 for (int k = 0; k < N; ++k)
1026 tree.insert(pool.make(k));
1027
1028 EXPECT_EQ(tree.size(), static_cast<size_t>(N));
1029 EXPECT_TRUE(tree.verify());
1030
1031 // Verify select works correctly
1032 for (int i = 0; i < 10; ++i)
1033 EXPECT_EQ(KEY(tree.select(i)), i);
1034
1035 // Remove half
1036 for (int k = 0; k < N; k += 2)
1037 {
1038 auto *removed = tree.remove(k);
1039 ASSERT_NE(removed, nullptr);
1040 pool.forget(removed);
1041 delete removed;
1042 }
1043
1044 EXPECT_EQ(tree.size(), static_cast<size_t>(N / 2));
1045 EXPECT_TRUE(tree.verify());
1046
1047 // Verify remaining elements
1048 for (int k = 1; k < N; k += 2)
1049 EXPECT_NE(tree.search(k), nullptr);
1050}
1051
1052// ============================================================================
1053// Rand_Tree_Vtl Tests
1054// ============================================================================
1055
1057{
1059 using NodeVtl = TreeVtl::Node;
1060
1061 TreeVtl tree(42);
1062
1063 for (int k : {1, 2, 3, 4, 5})
1064 tree.insert(new NodeVtl(k));
1065
1066 EXPECT_EQ(tree.size(), 5u);
1067 EXPECT_TRUE(tree.verify());
1068
1069 // Clean up properly using remove to avoid memory leaks
1070 for (int k : {1, 2, 3, 4, 5})
1071 delete tree.remove(k);
1072}
1073
1074// ============================================================================
1075// Verify Method Tests
1076// ============================================================================
1077
1079{
1080 Tree tree(42);
1081 NodePool pool;
1082
1083 EXPECT_TRUE(tree.verify()); // empty tree is valid
1084
1085 for (int k : {5, 3, 7, 1, 4, 6, 8})
1086 tree.insert(pool.make(k));
1087
1088 EXPECT_TRUE(tree.verify());
1089
1090 // After various operations
1091 tree.remove(5);
1092 EXPECT_TRUE(tree.verify());
1093}
1094
1095// ============================================================================
1096// API Coverage Tests
1097// ============================================================================
1098
1100{
1101 Tree tree(42);
1102 NodePool pool;
1103
1104 Node *&root = tree.getRoot();
1105 EXPECT_EQ(root, Node::NullPtr);
1106
1107 tree.insert(pool.make(10));
1108 EXPECT_NE(root, Node::NullPtr);
1109 EXPECT_EQ(KEY(root), 10);
1110}
1111
1113{
1114 Tree tree(42);
1115
1116 auto &cmp1 = tree.key_comp();
1117 auto &cmp2 = tree.get_compare();
1118
1119 // Both should return the same comparator
1120 EXPECT_TRUE(cmp1(1, 2));
1121 EXPECT_FALSE(cmp1(2, 1));
1122 EXPECT_TRUE(cmp2(1, 2));
1123 EXPECT_FALSE(cmp2(2, 1));
1124}
1125
1127{
1128 Tree tree(42);
1129
1130 auto *rng = tree.gsl_rng_object();
1131 EXPECT_NE(rng, nullptr);
1132}
1133
1135{
1136 Tree tree1(42);
1137 Tree tree2(42);
1138 NodePool pool1, pool2;
1139
1140 // Same seed, same insertion order -> same structure
1141 tree1.set_seed(999);
1142 tree2.set_seed(999);
1143
1144 for (int k : {1, 2, 3, 4, 5})
1145 {
1146 tree1.insert(pool1.make(k));
1147 tree2.insert(pool2.make(k));
1148 }
1149
1150 // Trees should have identical structure
1151 // (This is probabilistic but with same seed should be identical)
1152 EXPECT_EQ(tree1.size(), tree2.size());
1153}
1154
1155// ============================================================================
1156// Copy Prevention Tests (compile-time)
1157// ============================================================================
1158
1159static_assert(!std::is_copy_assignable_v<Tree>,
1160 "Rand_Tree should not be copy assignable");
1161
1162static_assert(!std::is_copy_constructible_v<Tree>,
1163 "Rand_Tree should not be copy constructible");
WeightedDigraph::Node Node
@ KEY
Definition btreepic.C:169
NodeType< Key > Node
Minimal std::expected-style result type for C++20.
void forget(Node *p)
Definition rand-tree.cc:94
std::vector< Node * > nodes
Definition rand-tree.cc:78
Node * make(int key)
Definition rand-tree.cc:87
Node for QuadTree spatial data structure.
Definition quadnode.H:94
QuadTree - Hierarchical spatial index for 2D points.
Definition quadtree.H:126
void remove(const Point &p)
Remove a point from the tree.
Definition quadtree.H:565
Point * search(const Point &p) noexcept
Search for a point in the tree.
Definition quadtree.H:524
Point * insert(Node *&r, const Point &p)
Recursive insert helper.
Definition quadtree.H:281
Generator for uniformly random trees.
#define TEST(name)
static mt19937 rng
#define N
Definition fib.C:294
__gmp_expr< T, __gmp_binary_expr< __gmp_expr< T, U >, unsigned long int, __gmp_root_function > > root(const __gmp_expr< T, U > &expr, unsigned long int l)
Definition gmpfrxx.h:4071
DynArray< Graph::Node * > nodes
Definition graphpic.C:406
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
STL namespace.
std::vector< int > inorder_keys(NodeT *root)
Definition rand-tree.cc:60
Randomized binary search tree.
Randomized binary search tree.
#define RLINK(i, n)
int keys[]
#define LLINK(i, n)
static int * k
Utility functions for binary tree operations.
Randomized binary search tree.