Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
avl-rb-rk.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
38/* Test for AVL and Red-Black trees with counters (select/position support) */
39
40# include <gtest/gtest.h>
41# include <random>
42# include <vector>
43# include <algorithm>
44
45# include <tpl_avlRk.H>
46# include <tpl_rbRk.H>
47
48using namespace std;
49using namespace Aleph;
50
51// Random generator
52static mt19937 rng(42);
53
54template <typename Tree>
55class RankTreeTest : public ::testing::Test
56{
57protected:
58 using Node = typename Tree::Node;
60 vector<int> keys;
61 static constexpr size_t N = 1000;
62
63 void SetUp() override
64 {
65 keys.resize(N);
66 iota(keys.begin(), keys.end(), 0);
67 shuffle(keys.begin(), keys.end(), rng);
68 }
69
70 void TearDown() override
71 {
72 while (not tree.is_empty())
73 {
74 auto p = tree.remove(tree.getRoot()->get_key());
75 delete p;
76 }
77 }
78
80 {
81 for (int k : keys)
82 {
83 auto p = new Node(k);
84 ASSERT_NE(tree.insert(p), nullptr);
85 }
86 }
87};
88
91
92// AVL Tree Tests
93
95{
96 insert_all();
97
98 EXPECT_EQ(tree.size(), N);
99 EXPECT_TRUE(tree.verify());
100}
101
103{
104 insert_all();
105
106 // After inserting 0..N-1, select(i) should return node with key i
107 for (size_t i = 0; i < N; ++i)
108 {
109 auto p = tree.select(i);
110 ASSERT_NE(p, nullptr);
111 EXPECT_EQ(p->get_key(), static_cast<int>(i));
112 }
113}
114
116{
117 insert_all();
118
119 // For each key k, position(k) should return k
120 for (size_t i = 0; i < N; ++i)
121 {
122 auto [pos, node] = tree.position(static_cast<int>(i));
123 EXPECT_EQ(pos, static_cast<long>(i));
124 ASSERT_NE(node, nullptr);
125 EXPECT_EQ(node->get_key(), static_cast<int>(i));
126 }
127}
128
130{
131 insert_all();
132
133 // Key not in tree should return -1
134 auto [pos, node] = tree.position(static_cast<int>(N + 100));
135 EXPECT_EQ(pos, -1);
136}
137
139{
140 insert_all();
141
142 shuffle(keys.begin(), keys.end(), rng);
143
144 for (size_t i = 0; i < N / 2; ++i)
145 {
146 auto p = tree.remove(keys[i]);
147 ASSERT_NE(p, nullptr);
148 delete p;
149 EXPECT_TRUE(tree.verify());
150 }
151
152 EXPECT_EQ(tree.size(), N - N / 2);
153}
154
156{
157 insert_all();
158
159 // Remove even keys
160 for (int k = 0; k < static_cast<int>(N); k += 2)
161 {
162 auto p = tree.remove(k);
163 delete p;
164 }
165
166 EXPECT_EQ(tree.size(), N / 2);
167
168 // Now select should return odd keys in order
169 for (size_t i = 0; i < N / 2; ++i)
170 {
171 auto p = tree.select(i);
172 ASSERT_NE(p, nullptr);
173 EXPECT_EQ(p->get_key(), static_cast<int>(2 * i + 1));
174 }
175}
176
177// Red-Black Tree Tests
178
180{
181 insert_all();
182
183 EXPECT_EQ(tree.size(), N);
184 EXPECT_TRUE(tree.verify());
185}
186
188{
189 insert_all();
190
191 // After inserting 0..N-1, select(i) should return node with key i
192 for (size_t i = 0; i < N; ++i)
193 {
194 auto p = tree.select(i);
195 ASSERT_NE(p, nullptr);
196 EXPECT_EQ(p->get_key(), static_cast<int>(i));
197 }
198}
199
201{
202 insert_all();
203
204 // For each key k, position(k) should return k
205 for (size_t i = 0; i < N; ++i)
206 {
207 auto [pos, node] = tree.position(static_cast<int>(i));
208 EXPECT_EQ(pos, static_cast<long>(i));
209 ASSERT_NE(node, nullptr);
210 EXPECT_EQ(node->get_key(), static_cast<int>(i));
211 }
212}
213
215{
216 insert_all();
217
218 // Key not in tree should return -1
219 auto [pos, node] = tree.position(static_cast<int>(N + 100));
220 EXPECT_EQ(pos, -1);
221}
222
224{
225 insert_all();
226
227 shuffle(keys.begin(), keys.end(), rng);
228
229 for (size_t i = 0; i < N / 2; ++i)
230 {
231 auto p = tree.remove(keys[i]);
232 ASSERT_NE(p, nullptr);
233 delete p;
234 EXPECT_TRUE(tree.verify());
235 }
236
237 EXPECT_EQ(tree.size(), N - N / 2);
238}
239
241{
242 insert_all();
243
244 // Remove even keys
245 for (int k = 0; k < static_cast<int>(N); k += 2)
246 {
247 auto p = tree.remove(k);
248 delete p;
249 }
250
251 EXPECT_EQ(tree.size(), N / 2);
252
253 // Now select should return odd keys in order
254 for (size_t i = 0; i < N / 2; ++i)
255 {
256 auto p = tree.select(i);
257 ASSERT_NE(p, nullptr);
258 EXPECT_EQ(p->get_key(), static_cast<int>(2 * i + 1));
259 }
260}
261
262// Combined stress test
263
265{
266 Avl_Tree_Rk<int> tree;
268 const size_t N = 5000;
269
270 // Insert
271 for (size_t i = 0; i < N; ++i)
272 {
273 auto p = new Node(static_cast<int>(i));
274 ASSERT_NE(tree.insert(p), nullptr);
275 }
276
277 EXPECT_TRUE(tree.verify());
278 EXPECT_EQ(tree.size(), N);
279
280 // Random selects
282 for (int i = 0; i < 100; ++i)
283 {
284 size_t pos = dist(rng);
285 auto p = tree.select(pos);
286 EXPECT_EQ(p->get_key(), static_cast<int>(pos));
287 }
288
289 // Random positions
290 for (int i = 0; i < 100; ++i)
291 {
292 int key = static_cast<int>(dist(rng));
293 auto [pos, node] = tree.position(key);
294 EXPECT_EQ(pos, key);
295 }
296
297 // Remove half
298 for (int i = 0; i < static_cast<int>(N); i += 2)
299 delete tree.remove(i);
300
301 EXPECT_TRUE(tree.verify());
302 EXPECT_EQ(tree.size(), N / 2);
303
304 // Cleanup
305 while (not tree.is_empty())
306 delete tree.remove(tree.getRoot()->get_key());
307}
308
310{
311 Rb_Tree_Rk<int> tree;
313 const size_t N = 5000;
314
315 // Insert
316 for (size_t i = 0; i < N; ++i)
317 {
318 auto p = new Node(static_cast<int>(i));
319 ASSERT_NE(tree.insert(p), nullptr);
320 }
321
322 EXPECT_TRUE(tree.verify());
323 EXPECT_EQ(tree.size(), N);
324
325 // Random selects
327 for (int i = 0; i < 100; ++i)
328 {
329 size_t pos = dist(rng);
330 auto p = tree.select(pos);
331 EXPECT_EQ(p->get_key(), static_cast<int>(pos));
332 }
333
334 // Random positions
335 for (int i = 0; i < 100; ++i)
336 {
337 int key = static_cast<int>(dist(rng));
338 auto [pos, node] = tree.position(key);
339 EXPECT_EQ(pos, key);
340 }
341
342 // Remove half
343 for (int i = 0; i < static_cast<int>(N); i += 2)
344 delete tree.remove(i);
345
346 EXPECT_TRUE(tree.verify());
347 EXPECT_EQ(tree.size(), N / 2);
348
349 // Cleanup
350 while (not tree.is_empty())
351 delete tree.remove(tree.getRoot()->get_key());
352}
353
354// Test empty tree edge cases
355
357{
358 Avl_Tree_Rk<int> tree;
359
360 EXPECT_TRUE(tree.is_empty());
361 EXPECT_EQ(tree.size(), 0);
362 EXPECT_EQ(tree.search(42), nullptr);
363 EXPECT_EQ(tree.remove(42), nullptr);
364
365 auto [pos, node] = tree.position(42);
366 EXPECT_EQ(pos, -1);
367}
368
370{
371 Rb_Tree_Rk<int> tree;
372
373 EXPECT_TRUE(tree.is_empty());
374 EXPECT_EQ(tree.size(), 0);
375 EXPECT_EQ(tree.search(42), nullptr);
376 EXPECT_EQ(tree.remove(42), nullptr);
377
378 auto [pos, node] = tree.position(42);
379 EXPECT_EQ(pos, -1);
380}
381
382// Test single element
383
385{
386 Avl_Tree_Rk<int> tree;
388
389 auto p = new Node(42);
390 ASSERT_NE(tree.insert(p), nullptr);
391
392 EXPECT_EQ(tree.size(), 1);
393 EXPECT_TRUE(tree.verify());
394
395 auto selected = tree.select(0);
396 EXPECT_EQ(selected->get_key(), 42);
397
398 auto [pos, node] = tree.position(42);
399 EXPECT_EQ(pos, 0);
400 EXPECT_EQ(node->get_key(), 42);
401
402 delete tree.remove(42);
403 EXPECT_TRUE(tree.is_empty());
404}
405
407{
408 Rb_Tree_Rk<int> tree;
410
411 auto p = new Node(42);
412 ASSERT_NE(tree.insert(p), nullptr);
413
414 EXPECT_EQ(tree.size(), 1);
415 EXPECT_TRUE(tree.verify());
416
417 auto selected = tree.select(0);
418 EXPECT_EQ(selected->get_key(), 42);
419
420 auto [pos, node] = tree.position(42);
421 EXPECT_EQ(pos, 0);
422 EXPECT_EQ(node->get_key(), 42);
423
424 delete tree.remove(42);
425 EXPECT_TRUE(tree.is_empty());
426}
427
428// Test search_or_insert
429
431{
432 Avl_Tree_Rk<int> tree;
434
435 auto p1 = new Node(42);
436 auto result1 = tree.search_or_insert(p1);
437 EXPECT_EQ(result1, p1);
438 EXPECT_EQ(tree.size(), 1);
439
440 auto p2 = new Node(42);
441 auto result2 = tree.search_or_insert(p2);
442 EXPECT_EQ(result2, p1); // Should return existing node
443 EXPECT_EQ(tree.size(), 1); // Size should not change
444
445 delete p2; // Delete the non-inserted node
446 delete tree.remove(42);
447}
448
450{
451 Rb_Tree_Rk<int> tree;
453
454 auto p1 = new Node(42);
455 auto result1 = tree.search_or_insert(p1);
456 EXPECT_EQ(result1, p1);
457 EXPECT_EQ(tree.size(), 1);
458
459 auto p2 = new Node(42);
460 auto result2 = tree.search_or_insert(p2);
461 EXPECT_EQ(result2, p1); // Should return existing node
462 EXPECT_EQ(tree.size(), 1); // Size should not change
463
464 delete p2; // Delete the non-inserted node
465 delete tree.remove(42);
466}
467
468// Test insert_dup
469
471{
472 Avl_Tree_Rk<int> tree;
474
475 for (int i = 0; i < 10; ++i)
476 {
477 auto p = new Node(42);
478 ASSERT_NE(tree.insert_dup(p), nullptr);
479 }
480
481 EXPECT_EQ(tree.size(), 10);
482 EXPECT_TRUE(tree.verify());
483
484 // All should have key 42
485 for (size_t i = 0; i < 10; ++i)
486 EXPECT_EQ(tree.select(i)->get_key(), 42);
487
488 while (not tree.is_empty())
489 delete tree.remove(42);
490}
491
493{
494 Rb_Tree_Rk<int> tree;
496
497 for (int i = 0; i < 10; ++i)
498 {
499 auto p = new Node(42);
500 ASSERT_NE(tree.insert_dup(p), nullptr);
501 }
502
503 EXPECT_EQ(tree.size(), 10);
504 EXPECT_TRUE(tree.verify());
505
506 // All should have key 42
507 for (size_t i = 0; i < 10; ++i)
508 EXPECT_EQ(tree.select(i)->get_key(), 42);
509
510 while (not tree.is_empty())
511 delete tree.remove(42);
512}
513
514// ==============================================================
515// Join/Split tests
516// ==============================================================
517
518// Helper to cleanup a tree
519template <typename Tree>
520void destroy_tree(Tree & tree)
521{
522 while (not tree.is_empty())
523 delete tree.remove(tree.getRoot()->get_key());
524}
525
526// AVL Join Tests
527
529{
532
533 // Insert 0-49 in t1, 50-99 in t2
534 for (int i = 0; i < 50; ++i)
535 ASSERT_NE(t1.insert(new Node(i)), nullptr);
536 for (int i = 50; i < 100; ++i)
537 ASSERT_NE(t2.insert(new Node(i)), nullptr);
538
539 EXPECT_EQ(t1.size(), 50);
540 EXPECT_EQ(t2.size(), 50);
541 EXPECT_TRUE(t1.verify());
542 EXPECT_TRUE(t2.verify());
543
544 t1.join_exclusive(t2);
545
546 EXPECT_EQ(t1.size(), 100);
548 EXPECT_TRUE(t1.verify());
549
550 // Check all elements are present and in order
551 for (int i = 0; i < 100; ++i)
552 {
553 auto p = t1.select(i);
554 EXPECT_EQ(p->get_key(), i);
555 }
556
558}
559
561{
564
565 for (int i = 0; i < 50; ++i)
566 ASSERT_NE(t2.insert(new Node(i)), nullptr);
567
568 t1.join_exclusive(t2);
569
570 EXPECT_EQ(t1.size(), 50);
572 EXPECT_TRUE(t1.verify());
573
575}
576
578{
581
582 for (int i = 0; i < 50; ++i)
583 ASSERT_NE(t1.insert(new Node(i)), nullptr);
584
585 t1.join_exclusive(t2);
586
587 EXPECT_EQ(t1.size(), 50);
589 EXPECT_TRUE(t1.verify());
590
592}
593
595{
596 Avl_Tree_Rk<int> tree, t1, t2;
598
599 for (int i = 0; i < 100; ++i)
600 ASSERT_NE(tree.insert(new Node(i)), nullptr);
601
602 auto pivot = tree.split_key(50, t1, t2);
603
604 EXPECT_NE(pivot, nullptr);
605 EXPECT_EQ(pivot->get_key(), 50);
606 EXPECT_TRUE(tree.is_empty());
607 EXPECT_TRUE(t1.verify());
608 EXPECT_TRUE(t2.verify());
609
610 EXPECT_EQ(t1.size(), 50); // 0-49
611 EXPECT_EQ(t2.size(), 49); // 51-99
612
613 // Check t1 contains 0-49
614 for (int i = 0; i < 50; ++i)
615 EXPECT_EQ(t1.select(i)->get_key(), i);
616
617 // Check t2 contains 51-99
618 for (int i = 0; i < 49; ++i)
619 EXPECT_EQ(t2.select(i)->get_key(), i + 51);
620
621 delete pivot;
624}
625
627{
628 Avl_Tree_Rk<int> tree, t1, t2;
630
631 // Insert even numbers only
632 for (int i = 0; i < 100; i += 2)
633 ASSERT_NE(tree.insert(new Node(i)), nullptr);
634
635 // Split by odd number (not in tree)
636 auto pivot = tree.split_key(51, t1, t2);
637
638 EXPECT_EQ(pivot, nullptr);
639 EXPECT_TRUE(tree.is_empty());
640 EXPECT_TRUE(t1.verify());
641 EXPECT_TRUE(t2.verify());
642
643 // t1 should have 0, 2, 4, ..., 50 (26 elements)
644 EXPECT_EQ(t1.size(), 26);
645 // t2 should have 52, 54, ..., 98 (24 elements)
646 EXPECT_EQ(t2.size(), 24);
647
650}
651
653{
654 Avl_Tree_Rk<int> tree, t1, t2;
656
657 for (int i = 0; i < 100; ++i)
658 ASSERT_NE(tree.insert(new Node(i)), nullptr);
659
660 tree.split_pos(30, t1, t2);
661
662 EXPECT_TRUE(tree.is_empty());
663 EXPECT_TRUE(t1.verify());
664 EXPECT_TRUE(t2.verify());
665
666 EXPECT_EQ(t1.size(), 30); // positions 0-29
667 EXPECT_EQ(t2.size(), 70); // positions 30-99
668
669 // Check t1 contains 0-29
670 for (int i = 0; i < 30; ++i)
671 EXPECT_EQ(t1.select(i)->get_key(), i);
672
673 // Check t2 contains 30-99
674 for (int i = 0; i < 70; ++i)
675 EXPECT_EQ(t2.select(i)->get_key(), i + 30);
676
679}
680
682{
683 Avl_Tree_Rk<int> tree, t1, t2;
685
686 for (int i = 0; i < 50; ++i)
687 ASSERT_NE(tree.insert(new Node(i)), nullptr);
688
689 tree.split_pos(0, t1, t2);
690
691 EXPECT_TRUE(tree.is_empty());
693 EXPECT_EQ(t2.size(), 50);
694 EXPECT_TRUE(t2.verify());
695
697}
698
700{
701 Avl_Tree_Rk<int> tree, t1, t2;
703
704 for (int i = 0; i < 50; ++i)
705 ASSERT_NE(tree.insert(new Node(i)), nullptr);
706
707 tree.split_pos(50, t1, t2);
708
709 EXPECT_TRUE(tree.is_empty());
710 EXPECT_EQ(t1.size(), 50);
712 EXPECT_TRUE(t1.verify());
713
715}
716
718{
721
722 for (int i = 0; i < 50; ++i)
723 ASSERT_NE(t1.insert(new Node(i)), nullptr);
724 for (int i = 50; i < 100; ++i)
725 ASSERT_NE(t2.insert(new Node(i)), nullptr);
726
727 t1.join_exclusive(t2);
728 EXPECT_EQ(t1.size(), 100);
729 EXPECT_TRUE(t1.verify());
730
731 auto pivot = t1.split_key(50, t3, t4);
732 EXPECT_EQ(pivot->get_key(), 50);
733 EXPECT_EQ(t3.size(), 50);
734 EXPECT_EQ(t4.size(), 49);
735 EXPECT_TRUE(t3.verify());
736 EXPECT_TRUE(t4.verify());
737
738 delete pivot;
741}
742
743// Red-Black Join Tests
744
746{
749
750 for (int i = 0; i < 50; ++i)
751 ASSERT_NE(t1.insert(new Node(i)), nullptr);
752 for (int i = 50; i < 100; ++i)
753 ASSERT_NE(t2.insert(new Node(i)), nullptr);
754
755 EXPECT_EQ(t1.size(), 50);
756 EXPECT_EQ(t2.size(), 50);
757 EXPECT_TRUE(t1.verify());
758 EXPECT_TRUE(t2.verify());
759
760 t1.join_exclusive(t2);
761
762 EXPECT_EQ(t1.size(), 100);
764 EXPECT_TRUE(t1.verify());
765
766 for (int i = 0; i < 100; ++i)
767 {
768 auto p = t1.select(i);
769 EXPECT_EQ(p->get_key(), i);
770 }
771
773}
774
776{
779
780 for (int i = 0; i < 50; ++i)
781 ASSERT_NE(t2.insert(new Node(i)), nullptr);
782
783 t1.join_exclusive(t2);
784
785 EXPECT_EQ(t1.size(), 50);
787 EXPECT_TRUE(t1.verify());
788
790}
791
793{
796
797 for (int i = 0; i < 50; ++i)
798 ASSERT_NE(t1.insert(new Node(i)), nullptr);
799
800 t1.join_exclusive(t2);
801
802 EXPECT_EQ(t1.size(), 50);
804 EXPECT_TRUE(t1.verify());
805
807}
808
810{
811 Rb_Tree_Rk<int> tree, t1, t2;
813
814 for (int i = 0; i < 100; ++i)
815 ASSERT_NE(tree.insert(new Node(i)), nullptr);
816
817 auto pivot = tree.split_key(50, t1, t2);
818
819 EXPECT_NE(pivot, nullptr);
820 EXPECT_EQ(pivot->get_key(), 50);
821 EXPECT_TRUE(tree.is_empty());
822 EXPECT_TRUE(t1.verify());
823 EXPECT_TRUE(t2.verify());
824
825 EXPECT_EQ(t1.size(), 50); // 0-49
826 EXPECT_EQ(t2.size(), 49); // 51-99
827
828 for (int i = 0; i < 50; ++i)
829 EXPECT_EQ(t1.select(i)->get_key(), i);
830
831 for (int i = 0; i < 49; ++i)
832 EXPECT_EQ(t2.select(i)->get_key(), i + 51);
833
834 delete pivot;
837}
838
840{
841 Rb_Tree_Rk<int> tree, t1, t2;
843
844 for (int i = 0; i < 100; i += 2)
845 ASSERT_NE(tree.insert(new Node(i)), nullptr);
846
847 auto pivot = tree.split_key(51, t1, t2);
848
849 EXPECT_EQ(pivot, nullptr);
850 EXPECT_TRUE(tree.is_empty());
851 EXPECT_TRUE(t1.verify());
852 EXPECT_TRUE(t2.verify());
853
854 EXPECT_EQ(t1.size(), 26);
855 EXPECT_EQ(t2.size(), 24);
856
859}
860
862{
863 Rb_Tree_Rk<int> tree, t1, t2;
865
866 for (int i = 0; i < 100; ++i)
867 ASSERT_NE(tree.insert(new Node(i)), nullptr);
868
869 tree.split_pos(30, t1, t2);
870
871 EXPECT_TRUE(tree.is_empty());
872 EXPECT_TRUE(t1.verify());
873 EXPECT_TRUE(t2.verify());
874
875 EXPECT_EQ(t1.size(), 30);
876 EXPECT_EQ(t2.size(), 70);
877
878 for (int i = 0; i < 30; ++i)
879 EXPECT_EQ(t1.select(i)->get_key(), i);
880
881 for (int i = 0; i < 70; ++i)
882 EXPECT_EQ(t2.select(i)->get_key(), i + 30);
883
886}
887
889{
890 Rb_Tree_Rk<int> tree, t1, t2;
892
893 for (int i = 0; i < 50; ++i)
894 ASSERT_NE(tree.insert(new Node(i)), nullptr);
895
896 tree.split_pos(0, t1, t2);
897
898 EXPECT_TRUE(tree.is_empty());
900 EXPECT_EQ(t2.size(), 50);
901 EXPECT_TRUE(t2.verify());
902
904}
905
907{
908 Rb_Tree_Rk<int> tree, t1, t2;
910
911 for (int i = 0; i < 50; ++i)
912 ASSERT_NE(tree.insert(new Node(i)), nullptr);
913
914 tree.split_pos(50, t1, t2);
915
916 EXPECT_TRUE(tree.is_empty());
917 EXPECT_EQ(t1.size(), 50);
919 EXPECT_TRUE(t1.verify());
920
922}
923
925{
928
929 for (int i = 0; i < 50; ++i)
930 ASSERT_NE(t1.insert(new Node(i)), nullptr);
931 for (int i = 50; i < 100; ++i)
932 ASSERT_NE(t2.insert(new Node(i)), nullptr);
933
934 t1.join_exclusive(t2);
935 EXPECT_EQ(t1.size(), 100);
936 EXPECT_TRUE(t1.verify());
937
938 auto pivot = t1.split_key(50, t3, t4);
939 EXPECT_EQ(pivot->get_key(), 50);
940 EXPECT_EQ(t3.size(), 50);
941 EXPECT_EQ(t4.size(), 49);
942 EXPECT_TRUE(t3.verify());
943 EXPECT_TRUE(t4.verify());
944
945 delete pivot;
948}
949
950// Large scale join/split stress tests
951
953{
956 const int N = 1000;
957
958 for (int i = 0; i < N / 2; ++i)
959 ASSERT_NE(t1.insert(new Node(i)), nullptr);
960 for (int i = N / 2; i < N; ++i)
961 ASSERT_NE(t2.insert(new Node(i)), nullptr);
962
963 t1.join_exclusive(t2);
964 EXPECT_EQ(t1.size(), N);
965 EXPECT_TRUE(t1.verify());
966
967 t1.split_pos(N / 3, t3, t4);
968 EXPECT_EQ(t3.size(), N / 3);
969 EXPECT_EQ(t4.size(), N - N / 3);
970 EXPECT_TRUE(t3.verify());
971 EXPECT_TRUE(t4.verify());
972
973 t3.join_exclusive(t4);
974 EXPECT_EQ(t3.size(), N);
975 EXPECT_TRUE(t3.verify());
976
978}
979
981{
984 const int N = 1000;
985
986 for (int i = 0; i < N / 2; ++i)
987 ASSERT_NE(t1.insert(new Node(i)), nullptr);
988 for (int i = N / 2; i < N; ++i)
989 ASSERT_NE(t2.insert(new Node(i)), nullptr);
990
991 t1.join_exclusive(t2);
992 EXPECT_EQ(t1.size(), N);
993 EXPECT_TRUE(t1.verify());
994
995 t1.split_pos(N / 3, t3, t4);
996 EXPECT_EQ(t3.size(), N / 3);
997 EXPECT_EQ(t4.size(), N - N / 3);
998 EXPECT_TRUE(t3.verify());
999 EXPECT_TRUE(t4.verify());
1000
1001 t3.join_exclusive(t4);
1002 EXPECT_EQ(t3.size(), N);
1003 EXPECT_TRUE(t3.verify());
1004
1006}
1007
1008// Test split_key_dup
1009
1011{
1012 Avl_Tree_Rk<int> tree, t1, t2;
1014
1015 // Insert with duplicates: several 50s
1016 for (int i = 0; i < 50; ++i)
1017 ASSERT_NE(tree.insert_dup(new Node(i)), nullptr);
1018 for (int i = 0; i < 10; ++i)
1019 ASSERT_NE(tree.insert_dup(new Node(50)), nullptr);
1020 for (int i = 51; i < 100; ++i)
1021 ASSERT_NE(tree.insert_dup(new Node(i)), nullptr);
1022
1023 EXPECT_EQ(tree.size(), 109); // 50 + 10 + 49
1024
1025 tree.split_key_dup(50, t1, t2);
1026
1027 EXPECT_TRUE(tree.is_empty());
1028 EXPECT_TRUE(t1.verify());
1029 EXPECT_TRUE(t2.verify());
1030
1031 // t1 should have keys <= 50 (0-49 + 10 duplicates of 50 = 50 + 10 = 60)
1032 EXPECT_EQ(t1.size(), 60);
1033 // t2 should have keys > 50 (51-99 = 49)
1034 EXPECT_EQ(t2.size(), 49);
1035
1038}
1039
1041{
1042 Rb_Tree_Rk<int> tree, t1, t2;
1044
1045 for (int i = 0; i < 50; ++i)
1046 ASSERT_NE(tree.insert_dup(new Node(i)), nullptr);
1047 for (int i = 0; i < 10; ++i)
1048 ASSERT_NE(tree.insert_dup(new Node(50)), nullptr);
1049 for (int i = 51; i < 100; ++i)
1050 ASSERT_NE(tree.insert_dup(new Node(i)), nullptr);
1051
1052 EXPECT_EQ(tree.size(), 109);
1053
1054 tree.split_key_dup(50, t1, t2);
1055
1056 EXPECT_TRUE(tree.is_empty());
1057 EXPECT_TRUE(t1.verify());
1058 EXPECT_TRUE(t2.verify());
1059
1060 // t1 should have keys <= 50 (0-49 + 10 duplicates of 50 = 50 + 10 = 60)
1061 EXPECT_EQ(t1.size(), 60);
1062 EXPECT_EQ(t2.size(), 49);
1063
1066}
1067
1068int main(int argc, char **argv)
1069{
1070 ::testing::InitGoogleTest(&argc, argv);
1071 return RUN_ALL_TESTS();
1072}
int main()
TEST_F(AvlRkTest, InsertAndVerify)
Definition avl-rb-rk.cc:94
void destroy_tree(Tree &tree)
Definition avl-rb-rk.cc:520
WeightedDigraph::Node Node
T & insert(const T &item)
Insert a new item by copy.
Definition htlist.H:1502
Node * insert(Node *p) noexcept
Insert the node pointed by p in the tree.
Definition tpl_avlRk.H:568
constexpr Node *& getRoot() noexcept
Return a modifiable reference to tree's root.
Definition tpl_avlRk.H:544
Node * select(const size_t i) const
Return the i-th node in order sense.
Definition tpl_avlRk.H:703
Node * search_or_insert(Node *p) noexcept
Search or insert a key.
Definition tpl_avlRk.H:598
Node * remove(const Key &key) noexcept
Remove from tree the node containing key.
Definition tpl_avlRk.H:642
size_t size() const noexcept
Return the number of nodes in the tree.
Definition tpl_avlRk.H:550
constexpr bool is_empty() const noexcept
Return true if tree is empty.
Definition tpl_avlRk.H:553
Node * insert_dup(Node *p) noexcept
Insert the node p without testing for key duplicity.
Definition tpl_avlRk.H:622
void split_key_dup(const Key &key, Gen_Avl_Tree_Rk &t1, Gen_Avl_Tree_Rk &t2) noexcept
Split tree by key including duplicates.
Definition tpl_avlRk.H:1297
Node * split_key(const Key &key, Gen_Avl_Tree_Rk &t1, Gen_Avl_Tree_Rk &t2) noexcept
Split tree by key.
Definition tpl_avlRk.H:1247
void split_pos(const size_t pos, Gen_Avl_Tree_Rk &t1, Gen_Avl_Tree_Rk &t2) noexcept
Split tree by inorder position.
Definition tpl_avlRk.H:1341
bool verify() const noexcept
Return true if the tree is a valid AVL tree with correct counters.
Definition tpl_avlRk.H:740
Node * search(const Key &key) const noexcept
Search a node containing key; if found, then a pointer to the node containing it is returned; otherwi...
Definition tpl_avlRk.H:557
std::pair< long, Node * > position(const Key &key) const noexcept
Compute the inorder position of a key.
Definition tpl_avlRk.H:714
bool is_empty() const noexcept
Return true if the tree is empty.
Node * remove(const Key &key) noexcept
Remove a key from the tree.
NodeType< Key > Node
Node * insert(Node *p) noexcept
Insert a node in the tree.
Node *& getRoot() noexcept
Return the tree's root.
Node * split_key(const Key &key, Gen_Rb_Tree_Rk &t1, Gen_Rb_Tree_Rk &t2) noexcept
Split tree by key.
Definition tpl_rbRk.H:1375
size_t size() const noexcept
Definition tpl_rbRk.H:506
Node * select(const size_t i) const
Return the i-th node in order sense.
Definition tpl_rbRk.H:640
Node * insert_dup(Node *p)
Definition tpl_rbRk.H:560
bool is_empty() const noexcept
Definition tpl_rbRk.H:504
Node * search(const Key &key)
Definition tpl_rbRk.H:496
bool verify() const
Definition tpl_rbRk.H:581
void split_pos(size_t pos, Gen_Rb_Tree_Rk &t1, Gen_Rb_Tree_Rk &t2) noexcept
Split tree by inorder position.
Definition tpl_rbRk.H:1465
Node * search_or_insert(Node *p)
Definition tpl_rbRk.H:534
Node * insert(Node *p)
Definition tpl_rbRk.H:508
void split_key_dup(const Key &key, Gen_Rb_Tree_Rk &t1, Gen_Rb_Tree_Rk &t2) noexcept
Split tree by key including duplicates.
Definition tpl_rbRk.H:1423
Node *& getRoot() noexcept
Definition tpl_rbRk.H:502
Node * remove(const Key &key)
Definition tpl_rbRk.H:583
std::pair< long, Node * > position(const Key &key) const noexcept
Compute the inorder position of a key.
Definition tpl_rbRk.H:651
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
void insert_all()
Definition avl-rb-rk.cc:79
typename Tree::Node Node
Definition avl-rb-rk.cc:58
void SetUp() override
Definition avl-rb-rk.cc:63
void TearDown() override
Definition avl-rb-rk.cc:70
static constexpr size_t N
Definition avl-rb-rk.cc:61
vector< int > keys
Definition avl-rb-rk.cc:60
#define TEST(name)
static mt19937 rng
#define N
Definition fib.C:294
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
auto shuffle(const C< T > &c)
Randomly shuffle a sequence.
DynList< T > maps(const C &c, Op op)
Classic map operation.
STL namespace.
AVL binary search tree with nodes without virtual destructor and with subtree counters for select/pos...
Definition tpl_avlRk.H:1424
Red-Black binary search tree with nodes without virtual destructor and with subtree counters for sele...
Definition tpl_rbRk.H:1544
AVL tree with rank (order statistics).
Red-Black tree with rank (order statistics).