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 <numeric>
42# include <random>
43# include <vector>
44# include <algorithm>
45
46# include <tpl_avlRk.H>
47# include <tpl_rbRk.H>
48
49using namespace std;
50using namespace Aleph;
51
52// Random generator
53static mt19937 rng(42);
54
55template <typename Tree>
56class RankTreeTest : public ::testing::Test
57{
58protected:
59 using Node = typename Tree::Node;
61 vector<int> keys;
62 static constexpr size_t N = 1000;
63
64 void SetUp() override
65 {
66 keys.resize(N);
67 iota(keys.begin(), keys.end(), 0);
68 shuffle(keys.begin(), keys.end(), rng);
69 }
70
71 void TearDown() override
72 {
73 while (not tree.is_empty())
74 {
75 auto p = tree.remove(tree.getRoot()->get_key());
76 delete p;
77 }
78 }
79
81 {
82 for (int k : keys)
83 {
84 auto p = new Node(k);
85 ASSERT_NE(tree.insert(p), nullptr);
86 }
87 }
88};
89
92
93// AVL Tree Tests
94
96{
97 insert_all();
98
99 EXPECT_EQ(tree.size(), N);
100 EXPECT_TRUE(tree.verify());
101}
102
104{
105 insert_all();
106
107 // After inserting 0..N-1, select(i) should return node with key i
108 for (size_t i = 0; i < N; ++i)
109 {
110 auto p = tree.select(i);
111 ASSERT_NE(p, nullptr);
112 EXPECT_EQ(p->get_key(), static_cast<int>(i));
113 }
114}
115
117{
118 insert_all();
119
120 // For each key k, position(k) should return k
121 for (size_t i = 0; i < N; ++i)
122 {
123 auto [pos, node] = tree.position(static_cast<int>(i));
124 EXPECT_EQ(pos, static_cast<long>(i));
125 ASSERT_NE(node, nullptr);
126 EXPECT_EQ(node->get_key(), static_cast<int>(i));
127 }
128}
129
131{
132 insert_all();
133
134 // Key not in tree should return -1
135 auto [pos, node] = tree.position(static_cast<int>(N + 100));
136 EXPECT_EQ(pos, -1);
137}
138
140{
141 insert_all();
142
143 shuffle(keys.begin(), keys.end(), rng);
144
145 for (size_t i = 0; i < N / 2; ++i)
146 {
147 auto p = tree.remove(keys[i]);
148 ASSERT_NE(p, nullptr);
149 delete p;
150 EXPECT_TRUE(tree.verify());
151 }
152
153 EXPECT_EQ(tree.size(), N - N / 2);
154}
155
157{
158 insert_all();
159
160 // Remove even keys
161 for (int k = 0; k < static_cast<int>(N); k += 2)
162 {
163 auto p = tree.remove(k);
164 delete p;
165 }
166
167 EXPECT_EQ(tree.size(), N / 2);
168
169 // Now select should return odd keys in order
170 for (size_t i = 0; i < N / 2; ++i)
171 {
172 auto p = tree.select(i);
173 ASSERT_NE(p, nullptr);
174 EXPECT_EQ(p->get_key(), static_cast<int>(2 * i + 1));
175 }
176}
177
178// Red-Black Tree Tests
179
181{
182 insert_all();
183
184 EXPECT_EQ(tree.size(), N);
185 EXPECT_TRUE(tree.verify());
186}
187
189{
190 insert_all();
191
192 // After inserting 0..N-1, select(i) should return node with key i
193 for (size_t i = 0; i < N; ++i)
194 {
195 auto p = tree.select(i);
196 ASSERT_NE(p, nullptr);
197 EXPECT_EQ(p->get_key(), static_cast<int>(i));
198 }
199}
200
202{
203 insert_all();
204
205 // For each key k, position(k) should return k
206 for (size_t i = 0; i < N; ++i)
207 {
208 auto [pos, node] = tree.position(static_cast<int>(i));
209 EXPECT_EQ(pos, static_cast<long>(i));
210 ASSERT_NE(node, nullptr);
211 EXPECT_EQ(node->get_key(), static_cast<int>(i));
212 }
213}
214
216{
217 insert_all();
218
219 // Key not in tree should return -1
220 auto [pos, node] = tree.position(static_cast<int>(N + 100));
221 EXPECT_EQ(pos, -1);
222}
223
225{
226 insert_all();
227
228 shuffle(keys.begin(), keys.end(), rng);
229
230 for (size_t i = 0; i < N / 2; ++i)
231 {
232 auto p = tree.remove(keys[i]);
233 ASSERT_NE(p, nullptr);
234 delete p;
235 EXPECT_TRUE(tree.verify());
236 }
237
238 EXPECT_EQ(tree.size(), N - N / 2);
239}
240
242{
243 insert_all();
244
245 // Remove even keys
246 for (int k = 0; k < static_cast<int>(N); k += 2)
247 {
248 auto p = tree.remove(k);
249 delete p;
250 }
251
252 EXPECT_EQ(tree.size(), N / 2);
253
254 // Now select should return odd keys in order
255 for (size_t i = 0; i < N / 2; ++i)
256 {
257 auto p = tree.select(i);
258 ASSERT_NE(p, nullptr);
259 EXPECT_EQ(p->get_key(), static_cast<int>(2 * i + 1));
260 }
261}
262
263// Combined stress test
264
266{
267 Avl_Tree_Rk<int> tree;
269 const size_t N = 5000;
270
271 // Insert
272 for (size_t i = 0; i < N; ++i)
273 {
274 auto p = new Node(static_cast<int>(i));
275 ASSERT_NE(tree.insert(p), nullptr);
276 }
277
278 EXPECT_TRUE(tree.verify());
279 EXPECT_EQ(tree.size(), N);
280
281 // Random selects
283 for (int i = 0; i < 100; ++i)
284 {
285 size_t pos = dist(rng);
286 auto p = tree.select(pos);
287 EXPECT_EQ(p->get_key(), static_cast<int>(pos));
288 }
289
290 // Random positions
291 for (int i = 0; i < 100; ++i)
292 {
293 int key = static_cast<int>(dist(rng));
294 auto [pos, node] = tree.position(key);
295 EXPECT_EQ(pos, key);
296 }
297
298 // Remove half
299 for (int i = 0; i < static_cast<int>(N); i += 2)
300 delete tree.remove(i);
301
302 EXPECT_TRUE(tree.verify());
303 EXPECT_EQ(tree.size(), N / 2);
304
305 // Cleanup
306 while (not tree.is_empty())
307 delete tree.remove(tree.getRoot()->get_key());
308}
309
311{
312 Rb_Tree_Rk<int> tree;
314 const size_t N = 5000;
315
316 // Insert
317 for (size_t i = 0; i < N; ++i)
318 {
319 auto p = new Node(static_cast<int>(i));
320 ASSERT_NE(tree.insert(p), nullptr);
321 }
322
323 EXPECT_TRUE(tree.verify());
324 EXPECT_EQ(tree.size(), N);
325
326 // Random selects
328 for (int i = 0; i < 100; ++i)
329 {
330 size_t pos = dist(rng);
331 auto p = tree.select(pos);
332 EXPECT_EQ(p->get_key(), static_cast<int>(pos));
333 }
334
335 // Random positions
336 for (int i = 0; i < 100; ++i)
337 {
338 int key = static_cast<int>(dist(rng));
339 auto [pos, node] = tree.position(key);
340 EXPECT_EQ(pos, key);
341 }
342
343 // Remove half
344 for (int i = 0; i < static_cast<int>(N); i += 2)
345 delete tree.remove(i);
346
347 EXPECT_TRUE(tree.verify());
348 EXPECT_EQ(tree.size(), N / 2);
349
350 // Cleanup
351 while (not tree.is_empty())
352 delete tree.remove(tree.getRoot()->get_key());
353}
354
355// Test empty tree edge cases
356
358{
359 Avl_Tree_Rk<int> tree;
360
361 EXPECT_TRUE(tree.is_empty());
362 EXPECT_EQ(tree.size(), 0);
363 EXPECT_EQ(tree.search(42), nullptr);
364 EXPECT_EQ(tree.remove(42), nullptr);
365
366 auto [pos, node] = tree.position(42);
367 EXPECT_EQ(pos, -1);
368}
369
371{
372 Rb_Tree_Rk<int> tree;
373
374 EXPECT_TRUE(tree.is_empty());
375 EXPECT_EQ(tree.size(), 0);
376 EXPECT_EQ(tree.search(42), nullptr);
377 EXPECT_EQ(tree.remove(42), nullptr);
378
379 auto [pos, node] = tree.position(42);
380 EXPECT_EQ(pos, -1);
381}
382
383// Test single element
384
386{
387 Avl_Tree_Rk<int> tree;
389
390 auto p = new Node(42);
391 ASSERT_NE(tree.insert(p), nullptr);
392
393 EXPECT_EQ(tree.size(), 1);
394 EXPECT_TRUE(tree.verify());
395
396 auto selected = tree.select(0);
397 EXPECT_EQ(selected->get_key(), 42);
398
399 auto [pos, node] = tree.position(42);
400 EXPECT_EQ(pos, 0);
401 EXPECT_EQ(node->get_key(), 42);
402
403 delete tree.remove(42);
404 EXPECT_TRUE(tree.is_empty());
405}
406
408{
409 Rb_Tree_Rk<int> tree;
411
412 auto p = new Node(42);
413 ASSERT_NE(tree.insert(p), nullptr);
414
415 EXPECT_EQ(tree.size(), 1);
416 EXPECT_TRUE(tree.verify());
417
418 auto selected = tree.select(0);
419 EXPECT_EQ(selected->get_key(), 42);
420
421 auto [pos, node] = tree.position(42);
422 EXPECT_EQ(pos, 0);
423 EXPECT_EQ(node->get_key(), 42);
424
425 delete tree.remove(42);
426 EXPECT_TRUE(tree.is_empty());
427}
428
429// Test search_or_insert
430
432{
433 Avl_Tree_Rk<int> tree;
435
436 auto p1 = new Node(42);
437 auto result1 = tree.search_or_insert(p1);
438 EXPECT_EQ(result1, p1);
439 EXPECT_EQ(tree.size(), 1);
440
441 auto p2 = new Node(42);
442 auto result2 = tree.search_or_insert(p2);
443 EXPECT_EQ(result2, p1); // Should return existing node
444 EXPECT_EQ(tree.size(), 1); // Size should not change
445
446 delete p2; // Delete the non-inserted node
447 delete tree.remove(42);
448}
449
451{
452 Rb_Tree_Rk<int> tree;
454
455 auto p1 = new Node(42);
456 auto result1 = tree.search_or_insert(p1);
457 EXPECT_EQ(result1, p1);
458 EXPECT_EQ(tree.size(), 1);
459
460 auto p2 = new Node(42);
461 auto result2 = tree.search_or_insert(p2);
462 EXPECT_EQ(result2, p1); // Should return existing node
463 EXPECT_EQ(tree.size(), 1); // Size should not change
464
465 delete p2; // Delete the non-inserted node
466 delete tree.remove(42);
467}
468
469// Test insert_dup
470
472{
473 Avl_Tree_Rk<int> tree;
475
476 for (int i = 0; i < 10; ++i)
477 {
478 auto p = new Node(42);
479 ASSERT_NE(tree.insert_dup(p), nullptr);
480 }
481
482 EXPECT_EQ(tree.size(), 10);
483 EXPECT_TRUE(tree.verify());
484
485 // All should have key 42
486 for (size_t i = 0; i < 10; ++i)
487 EXPECT_EQ(tree.select(i)->get_key(), 42);
488
489 while (not tree.is_empty())
490 delete tree.remove(42);
491}
492
494{
495 Rb_Tree_Rk<int> tree;
497
498 for (int i = 0; i < 10; ++i)
499 {
500 auto p = new Node(42);
501 ASSERT_NE(tree.insert_dup(p), nullptr);
502 }
503
504 EXPECT_EQ(tree.size(), 10);
505 EXPECT_TRUE(tree.verify());
506
507 // All should have key 42
508 for (size_t i = 0; i < 10; ++i)
509 EXPECT_EQ(tree.select(i)->get_key(), 42);
510
511 while (not tree.is_empty())
512 delete tree.remove(42);
513}
514
515// ==============================================================
516// Join/Split tests
517// ==============================================================
518
519// Helper to cleanup a tree
520template <typename Tree>
521void destroy_tree(Tree & tree)
522{
523 while (not tree.is_empty())
524 delete tree.remove(tree.getRoot()->get_key());
525}
526
527// AVL Join Tests
528
530{
533
534 // Insert 0-49 in t1, 50-99 in t2
535 for (int i = 0; i < 50; ++i)
536 ASSERT_NE(t1.insert(new Node(i)), nullptr);
537 for (int i = 50; i < 100; ++i)
538 ASSERT_NE(t2.insert(new Node(i)), nullptr);
539
540 EXPECT_EQ(t1.size(), 50);
541 EXPECT_EQ(t2.size(), 50);
542 EXPECT_TRUE(t1.verify());
543 EXPECT_TRUE(t2.verify());
544
545 t1.join_exclusive(t2);
546
547 EXPECT_EQ(t1.size(), 100);
548 EXPECT_TRUE(t2.is_empty());
549 EXPECT_TRUE(t1.verify());
550
551 // Check all elements are present and in order
552 for (int i = 0; i < 100; ++i)
553 {
554 auto p = t1.select(i);
555 EXPECT_EQ(p->get_key(), i);
556 }
557
559}
560
562{
565
566 for (int i = 0; i < 50; ++i)
567 ASSERT_NE(t2.insert(new Node(i)), nullptr);
568
570
571 EXPECT_EQ(t1.size(), 50);
572 EXPECT_TRUE(t2.is_empty());
573 EXPECT_TRUE(t1.verify());
574
576}
577
579{
582
583 for (int i = 0; i < 50; ++i)
584 ASSERT_NE(t1.insert(new Node(i)), nullptr);
585
587
588 EXPECT_EQ(t1.size(), 50);
589 EXPECT_TRUE(t2.is_empty());
590 EXPECT_TRUE(t1.verify());
591
593}
594
596{
597 Avl_Tree_Rk<int> tree, t1, t2;
599
600 for (int i = 0; i < 100; ++i)
601 ASSERT_NE(tree.insert(new Node(i)), nullptr);
602
603 auto pivot = tree.split_key(50, t1, t2);
604
605 EXPECT_NE(pivot, nullptr);
606 EXPECT_EQ(pivot->get_key(), 50);
607 EXPECT_TRUE(tree.is_empty());
608 EXPECT_TRUE(t1.verify());
609 EXPECT_TRUE(t2.verify());
610
611 EXPECT_EQ(t1.size(), 50); // 0-49
612 EXPECT_EQ(t2.size(), 49); // 51-99
613
614 // Check t1 contains 0-49
615 for (int i = 0; i < 50; ++i)
616 EXPECT_EQ(t1.select(i)->get_key(), i);
617
618 // Check t2 contains 51-99
619 for (int i = 0; i < 49; ++i)
620 EXPECT_EQ(t2.select(i)->get_key(), i + 51);
621
622 delete pivot;
625}
626
628{
629 Avl_Tree_Rk<int> tree, t1, t2;
631
632 // Insert even numbers only
633 for (int i = 0; i < 100; i += 2)
634 ASSERT_NE(tree.insert(new Node(i)), nullptr);
635
636 // Split by odd number (not in tree)
637 auto pivot = tree.split_key(51, t1, t2);
638
639 EXPECT_EQ(pivot, nullptr);
640 EXPECT_TRUE(tree.is_empty());
641 EXPECT_TRUE(t1.verify());
642 EXPECT_TRUE(t2.verify());
643
644 // t1 should have 0, 2, 4, ..., 50 (26 elements)
645 EXPECT_EQ(t1.size(), 26);
646 // t2 should have 52, 54, ..., 98 (24 elements)
647 EXPECT_EQ(t2.size(), 24);
648
651}
652
654{
655 Avl_Tree_Rk<int> tree, t1, t2;
657
658 for (int i = 0; i < 100; ++i)
659 ASSERT_NE(tree.insert(new Node(i)), nullptr);
660
661 tree.split_pos(30, t1, t2);
662
663 EXPECT_TRUE(tree.is_empty());
664 EXPECT_TRUE(t1.verify());
665 EXPECT_TRUE(t2.verify());
666
667 EXPECT_EQ(t1.size(), 30); // positions 0-29
668 EXPECT_EQ(t2.size(), 70); // positions 30-99
669
670 // Check t1 contains 0-29
671 for (int i = 0; i < 30; ++i)
672 EXPECT_EQ(t1.select(i)->get_key(), i);
673
674 // Check t2 contains 30-99
675 for (int i = 0; i < 70; ++i)
676 EXPECT_EQ(t2.select(i)->get_key(), i + 30);
677
680}
681
683{
684 Avl_Tree_Rk<int> tree, t1, t2;
686
687 for (int i = 0; i < 50; ++i)
688 ASSERT_NE(tree.insert(new Node(i)), nullptr);
689
690 tree.split_pos(0, t1, t2);
691
692 EXPECT_TRUE(tree.is_empty());
693 EXPECT_TRUE(t1.is_empty());
694 EXPECT_EQ(t2.size(), 50);
695 EXPECT_TRUE(t2.verify());
696
698}
699
701{
702 Avl_Tree_Rk<int> tree, t1, t2;
704
705 for (int i = 0; i < 50; ++i)
706 ASSERT_NE(tree.insert(new Node(i)), nullptr);
707
708 tree.split_pos(50, t1, t2);
709
710 EXPECT_TRUE(tree.is_empty());
711 EXPECT_EQ(t1.size(), 50);
712 EXPECT_TRUE(t2.is_empty());
713 EXPECT_TRUE(t1.verify());
714
716}
717
719{
722
723 for (int i = 0; i < 50; ++i)
724 ASSERT_NE(t1.insert(new Node(i)), nullptr);
725 for (int i = 50; i < 100; ++i)
726 ASSERT_NE(t2.insert(new Node(i)), nullptr);
727
729 EXPECT_EQ(t1.size(), 100);
730 EXPECT_TRUE(t1.verify());
731
732 auto pivot = t1.split_key(50, t3, t4);
733 EXPECT_EQ(pivot->get_key(), 50);
734 EXPECT_EQ(t3.size(), 50);
735 EXPECT_EQ(t4.size(), 49);
736 EXPECT_TRUE(t3.verify());
737 EXPECT_TRUE(t4.verify());
738
739 delete pivot;
742}
743
744// Red-Black Join Tests
745
747{
750
751 for (int i = 0; i < 50; ++i)
752 ASSERT_NE(t1.insert(new Node(i)), nullptr);
753 for (int i = 50; i < 100; ++i)
754 ASSERT_NE(t2.insert(new Node(i)), nullptr);
755
756 EXPECT_EQ(t1.size(), 50);
757 EXPECT_EQ(t2.size(), 50);
758 EXPECT_TRUE(t1.verify());
759 EXPECT_TRUE(t2.verify());
760
761 t1.join_exclusive(t2);
762
763 EXPECT_EQ(t1.size(), 100);
764 EXPECT_TRUE(t2.is_empty());
765 EXPECT_TRUE(t1.verify());
766
767 for (int i = 0; i < 100; ++i)
768 {
769 auto p = t1.select(i);
770 EXPECT_EQ(p->get_key(), i);
771 }
772
774}
775
777{
780
781 for (int i = 0; i < 50; ++i)
782 ASSERT_NE(t2.insert(new Node(i)), nullptr);
783
785
786 EXPECT_EQ(t1.size(), 50);
787 EXPECT_TRUE(t2.is_empty());
788 EXPECT_TRUE(t1.verify());
789
791}
792
794{
797
798 for (int i = 0; i < 50; ++i)
799 ASSERT_NE(t1.insert(new Node(i)), nullptr);
800
802
803 EXPECT_EQ(t1.size(), 50);
804 EXPECT_TRUE(t2.is_empty());
805 EXPECT_TRUE(t1.verify());
806
808}
809
811{
812 Rb_Tree_Rk<int> tree, t1, t2;
814
815 for (int i = 0; i < 100; ++i)
816 ASSERT_NE(tree.insert(new Node(i)), nullptr);
817
818 auto pivot = tree.split_key(50, t1, t2);
819
820 EXPECT_NE(pivot, nullptr);
821 EXPECT_EQ(pivot->get_key(), 50);
822 EXPECT_TRUE(tree.is_empty());
823 EXPECT_TRUE(t1.verify());
824 EXPECT_TRUE(t2.verify());
825
826 EXPECT_EQ(t1.size(), 50); // 0-49
827 EXPECT_EQ(t2.size(), 49); // 51-99
828
829 for (int i = 0; i < 50; ++i)
830 EXPECT_EQ(t1.select(i)->get_key(), i);
831
832 for (int i = 0; i < 49; ++i)
833 EXPECT_EQ(t2.select(i)->get_key(), i + 51);
834
835 delete pivot;
838}
839
841{
842 Rb_Tree_Rk<int> tree, t1, t2;
844
845 for (int i = 0; i < 100; i += 2)
846 ASSERT_NE(tree.insert(new Node(i)), nullptr);
847
848 auto pivot = tree.split_key(51, t1, t2);
849
850 EXPECT_EQ(pivot, nullptr);
851 EXPECT_TRUE(tree.is_empty());
852 EXPECT_TRUE(t1.verify());
853 EXPECT_TRUE(t2.verify());
854
855 EXPECT_EQ(t1.size(), 26);
856 EXPECT_EQ(t2.size(), 24);
857
860}
861
863{
864 Rb_Tree_Rk<int> tree, t1, t2;
866
867 for (int i = 0; i < 100; ++i)
868 ASSERT_NE(tree.insert(new Node(i)), nullptr);
869
870 tree.split_pos(30, t1, t2);
871
872 EXPECT_TRUE(tree.is_empty());
873 EXPECT_TRUE(t1.verify());
874 EXPECT_TRUE(t2.verify());
875
876 EXPECT_EQ(t1.size(), 30);
877 EXPECT_EQ(t2.size(), 70);
878
879 for (int i = 0; i < 30; ++i)
880 EXPECT_EQ(t1.select(i)->get_key(), i);
881
882 for (int i = 0; i < 70; ++i)
883 EXPECT_EQ(t2.select(i)->get_key(), i + 30);
884
887}
888
890{
891 Rb_Tree_Rk<int> tree, t1, t2;
893
894 for (int i = 0; i < 50; ++i)
895 ASSERT_NE(tree.insert(new Node(i)), nullptr);
896
897 tree.split_pos(0, t1, t2);
898
899 EXPECT_TRUE(tree.is_empty());
900 EXPECT_TRUE(t1.is_empty());
901 EXPECT_EQ(t2.size(), 50);
902 EXPECT_TRUE(t2.verify());
903
905}
906
908{
909 Rb_Tree_Rk<int> tree, t1, t2;
911
912 for (int i = 0; i < 50; ++i)
913 ASSERT_NE(tree.insert(new Node(i)), nullptr);
914
915 tree.split_pos(50, t1, t2);
916
917 EXPECT_TRUE(tree.is_empty());
918 EXPECT_EQ(t1.size(), 50);
919 EXPECT_TRUE(t2.is_empty());
920 EXPECT_TRUE(t1.verify());
921
923}
924
926{
929
930 for (int i = 0; i < 50; ++i)
931 ASSERT_NE(t1.insert(new Node(i)), nullptr);
932 for (int i = 50; i < 100; ++i)
933 ASSERT_NE(t2.insert(new Node(i)), nullptr);
934
936 EXPECT_EQ(t1.size(), 100);
937 EXPECT_TRUE(t1.verify());
938
939 auto pivot = t1.split_key(50, t3, t4);
940 EXPECT_EQ(pivot->get_key(), 50);
941 EXPECT_EQ(t3.size(), 50);
942 EXPECT_EQ(t4.size(), 49);
943 EXPECT_TRUE(t3.verify());
944 EXPECT_TRUE(t4.verify());
945
946 delete pivot;
949}
950
951// Large scale join/split stress tests
952
954{
957 const int N = 1000;
958
959 for (int i = 0; i < N / 2; ++i)
960 ASSERT_NE(t1.insert(new Node(i)), nullptr);
961 for (int i = N / 2; i < N; ++i)
962 ASSERT_NE(t2.insert(new Node(i)), nullptr);
963
965 EXPECT_EQ(t1.size(), N);
966 EXPECT_TRUE(t1.verify());
967
968 t1.split_pos(N / 3, t3, t4);
969 EXPECT_EQ(t3.size(), N / 3);
970 EXPECT_EQ(t4.size(), N - N / 3);
971 EXPECT_TRUE(t3.verify());
972 EXPECT_TRUE(t4.verify());
973
974 t3.join_exclusive(t4);
975 EXPECT_EQ(t3.size(), N);
976 EXPECT_TRUE(t3.verify());
977
979}
980
982{
985 const int N = 1000;
986
987 for (int i = 0; i < N / 2; ++i)
988 ASSERT_NE(t1.insert(new Node(i)), nullptr);
989 for (int i = N / 2; i < N; ++i)
990 ASSERT_NE(t2.insert(new Node(i)), nullptr);
991
993 EXPECT_EQ(t1.size(), N);
994 EXPECT_TRUE(t1.verify());
995
996 t1.split_pos(N / 3, t3, t4);
997 EXPECT_EQ(t3.size(), N / 3);
998 EXPECT_EQ(t4.size(), N - N / 3);
999 EXPECT_TRUE(t3.verify());
1000 EXPECT_TRUE(t4.verify());
1001
1002 t3.join_exclusive(t4);
1003 EXPECT_EQ(t3.size(), N);
1004 EXPECT_TRUE(t3.verify());
1005
1007}
1008
1009// Test split_key_dup
1010
1012{
1013 Avl_Tree_Rk<int> tree, t1, t2;
1015
1016 // Insert with duplicates: several 50s
1017 for (int i = 0; i < 50; ++i)
1018 ASSERT_NE(tree.insert_dup(new Node(i)), nullptr);
1019 for (int i = 0; i < 10; ++i)
1020 ASSERT_NE(tree.insert_dup(new Node(50)), nullptr);
1021 for (int i = 51; i < 100; ++i)
1022 ASSERT_NE(tree.insert_dup(new Node(i)), nullptr);
1023
1024 EXPECT_EQ(tree.size(), 109); // 50 + 10 + 49
1025
1026 tree.split_key_dup(50, t1, t2);
1027
1028 EXPECT_TRUE(tree.is_empty());
1029 EXPECT_TRUE(t1.verify());
1030 EXPECT_TRUE(t2.verify());
1031
1032 // t1 should have keys <= 50 (0-49 + 10 duplicates of 50 = 50 + 10 = 60)
1033 EXPECT_EQ(t1.size(), 60);
1034 // t2 should have keys > 50 (51-99 = 49)
1035 EXPECT_EQ(t2.size(), 49);
1036
1039}
1040
1042{
1043 Rb_Tree_Rk<int> tree, t1, t2;
1045
1046 for (int i = 0; i < 50; ++i)
1047 ASSERT_NE(tree.insert_dup(new Node(i)), nullptr);
1048 for (int i = 0; i < 10; ++i)
1049 ASSERT_NE(tree.insert_dup(new Node(50)), nullptr);
1050 for (int i = 51; i < 100; ++i)
1051 ASSERT_NE(tree.insert_dup(new Node(i)), nullptr);
1052
1053 EXPECT_EQ(tree.size(), 109);
1054
1055 tree.split_key_dup(50, t1, t2);
1056
1057 EXPECT_TRUE(tree.is_empty());
1058 EXPECT_TRUE(t1.verify());
1059 EXPECT_TRUE(t2.verify());
1060
1061 // t1 should have keys <= 50 (0-49 + 10 duplicates of 50 = 50 + 10 = 60)
1062 EXPECT_EQ(t1.size(), 60);
1063 EXPECT_EQ(t2.size(), 49);
1064
1067}
1068
1069int main(int argc, char **argv)
1070{
1071 ::testing::InitGoogleTest(&argc, argv);
1072 return RUN_ALL_TESTS();
1073}
TEST_F(AvlRkTest, InsertAndVerify)
Definition avl-rb-rk.cc:95
void destroy_tree(Tree &tree)
Definition avl-rb-rk.cc:521
WeightedDigraph::Node Node
int main()
Node * insert(Node *p) noexcept
Insert the node pointed by p in the tree.
Definition tpl_avlRk.H:602
constexpr Node *& getRoot() noexcept
Return a modifiable reference to tree's root.
Definition tpl_avlRk.H:566
Node * select(const size_t i) const
Return the i-th node in order sense.
Definition tpl_avlRk.H:737
Node * search_or_insert(Node *p) noexcept
Search or insert a key.
Definition tpl_avlRk.H:632
Node * remove(const Key &key) noexcept
Remove from tree the node containing key.
Definition tpl_avlRk.H:676
size_t size() const noexcept
Return the number of nodes in the tree.
Definition tpl_avlRk.H:578
void join_exclusive(Gen_Avl_Tree_Rk &t) noexcept
Join this tree exclusively with another tree.
Definition tpl_avlRk.H:1237
constexpr bool is_empty() const noexcept
Return true if tree is empty.
Definition tpl_avlRk.H:584
Node * insert_dup(Node *p) noexcept
Insert the node p without testing for key duplicity.
Definition tpl_avlRk.H:656
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:1340
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:1289
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:1385
bool verify() const noexcept
Return true if the tree is a valid AVL tree with correct counters.
Definition tpl_avlRk.H:773
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:591
std::pair< long, Node * > position(const Key &key) const noexcept
Compute the inorder position of a key.
Definition tpl_avlRk.H:748
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:1381
size_t size() const noexcept
Definition tpl_rbRk.H:512
void join_exclusive(Gen_Rb_Tree_Rk &t) noexcept
Join this tree exclusively with another tree.
Definition tpl_rbRk.H:1333
Node * select(const size_t i) const
Return the i-th node in order sense.
Definition tpl_rbRk.H:646
Node * insert_dup(Node *p)
Definition tpl_rbRk.H:566
bool is_empty() const noexcept
Definition tpl_rbRk.H:510
Node * search(const Key &key)
Definition tpl_rbRk.H:502
bool verify() const
Definition tpl_rbRk.H:587
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:1471
Node * search_or_insert(Node *p)
Definition tpl_rbRk.H:540
Node * insert(Node *p)
Definition tpl_rbRk.H:514
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:1429
Node *& getRoot() noexcept
Definition tpl_rbRk.H:508
Node * remove(const Key &key)
Definition tpl_rbRk.H:589
std::pair< long, Node * > position(const Key &key) const noexcept
Compute the inorder position of a key.
Definition tpl_rbRk.H:657
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
QuadNode Node
Definition quadtree.H:128
Point * insert(Node *&r, const Point &p)
Recursive insert helper.
Definition quadtree.H:281
void insert_all()
Definition avl-rb-rk.cc:80
typename Tree::Node Node
Definition avl-rb-rk.cc:59
void SetUp() override
Definition avl-rb-rk.cc:64
void TearDown() override
Definition avl-rb-rk.cc:71
static constexpr size_t N
Definition avl-rb-rk.cc:62
vector< int > keys
Definition avl-rb-rk.cc:61
#define TEST(name)
static mt19937 rng
#define N
Definition fib.C:294
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
void iota(C &container, typename C::Item_Type start)
Fill all elements of a container with unit-step sequential values.
auto shuffle(const C< T > &c)
Randomly shuffle a sequence.
STL namespace.
Ranked AVL tree with nodes without a virtual destructor.
Definition tpl_avlRk.H:1469
Red-Black binary search tree with nodes without virtual destructor and with subtree counters for sele...
Definition tpl_rbRk.H:1551
int keys[]
static int * k
AVL tree with rank (order statistics).
Red-Black tree with rank (order statistics).