Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tdrbtree_test.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
51#include <gtest/gtest.h>
52#include <tpl_tdRbTree.H>
53#include <tpl_rb_tree.H>
54#include <ahSort.H>
55#include <random>
56#include <set>
57#include <vector>
58#include <string>
59#include <functional>
60
61using namespace Aleph;
62
63// ============================================================================
64// Test Fixtures
65// ============================================================================
66
67class TdRbTreeTest : public ::testing::Test
68{
69protected:
72
74 std::vector<Node*> allocated_nodes;
75
76 void TearDown() override
77 {
78 for (auto *node : allocated_nodes)
79 delete node;
80 allocated_nodes.clear();
81 }
82
83 Node* make_node(int key)
84 {
85 auto *node = new Node(key);
86 allocated_nodes.push_back(node);
87 return node;
88 }
89
90 std::vector<Node*> make_nodes(const std::vector<int>& keys)
91 {
92 std::vector<Node*> nodes;
93 for (int k : keys)
94 nodes.push_back(make_node(k));
95 return nodes;
96 }
97};
98
99class TdRbTreeCustomCompareTest : public ::testing::Test
100{
101protected:
102 // Reverse order comparator
104 {
105 bool operator()(int a, int b) const { return a > b; }
106 };
107
110
112 std::vector<Node*> allocated_nodes;
113
114 void TearDown() override
115 {
116 for (auto *node : allocated_nodes)
117 delete node;
118 }
119
120 Node* make_node(int key)
121 {
122 auto *node = new Node(key);
123 allocated_nodes.push_back(node);
124 return node;
125 }
126
127 std::vector<Node*> make_nodes(const std::vector<int>& keys)
128 {
129 std::vector<Node*> nodes;
130 for (int k : keys)
131 nodes.push_back(make_node(k));
132 return nodes;
133 }
134};
135
136// ============================================================================
137// Basic Operations Tests
138// ============================================================================
139
141{
142 EXPECT_TRUE(tree.is_empty());
143 EXPECT_EQ(tree.size(), 0u);
144 EXPECT_EQ(tree.search(42), nullptr);
145 EXPECT_EQ(tree.remove(42), nullptr);
146 EXPECT_TRUE(tree.verifyRedBlack());
147}
148
150{
151 Node *node = make_node(42);
152 EXPECT_EQ(tree.insert(node), node);
153
154 EXPECT_FALSE(tree.is_empty());
155 EXPECT_EQ(tree.size(), 1u);
156 EXPECT_EQ(tree.search(42), node);
157 EXPECT_TRUE(tree.verifyRedBlack());
158}
159
161{
162 std::vector<int> keys = {50, 25, 75, 10, 30, 60, 90};
163 auto nodes = make_nodes(keys);
164
165 for (auto *node : nodes)
166 EXPECT_NE(tree.insert(node), nullptr);
167
168 EXPECT_EQ(tree.size(), keys.size());
169
170 for (int key : keys)
171 EXPECT_NE(tree.search(key), nullptr) << "Key " << key << " not found";
172
173 EXPECT_TRUE(tree.verifyRedBlack());
174}
175
177{
178 Node *node1 = make_node(42);
179 Node *node2 = make_node(42);
180
181 EXPECT_EQ(tree.insert(node1), node1);
182 EXPECT_EQ(tree.insert(node2), nullptr); // Duplicate rejected
183
184 EXPECT_EQ(tree.size(), 1u);
185 EXPECT_TRUE(tree.verifyRedBlack());
186}
187
189{
190 auto nodes = make_nodes({10, 20, 30});
191 for (auto *node : nodes)
192 tree.insert(node);
193
194 EXPECT_EQ(tree.search(15), nullptr);
195 EXPECT_EQ(tree.search(0), nullptr);
196 EXPECT_EQ(tree.search(100), nullptr);
197}
198
200{
201 Node *node = make_node(42);
202 tree.insert(node);
203
204 Node *removed = tree.remove(42);
205 EXPECT_EQ(removed, node);
206 EXPECT_TRUE(tree.is_empty());
207 EXPECT_EQ(tree.size(), 0u);
208 EXPECT_TRUE(tree.verifyRedBlack());
209}
210
212{
213 auto nodes = make_nodes({50, 25, 75});
214 for (auto *node : nodes)
215 tree.insert(node);
216
217 // Remove leaf (75)
218 Node *removed = tree.remove(75);
219 EXPECT_NE(removed, nullptr);
220 EXPECT_EQ(KEY(removed), 75);
221 EXPECT_EQ(tree.size(), 2u);
222 EXPECT_EQ(tree.search(75), nullptr);
223 EXPECT_NE(tree.search(50), nullptr);
224 EXPECT_NE(tree.search(25), nullptr);
225 EXPECT_TRUE(tree.verifyRedBlack());
226}
227
229{
230 auto nodes = make_nodes({50, 25, 75, 10, 30, 60, 90});
231 for (auto *node : nodes)
232 tree.insert(node);
233
234 // Remove internal node (25)
235 Node *removed = tree.remove(25);
236 EXPECT_NE(removed, nullptr);
237 EXPECT_EQ(tree.size(), 6u);
238 EXPECT_EQ(tree.search(25), nullptr);
239
240 // All other keys should still be present
241 for (int key : {50, 75, 10, 30, 60, 90})
242 EXPECT_NE(tree.search(key), nullptr) << "Key " << key << " missing";
243
244 EXPECT_TRUE(tree.verifyRedBlack());
245}
246
248{
249 auto nodes = make_nodes({50, 25, 75});
250 for (auto *node : nodes)
251 tree.insert(node);
252
253 Node *removed = tree.remove(50);
254 EXPECT_NE(removed, nullptr);
255 EXPECT_EQ(tree.size(), 2u);
256 EXPECT_EQ(tree.search(50), nullptr);
257 EXPECT_NE(tree.search(25), nullptr);
258 EXPECT_NE(tree.search(75), nullptr);
259 EXPECT_TRUE(tree.verifyRedBlack());
260}
261
263{
264 auto nodes = make_nodes({10, 20, 30});
265 for (auto *node : nodes)
266 tree.insert(node);
267
268 EXPECT_EQ(tree.remove(15), nullptr);
269 EXPECT_EQ(tree.size(), 3u);
270 EXPECT_TRUE(tree.verifyRedBlack());
271}
272
274{
275 std::vector<int> keys = {50, 25, 75, 10, 30, 60, 90};
276 auto nodes = make_nodes(keys);
277
278 for (auto *node : nodes)
279 tree.insert(node);
280
281 // Remove in different order
282 std::vector<int> removal_order = {30, 10, 90, 50, 25, 75, 60};
283 for (int key : removal_order)
284 {
285 EXPECT_NE(tree.remove(key), nullptr) << "Failed to remove " << key;
286 EXPECT_TRUE(tree.verifyRedBlack()) << "RB violation after removing " << key;
287 }
288
289 EXPECT_TRUE(tree.is_empty());
290 EXPECT_EQ(tree.size(), 0u);
291}
292
293// ============================================================================
294// Reset and Swap Tests
295// ============================================================================
296
298{
299 auto nodes = make_nodes({10, 20, 30});
300 for (auto *node : nodes)
301 tree.insert(node);
302
303 tree.reset();
304
305 EXPECT_TRUE(tree.is_empty());
306 EXPECT_EQ(tree.size(), 0u);
307 EXPECT_TRUE(tree.verifyRedBlack());
308}
309
311{
313
314 auto node1 = make_node(10);
315 auto node2 = make_node(20);
316 auto node3 = make_node(30);
317
321
322 EXPECT_EQ(tree1.size(), 1u);
323 EXPECT_EQ(tree2.size(), 2u);
324
326
327 EXPECT_EQ(tree1.size(), 2u);
328 EXPECT_EQ(tree2.size(), 1u);
329 EXPECT_NE(tree1.search(20), nullptr);
330 EXPECT_NE(tree1.search(30), nullptr);
331 EXPECT_NE(tree2.search(10), nullptr);
332}
333
334// ============================================================================
335// Custom Comparator Tests
336// ============================================================================
337
339{
340 auto nodes = make_nodes({10, 20, 30, 40, 50});
341
342 for (auto *node : nodes)
343 tree.insert(node);
344
345 EXPECT_EQ(tree.size(), 5u);
346
347 // All nodes should be findable
348 for (int key : {10, 20, 30, 40, 50})
349 EXPECT_NE(tree.search(key), nullptr);
350
351 EXPECT_TRUE(tree.verifyRedBlack());
352}
353
355{
356 // Functor comparator: compare by absolute value
357 struct AbsCompare
358 {
359 bool operator()(int a, int b) const { return std::abs(a) < std::abs(b); }
360 };
361
363
364 std::vector<RbNode<int>*> nodes;
365 auto make = [&nodes](int k) {
366 auto *n = new RbNode<int>(k);
367 nodes.push_back(n);
368 return n;
369 };
370
371 tree.insert(make(-5));
372 tree.insert(make(3));
373 tree.insert(make(-10));
374 tree.insert(make(7));
375
376 EXPECT_EQ(tree.size(), 4u);
377 EXPECT_NE(tree.search(-5), nullptr);
378 EXPECT_NE(tree.search(3), nullptr);
379
380 // With abs compare, -5 and 5 should be considered equal
381 EXPECT_EQ(tree.insert(make(5)), nullptr); // Duplicate by abs value
382
384
385 for (auto *n : nodes)
386 delete n;
387}
388
389// ============================================================================
390// String Key Tests
391// ============================================================================
392
394{
396 std::vector<RbNode<std::string>*> nodes;
397
398 auto make = [&nodes](const std::string& s) {
399 auto *n = new RbNode<std::string>(s);
400 nodes.push_back(n);
401 return n;
402 };
403
404 tree.insert(make("banana"));
405 tree.insert(make("apple"));
406 tree.insert(make("cherry"));
407 tree.insert(make("date"));
408
409 EXPECT_EQ(tree.size(), 4u);
410 EXPECT_NE(tree.search("apple"), nullptr);
411 EXPECT_NE(tree.search("banana"), nullptr);
412 EXPECT_EQ(tree.search("fig"), nullptr);
413
414 auto *removed = tree.remove("banana");
415 EXPECT_NE(removed, nullptr);
416 EXPECT_EQ(tree.search("banana"), nullptr);
417
419
420 for (auto *n : nodes)
421 delete n;
422}
423
424// ============================================================================
425// Insertion Patterns Tests
426// ============================================================================
427
429{
430 for (int i = 1; i <= 100; ++i)
431 tree.insert(make_node(i));
432
433 EXPECT_EQ(tree.size(), 100u);
434 EXPECT_TRUE(tree.verifyRedBlack());
435
436 for (int i = 1; i <= 100; ++i)
437 EXPECT_NE(tree.search(i), nullptr);
438}
439
441{
442 for (int i = 100; i >= 1; --i)
443 tree.insert(make_node(i));
444
445 EXPECT_EQ(tree.size(), 100u);
446 EXPECT_TRUE(tree.verifyRedBlack());
447
448 for (int i = 1; i <= 100; ++i)
449 EXPECT_NE(tree.search(i), nullptr);
450}
451
453{
454 // Insert pattern: 50, 25, 75, 12, 37, 62, 87, ...
455 int low = 0, high = 100;
456 int mid;
457 std::vector<int> inserted;
458
459 while (low <= high)
460 {
461 mid = (low + high) / 2;
462 tree.insert(make_node(mid));
463 inserted.push_back(mid);
464 low = mid + 1;
465 }
466
467 EXPECT_TRUE(tree.verifyRedBlack());
468
469 for (int key : inserted)
470 EXPECT_NE(tree.search(key), nullptr);
471}
472
473// ============================================================================
474// Stress Tests
475// ============================================================================
476
478{
479 TdRbTree<int> tree;
480 std::set<int> reference; // For comparison
481 std::vector<RbNode<int>*> all_nodes;
482
483 std::mt19937 rng(12345);
484 std::uniform_int_distribution<int> key_dist(1, 10000);
485 std::uniform_int_distribution<int> op_dist(0, 2); // 0: insert, 1: remove, 2: search
486
487 auto make = [&all_nodes](int k) {
488 auto *n = new RbNode<int>(k);
489 all_nodes.push_back(n);
490 return n;
491 };
492
493 const int NUM_OPS = 5000;
494
495 for (int i = 0; i < NUM_OPS; ++i)
496 {
497 int op = op_dist(rng);
498 int key = key_dist(rng);
499
500 if (op == 0) // Insert
501 {
502 auto *node = make(key);
503 bool tree_inserted = (tree.insert(node) != nullptr);
504 bool ref_inserted = reference.insert(key).second;
506 << "Insert mismatch at op " << i << " key " << key;
507 }
508 else if (op == 1) // Remove
509 {
510 bool tree_removed = (tree.remove(key) != nullptr);
511 bool ref_removed = (reference.erase(key) > 0);
513 << "Remove mismatch at op " << i << " key " << key;
514 }
515 else // Search
516 {
517 bool tree_found = (tree.search(key) != nullptr);
518 bool ref_found = (reference.count(key) > 0);
520 << "Search mismatch at op " << i << " key " << key;
521 }
522
523 // Verify RB properties periodically
524 if (i % 500 == 0)
525 EXPECT_TRUE(tree.verifyRedBlack()) << "RB violation at op " << i;
526 }
527
528 EXPECT_EQ(tree.size(), reference.size());
530
531 for (auto *n : all_nodes)
532 delete n;
533}
534
536{
537 TdRbTree<int> tree;
538 std::vector<RbNode<int>*> nodes;
539
540 const int N = 10000;
541
542 // Insert N unique keys
543 for (int i = 0; i < N; ++i)
544 {
545 auto *node = new RbNode<int>(i);
546 nodes.push_back(node);
547 EXPECT_NE(tree.insert(node), nullptr);
548 }
549
550 EXPECT_EQ(tree.size(), static_cast<size_t>(N));
552
553 // Verify all keys present
554 for (int i = 0; i < N; ++i)
555 EXPECT_NE(tree.search(i), nullptr);
556
557 // Remove half
558 for (int i = 0; i < N; i += 2)
559 {
560 EXPECT_NE(tree.remove(i), nullptr);
561 }
562
563 EXPECT_EQ(tree.size(), static_cast<size_t>(N / 2));
565
566 // Verify remaining keys
567 for (int i = 0; i < N; ++i)
568 {
569 if (i % 2 == 0)
570 EXPECT_EQ(tree.search(i), nullptr);
571 else
572 EXPECT_NE(tree.search(i), nullptr);
573 }
574
575 for (auto *n : nodes)
576 delete n;
577}
578
579// ============================================================================
580// Comparison with Bottom-Up Implementation
581// ============================================================================
582
584{
586 Rb_Tree<int> bu_tree; // Bottom-up implementation
587
588 std::vector<RbNode<int>*> td_nodes;
589 std::vector<Rb_Tree<int>::Node*> bu_nodes;
590
591 std::mt19937 rng(42);
592 std::uniform_int_distribution<int> dist(1, 1000);
593
594 const int N = 500;
595 std::vector<int> keys;
596
597 // Generate unique keys
598 std::set<int> key_set;
599 while (key_set.size() < static_cast<size_t>(N))
600 key_set.insert(dist(rng));
601
602 for (int k : key_set)
603 keys.push_back(k);
604
605 // Insert into both trees
606 for (int key : keys)
607 {
608 auto *td_node = new RbNode<int>(key);
609 td_nodes.push_back(td_node);
610 auto *bu_node = new Rb_Tree<int>::Node(key);
611 bu_nodes.push_back(bu_node);
612
613 bool td_ok = (td_tree.insert(td_node) != nullptr);
614 bool bu_ok = (bu_tree.insert(bu_node) != nullptr);
615
616 EXPECT_EQ(td_ok, bu_ok) << "Insert mismatch for key " << key;
617 }
618
620
621 // Shuffle keys for removal order
622 std::shuffle(keys.begin(), keys.end(), rng);
623
624 // Remove from both and compare
625 for (int key : keys)
626 {
627 bool td_found = (td_tree.search(key) != nullptr);
628 bool bu_found = (bu_tree.search(key) != nullptr);
629 EXPECT_EQ(td_found, bu_found) << "Search mismatch for key " << key;
630
631 bool td_removed = (td_tree.remove(key) != nullptr);
632 bool bu_removed = (bu_tree.remove(key) != nullptr);
633 EXPECT_EQ(td_removed, bu_removed) << "Remove mismatch for key " << key;
634
635 EXPECT_TRUE(td_tree.verifyRedBlack());
636 EXPECT_TRUE(bu_tree.verify());
637 }
638
641
642 for (auto *n : td_nodes) delete n;
643 for (auto *n : bu_nodes) delete n;
644}
645
646// ============================================================================
647// Edge Cases
648// ============================================================================
649
651{
652 Node *node = make_node(42);
653
654 EXPECT_NE(tree.insert(node), nullptr);
655 EXPECT_NE(tree.remove(42), nullptr);
656
657 // Reset node for reinsertion
658 LLINK(node) = RLINK(node) = Node::NullPtr;
659 COLOR(node) = RED;
660
661 EXPECT_NE(tree.insert(node), nullptr);
662 EXPECT_EQ(tree.size(), 1u);
663 EXPECT_NE(tree.search(42), nullptr);
664 EXPECT_TRUE(tree.verifyRedBlack());
665}
666
668{
669 auto nodes = make_nodes({-50, -25, 0, 25, 50});
670
671 for (auto *node : nodes)
672 tree.insert(node);
673
674 EXPECT_EQ(tree.size(), 5u);
675
676 for (int key : {-50, -25, 0, 25, 50})
677 EXPECT_NE(tree.search(key), nullptr);
678
679 EXPECT_TRUE(tree.verifyRedBlack());
680}
681
683{
684 auto nodes = make_nodes({
685 std::numeric_limits<int>::min(),
686 std::numeric_limits<int>::max(),
687 0
688 });
689
690 for (auto *node : nodes)
691 tree.insert(node);
692
693 EXPECT_NE(tree.search(std::numeric_limits<int>::min()), nullptr);
694 EXPECT_NE(tree.search(std::numeric_limits<int>::max()), nullptr);
695 EXPECT_NE(tree.search(0), nullptr);
696 EXPECT_TRUE(tree.verifyRedBlack());
697}
698
699// ============================================================================
700// Virtual Destructor Variant Tests
701// ============================================================================
702
704{
705 TdRbTreeVtl<int> tree;
706 std::vector<RbNodeVtl<int>*> nodes;
707
708 auto make = [&nodes](int k) {
709 auto *n = new RbNodeVtl<int>(k);
710 nodes.push_back(n);
711 return n;
712 };
713
714 tree.insert(make(30));
715 tree.insert(make(10));
716 tree.insert(make(50));
717 tree.insert(make(5));
718 tree.insert(make(15));
719
720 EXPECT_EQ(tree.size(), 5u);
721 EXPECT_NE(tree.search(30), nullptr);
722 EXPECT_NE(tree.search(5), nullptr);
723 EXPECT_EQ(tree.search(100), nullptr);
724
726
727 EXPECT_NE(tree.remove(10), nullptr);
728 EXPECT_EQ(tree.size(), 4u);
730
731 for (auto *n : nodes)
732 delete n;
733}
734
735// ============================================================================
736// Move Semantics Tests
737// ============================================================================
738
740{
742 std::vector<RbNode<int>*> nodes;
743
744 auto make = [&nodes](int k) {
745 auto *n = new RbNode<int>(k);
746 nodes.push_back(n);
747 return n;
748 };
749
750 tree1.insert(make(50));
751 tree1.insert(make(25));
752 tree1.insert(make(75));
753
754 EXPECT_EQ(tree1.size(), 3u);
755
756 TdRbTree<int> tree2(std::move(tree1));
757
758 EXPECT_EQ(tree2.size(), 3u);
759 EXPECT_TRUE(tree1.is_empty()); // NOLINT: testing moved-from state
760 EXPECT_EQ(tree1.size(), 0u); // NOLINT
761
762 EXPECT_NE(tree2.search(50), nullptr);
763 EXPECT_NE(tree2.search(25), nullptr);
764 EXPECT_NE(tree2.search(75), nullptr);
765 EXPECT_TRUE(tree2.verifyRedBlack());
766
767 for (auto *n : nodes)
768 delete n;
769}
770
772{
774 std::vector<RbNode<int>*> nodes;
775
776 auto make = [&nodes](int k) {
777 auto *n = new RbNode<int>(k);
778 nodes.push_back(n);
779 return n;
780 };
781
782 tree1.insert(make(10));
783 tree1.insert(make(20));
784 tree1.insert(make(30));
785
786 tree2.insert(make(100));
787
788 tree2 = std::move(tree1);
789
790 EXPECT_EQ(tree2.size(), 3u);
791 EXPECT_TRUE(tree1.is_empty()); // NOLINT
792
793 EXPECT_NE(tree2.search(10), nullptr);
794 EXPECT_NE(tree2.search(20), nullptr);
795 EXPECT_TRUE(tree2.verifyRedBlack());
796
797 for (auto *n : nodes)
798 delete n;
799}
800
801// ============================================================================
802// Insert Dup Tests
803// ============================================================================
804
806{
807 TdRbTree<int> tree;
808 std::vector<RbNode<int>*> nodes;
809
810 auto make = [&nodes](int k) {
811 auto *n = new RbNode<int>(k);
812 nodes.push_back(n);
813 return n;
814 };
815
816 EXPECT_NE(tree.insert_dup(make(42)), nullptr);
817 EXPECT_NE(tree.insert_dup(make(42)), nullptr);
818 EXPECT_NE(tree.insert_dup(make(42)), nullptr);
819
820 EXPECT_EQ(tree.size(), 3u);
822
823 // Search finds first occurrence
824 EXPECT_NE(tree.search(42), nullptr);
825
826 for (auto *n : nodes)
827 delete n;
828}
829
831{
832 TdRbTree<int> tree;
833 std::vector<RbNode<int>*> nodes;
834
835 auto make = [&nodes](int k) {
836 auto *n = new RbNode<int>(k);
837 nodes.push_back(n);
838 return n;
839 };
840
841 tree.insert_dup(make(50));
842 tree.insert_dup(make(25));
843 tree.insert_dup(make(75));
844 tree.insert_dup(make(25)); // duplicate
845 tree.insert_dup(make(50)); // duplicate
846 tree.insert_dup(make(25)); // duplicate
847
848 EXPECT_EQ(tree.size(), 6u);
850
851 for (auto *n : nodes)
852 delete n;
853}
854
855// ============================================================================
856// Search or Insert Tests
857// ============================================================================
858
860{
861 TdRbTree<int> tree;
862 std::vector<RbNode<int>*> nodes;
863
864 auto make = [&nodes](int k) {
865 auto *n = new RbNode<int>(k);
866 nodes.push_back(n);
867 return n;
868 };
869
870 auto *node1 = make(42);
871 auto *result = tree.search_or_insert(node1);
872
873 EXPECT_EQ(result, node1); // Inserted
874 EXPECT_EQ(tree.size(), 1u);
875
876 for (auto *n : nodes)
877 delete n;
878}
879
881{
882 TdRbTree<int> tree;
883 std::vector<RbNode<int>*> nodes;
884
885 auto make = [&nodes](int k) {
886 auto *n = new RbNode<int>(k);
887 nodes.push_back(n);
888 return n;
889 };
890
891 auto *node1 = make(42);
892 auto *node2 = make(42); // Same key
893
894 tree.insert(node1);
895 auto *result = tree.search_or_insert(node2);
896
897 EXPECT_EQ(result, node1); // Returns existing, not inserted
898 EXPECT_EQ(tree.size(), 1u);
899
900 for (auto *n : nodes)
901 delete n;
902}
903
904// ============================================================================
905// Iterator Tests
906// ============================================================================
907
909{
910 TdRbTree<int> tree;
911 std::vector<RbNode<int>*> nodes;
912
913 auto make = [&nodes](int k) {
914 auto *n = new RbNode<int>(k);
915 nodes.push_back(n);
916 return n;
917 };
918
919 // Insert in random order
920 tree.insert(make(50));
921 tree.insert(make(25));
922 tree.insert(make(75));
923 tree.insert(make(10));
924 tree.insert(make(30));
925 tree.insert(make(60));
926 tree.insert(make(90));
927
928 // Iterator should traverse in sorted order
929 std::vector<int> traversal;
930 for (TdRbTree<int>::Iterator it(tree); it.has_curr(); it.next())
931 traversal.push_back(KEY(it.get_curr()));
932
933 std::vector<int> expected = {10, 25, 30, 50, 60, 75, 90};
935
936 for (auto *n : nodes)
937 delete n;
938}
939
941{
942 TdRbTree<int> tree;
943
945 EXPECT_FALSE(it.has_curr());
946}
947
949{
950 TdRbTree<int> tree;
951 auto *node = new RbNode<int>(42);
952 tree.insert(node);
953
955 EXPECT_TRUE(it.has_curr());
956 EXPECT_EQ(KEY(it.get_curr()), 42);
957 it.next();
958 EXPECT_FALSE(it.has_curr());
959
960 delete node;
961}
962
963// ============================================================================
964// Main
965// ============================================================================
966
967int main(int argc, char **argv)
968{
969 ::testing::InitGoogleTest(&argc, argv);
970 return RUN_ALL_TESTS();
971}
972
High-level sorting functions for Aleph containers.
int main()
WeightedDigraph::Node Node
@ KEY
Definition btreepic.C:169
T & insert(const T &item)
Insert a new item by copy.
Definition htlist.H:1502
T remove()
Remove the first item of the list.
Definition htlist.H:1611
DynList & swap(DynList &l) noexcept
Swap this with l.
Definition htlist.H:1448
Node * insert_dup(Node *p) noexcept
Insert a node, allowing duplicates.
size_t size() const noexcept
Get number of nodes in tree (O(1))
Node * remove(const Key &key) noexcept
Remove and return node with given key.
Node * search_or_insert(Node *p) noexcept
Search for key or insert if not found.
Node * search(const Key &key) const noexcept
Search for a key in the tree.
NodeType< Key > Node
bool verifyRedBlack() const noexcept
Verify that tree satisfies all red-black properties.
Node * insert(Node *p) noexcept
Insert a node into the tree.
constexpr bool is_empty() const noexcept
Return true if list is empty.
Definition htlist.H:523
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
Top-down red-black tree with virtual destructor.
Declare RbNode type with 128-byte pool allocation.
Definition rbNode.H:109
std::vector< Node * > allocated_nodes
std::vector< Node * > make_nodes(const std::vector< int > &keys)
Tree::Node Node
Node * make_node(int key)
void TearDown() override
std::vector< Node * > make_nodes(const std::vector< int > &keys)
std::vector< Node * > allocated_nodes
#define TEST(name)
static mt19937 rng
#define N
Definition fib.C:294
DynArray< Graph::Node * > nodes
Definition graphpic.C:406
constexpr Node *& RLINK(Node *p) noexcept
Return the right tree of p.
constexpr Node *& LLINK(Node *p) noexcept
Return a pointer to left subtree.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
static long & low(typename GT::Node *p)
Internal helper: low-link value stored directly in NODE_COOKIE(p).
DynList< T > maps(const C &c, Op op)
Classic map operation.
#define COLOR(p)
Definition quadnode.H:58
#define RED
Red color constant (newly inserted nodes are red)
Definition rbNode.H:73
Red-black tree with nodes without virtual destructor.
TEST_F(TdRbTreeTest, EmptyTree)
Red-Black tree implementation (bottom-up balancing).
Top-down Red-Black tree implementation.