Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
splay-tree-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#include <algorithm>
39#include <numeric>
40#include <random>
41#include <set>
42#include <vector>
43
44#include <gtest/gtest.h>
45
46#include <tpl_splay_treeRk.H>
47
48using namespace Aleph;
49using namespace testing;
50
51namespace
52{
54 using Node = Tree::Node;
55
56 struct AbsLess
57 {
58 bool operator()(int a, int b) const
59 {
60 return std::abs(a) < std::abs(b);
61 }
62 };
63
64 struct NodePool
65 {
66 std::vector<Node *> allocated;
67
68 Node * make(int k)
69 {
70 auto * p = new Node(k);
71 allocated.push_back(p);
72 return p;
73 }
74
75 void forget(Node * p) noexcept
76 {
77 for (auto & q : allocated)
78 if (q == p)
79 {
80 q = nullptr;
81 return;
82 }
83 }
84
85 ~NodePool()
86 {
87 for (auto * p : allocated)
88 delete p;
89 }
90 };
91
92 void delete_tree(Node * root) noexcept
93 {
94 if (root == Node::NullPtr)
95 return;
98 delete root;
99 }
100
101 std::vector<int> inorder_keys(Node * root)
102 {
103 std::vector<int> keys;
104 if (root == Node::NullPtr)
105 return keys;
106
107 auto left = inorder_keys(LLINK(root));
108 keys.insert(keys.end(), left.begin(), left.end());
109 keys.push_back(KEY(root));
110 auto right = inorder_keys(RLINK(root));
111 keys.insert(keys.end(), right.begin(), right.end());
112 return keys;
113 }
114
115 void assert_valid_tree(Tree & tree)
116 {
117 ASSERT_TRUE(tree.verify()) << "Rank tree invariant violated";
118 auto * root = tree.getRoot();
119 if (root != Node::NullPtr)
120 ASSERT_EQ(COUNT(root), tree.size());
121 }
122}
123
124// ============================================================================
125// Basic Operations Tests
126// ============================================================================
127
129{
130 Tree tree;
131
132 EXPECT_TRUE(tree.is_empty());
133 EXPECT_EQ(tree.size(), 0u);
134 EXPECT_EQ(tree.getRoot(), Node::NullPtr);
135 EXPECT_EQ(tree.search(42), nullptr);
136 EXPECT_TRUE(tree.verify());
137}
138
140{
141 Tree tree;
142 NodePool pool;
143
144 auto * p = pool.make(42);
145 auto * inserted = tree.insert(p);
146
148 EXPECT_FALSE(tree.is_empty());
149 EXPECT_EQ(tree.size(), 1u);
150 EXPECT_EQ(tree.getRoot(), p);
151 assert_valid_tree(tree);
152}
153
155{
156 Tree tree;
157 NodePool pool;
158
159 for (int k : {5, 3, 7, 1, 4, 6, 8})
160 {
161 auto * p = pool.make(k);
162 ASSERT_NE(tree.insert(p), nullptr);
163 }
164
165 EXPECT_EQ(tree.size(), 7u);
166 assert_valid_tree(tree);
167
168 auto keys = inorder_keys(tree.getRoot());
169 EXPECT_EQ(keys, (std::vector<int>{1, 3, 4, 5, 6, 7, 8}));
170}
171
173{
174 Tree tree;
175 NodePool pool;
176
177 auto * p1 = pool.make(10);
178 EXPECT_NE(tree.insert(p1), nullptr);
179
180 auto * p2 = pool.make(10);
181 EXPECT_EQ(tree.insert(p2), nullptr);
182
183 EXPECT_EQ(tree.size(), 1u);
184 assert_valid_tree(tree);
185}
186
188{
189 Tree tree;
190 NodePool pool;
191
192 for (int i = 0; i < 5; ++i)
193 ASSERT_NE(tree.insert_dup(pool.make(42)), nullptr);
194
195 EXPECT_EQ(tree.size(), 5u);
196 assert_valid_tree(tree);
197
198 auto keys = inorder_keys(tree.getRoot());
199 EXPECT_EQ(keys, (std::vector<int>{42, 42, 42, 42, 42}));
200}
201
203{
204 Tree tree;
205 NodePool pool;
206
207 for (int k : {1, 2, 3, 4, 5})
208 tree.insert(pool.make(k));
209
210 for (int k : {1, 2, 3, 4, 5})
211 {
212 auto * found = tree.search(k);
213 ASSERT_NE(found, nullptr);
214 EXPECT_EQ(KEY(found), k);
215 }
216
217 assert_valid_tree(tree);
218}
219
221{
222 Tree tree;
223 NodePool pool;
224
225 for (int k : {1, 3, 5})
226 tree.insert(pool.make(k));
227
228 EXPECT_EQ(tree.search(2), nullptr);
229 EXPECT_EQ(tree.search(4), nullptr);
230 EXPECT_EQ(tree.search(0), nullptr);
231 EXPECT_EQ(tree.search(6), nullptr);
232
233 assert_valid_tree(tree);
234}
235
237{
238 Tree tree;
239 NodePool pool;
240
241 // Insert via search_or_insert
242 auto * p1 = pool.make(10);
243 auto * ret1 = tree.search_or_insert(p1);
244 EXPECT_EQ(ret1, p1);
245 EXPECT_EQ(tree.size(), 1u);
246
247 // Search existing via search_or_insert
248 auto * p2 = pool.make(10);
249 auto * ret2 = tree.search_or_insert(p2);
250 EXPECT_NE(ret2, p2);
251 EXPECT_EQ(KEY(ret2), 10);
252 EXPECT_EQ(tree.size(), 1u);
253
254 assert_valid_tree(tree);
255}
256
257// ============================================================================
258// Remove Tests
259// ============================================================================
260
262{
263 Tree tree;
264 NodePool pool;
265
266 for (int k : {1, 2, 3, 4, 5})
267 tree.insert(pool.make(k));
268
269 auto * removed = tree.remove(3);
270 ASSERT_NE(removed, nullptr);
271 EXPECT_EQ(KEY(removed), 3);
272 pool.forget(removed);
273 delete removed;
274
275 EXPECT_EQ(tree.size(), 4u);
276 EXPECT_EQ(tree.search(3), nullptr);
277 assert_valid_tree(tree);
278
279 auto keys = inorder_keys(tree.getRoot());
280 EXPECT_EQ(keys, (std::vector<int>{1, 2, 4, 5}));
281}
282
284{
285 Tree tree;
286 NodePool pool;
287
288 for (int k : {1, 3, 5})
289 tree.insert(pool.make(k));
290
291 EXPECT_EQ(tree.remove(2), nullptr);
292 EXPECT_EQ(tree.remove(4), nullptr);
293 EXPECT_EQ(tree.size(), 3u);
294
295 assert_valid_tree(tree);
296}
297
299{
300 Tree tree;
301
302 EXPECT_EQ(tree.remove(42), nullptr);
303 EXPECT_TRUE(tree.is_empty());
304}
305
307{
308 Tree tree;
309 NodePool pool;
310
311 // Insert in order to create a tree where root has no left child
312 tree.insert(pool.make(1));
313 tree.insert(pool.make(2));
314 tree.insert(pool.make(3));
315
316 // After splay for 1, root should be 1 which has no left child
317 auto * removed = tree.remove(1);
318 ASSERT_NE(removed, nullptr);
319 EXPECT_EQ(KEY(removed), 1);
320 pool.forget(removed);
321 delete removed;
322
323 EXPECT_EQ(tree.size(), 2u);
324 assert_valid_tree(tree);
325}
326
328{
329 Tree tree;
330 NodePool pool;
331
332 std::vector<int> keys = {5, 3, 7, 1, 4, 6, 8};
333 for (int k : keys)
334 tree.insert(pool.make(k));
335
336 for (int k : keys)
337 {
338 auto * removed = tree.remove(k);
339 ASSERT_NE(removed, nullptr) << "Failed to remove " << k;
340 pool.forget(removed);
341 delete removed;
342 assert_valid_tree(tree);
343 }
344
345 EXPECT_TRUE(tree.is_empty());
346 EXPECT_EQ(tree.size(), 0u);
347}
348
349// ============================================================================
350// Rank Operations Tests (select, position)
351// ============================================================================
352
354{
355 Tree tree;
356 NodePool pool;
357
358 for (int k : {5, 3, 7, 1, 4, 6, 8})
359 tree.insert(pool.make(k));
360
361 // Expected order: 1, 3, 4, 5, 6, 7, 8
362 std::vector<int> expected = {1, 3, 4, 5, 6, 7, 8};
363
364 for (size_t i = 0; i < expected.size(); ++i)
365 {
366 auto * node = tree.select(i);
367 ASSERT_NE(node, Node::NullPtr) << "select(" << i << ") returned null";
368 EXPECT_EQ(KEY(node), expected[i]) << "select(" << i << ") wrong key";
369 }
370}
371
373{
374 Tree tree;
375 NodePool pool;
376
377 for (int k : {1, 2, 3})
378 tree.insert(pool.make(k));
379
380 EXPECT_THROW(tree.select(3), std::out_of_range);
381 EXPECT_THROW(tree.select(100), std::out_of_range);
382}
383
385{
386 Tree tree;
387 NodePool pool;
388
389 for (int k : {5, 3, 7, 1, 4, 6, 8})
390 tree.insert(pool.make(k));
391
392 // Expected order: 1, 3, 4, 5, 6, 7, 8 (positions 0-6)
393 std::vector<std::pair<int, long>> expected = {
394 {1, 0}, {3, 1}, {4, 2}, {5, 3}, {6, 4}, {7, 5}, {8, 6}
395 };
396
397 for (auto [key, pos] : expected)
398 {
399 auto result = tree.position(key);
400 EXPECT_EQ(result.first, pos) << "position(" << key << ") wrong";
401 ASSERT_NE(result.second, nullptr);
402 EXPECT_EQ(KEY(result.second), key);
403 }
404}
405
407{
408 Tree tree;
409 NodePool pool;
410
411 for (int k : {2, 4, 6})
412 tree.insert(pool.make(k));
413
414 auto result = tree.position(3);
415 EXPECT_EQ(result.first, -1);
416 // Note: result.second may be uninitialized in current implementation
417}
418
420{
421 Tree tree;
422
423 // This should handle empty tree gracefully
424 // Current implementation may crash - this tests the fix
425 auto result = tree.position(42);
426 EXPECT_EQ(result.first, -1);
427}
428
429// ============================================================================
430// Splay Operation Tests
431// ============================================================================
432
434{
435 Tree tree;
436 NodePool pool;
437
438 for (int k : {1, 2, 3, 4, 5})
439 tree.insert(pool.make(k));
440
441 // Search for 1 should bring it to root
442 tree.search(1);
443 EXPECT_EQ(KEY(tree.getRoot()), 1);
444 assert_valid_tree(tree);
445
446 // Search for 5 should bring it to root
447 tree.search(5);
448 EXPECT_EQ(KEY(tree.getRoot()), 5);
449 assert_valid_tree(tree);
450
451 // Search for 3 should bring it to root
452 tree.search(3);
453 EXPECT_EQ(KEY(tree.getRoot()), 3);
454 assert_valid_tree(tree);
455}
456
458{
459 Tree tree;
460 NodePool pool;
461
462 for (int k : {5, 3, 7, 1, 4, 6, 8})
463 tree.insert(pool.make(k));
464
465 size_t original_size = tree.size();
466
467 // Multiple searches should maintain counts
468 for (int k : {1, 8, 4, 6, 3, 7, 5})
469 {
470 tree.search(k);
472 assert_valid_tree(tree);
473 }
474}
475
476// ============================================================================
477// Edge Cases
478// ============================================================================
479
481{
482 Tree tree;
483 NodePool pool;
484
485 auto * p = pool.make(42);
486 tree.insert(p);
487
488 EXPECT_EQ(tree.select(0), p);
489 EXPECT_EQ(tree.position(42).first, 0);
490 EXPECT_EQ(tree.search(42), p);
491
492 auto * removed = tree.remove(42);
493 EXPECT_EQ(removed, p);
494 EXPECT_TRUE(tree.is_empty());
495 pool.forget(removed);
496 delete removed;
497}
498
500{
501 Tree tree;
502 NodePool pool;
503
504 for (int k = 10; k >= 1; --k)
505 tree.insert(pool.make(k));
506
507 EXPECT_EQ(tree.size(), 10u);
508 assert_valid_tree(tree);
509
510 auto keys = inorder_keys(tree.getRoot());
511 EXPECT_EQ(keys, (std::vector<int>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
512}
513
515{
516 Tree tree;
517 NodePool pool;
518
519 for (int k = 1; k <= 10; ++k)
520 tree.insert(pool.make(k));
521
522 EXPECT_EQ(tree.size(), 10u);
523 assert_valid_tree(tree);
524
525 auto keys = inorder_keys(tree.getRoot());
526 EXPECT_EQ(keys, (std::vector<int>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
527}
528
529// ============================================================================
530// Custom Comparator Tests
531// ============================================================================
532
534{
536 using NodeGt = TreeGt::Node;
537
538 TreeGt tree;
539 std::vector<NodeGt *> nodes;
540
541 for (int k : {1, 2, 3, 4, 5})
542 {
543 auto * p = new NodeGt(k);
544 nodes.push_back(p);
545 tree.insert(p);
546 }
547
548 EXPECT_EQ(tree.size(), 5u);
549 EXPECT_TRUE(tree.verify());
550
551 // With greater<int>, inorder should be descending
552 std::vector<int> keys;
553 std::function<void(NodeGt*)> collect = [&](NodeGt* r) {
554 if (r == NodeGt::NullPtr) return;
555 collect(LLINK(r));
556 keys.push_back(KEY(r));
557 collect(RLINK(r));
558 };
559 collect(tree.getRoot());
560
561 EXPECT_EQ(keys, (std::vector<int>{5, 4, 3, 2, 1}));
562
563 for (auto * p : nodes)
564 delete p;
565}
566
568{
570 using NodeAbs = TreeAbs::Node;
571
572 TreeAbs tree(AbsLess{});
573 auto * p = new NodeAbs(1);
574 tree.insert(p);
575
576 auto * found = tree.search(-1);
577 ASSERT_NE(found, nullptr);
578 EXPECT_EQ(found, p);
579 EXPECT_TRUE(tree.verify());
580
581 delete tree.remove(1);
582}
583
584// ============================================================================
585// Stress Tests
586// ============================================================================
587
589{
590 Tree tree;
591 NodePool pool;
592 std::set<int> oracle;
593
594 std::mt19937 rng(42);
595 std::uniform_int_distribution<int> dist(0, 500);
596
597 // Insert phase
598 for (int i = 0; i < 200; ++i)
599 {
600 int k = dist(rng);
601 auto * p = pool.make(k);
602 if (tree.insert(p) != nullptr)
603 oracle.insert(k);
604 else
605 {
606 pool.forget(p);
607 delete p;
608 }
609
610 ASSERT_EQ(tree.size(), oracle.size());
611 assert_valid_tree(tree);
612 }
613
614 // Verify all elements
615 auto keys = inorder_keys(tree.getRoot());
616 EXPECT_EQ(keys, std::vector<int>(oracle.begin(), oracle.end()));
617
618 // Search phase
619 for (int i = 0; i < 100; ++i)
620 {
621 int k = dist(rng);
622 auto * found = tree.search(k);
623 if (oracle.count(k))
624 {
625 ASSERT_NE(found, nullptr);
626 EXPECT_EQ(KEY(found), k);
627 }
628 else
629 EXPECT_EQ(found, nullptr);
630
631 assert_valid_tree(tree);
632 }
633
634 // Remove phase
635 for (int i = 0; i < 150; ++i)
636 {
637 int k = dist(rng);
638 auto * removed = tree.remove(k);
639 if (oracle.count(k))
640 {
641 ASSERT_NE(removed, nullptr);
643 oracle.erase(k);
644 pool.forget(removed);
645 delete removed;
646 }
647 else
648 EXPECT_EQ(removed, nullptr);
649
650 ASSERT_EQ(tree.size(), oracle.size());
651 assert_valid_tree(tree);
652 }
653
654 // Final verification
655 keys = inorder_keys(tree.getRoot());
656 EXPECT_EQ(keys, std::vector<int>(oracle.begin(), oracle.end()));
657}
658
660{
661 Tree tree;
662 NodePool pool;
663
664 std::mt19937 rng(123);
665 std::uniform_int_distribution<int> dist(0, 1000);
666
667 std::set<int> oracle;
668 for (int i = 0; i < 100; ++i)
669 {
670 int k = dist(rng);
671 auto * p = pool.make(k);
672 if (tree.insert(p) != nullptr)
673 oracle.insert(k);
674 else
675 {
676 pool.forget(p);
677 delete p;
678 }
679 }
680
681 // For each position, select should return correct element
682 std::vector<int> sorted(oracle.begin(), oracle.end());
683 for (size_t i = 0; i < sorted.size(); ++i)
684 {
685 auto * node = tree.select(i);
686 ASSERT_NE(node, Node::NullPtr);
687 EXPECT_EQ(KEY(node), sorted[i]);
688
689 // Position of that key should be i
690 auto pos_result = tree.position(sorted[i]);
691 EXPECT_EQ(pos_result.first, static_cast<long>(i));
692 }
693}
694
695// ============================================================================
696// Verify Method Tests
697// ============================================================================
698
700{
701 Tree tree;
702 NodePool pool;
703
704 for (int k : {5, 3, 7, 1, 4, 6, 8})
705 tree.insert(pool.make(k));
706
707 EXPECT_TRUE(tree.verify());
708}
709
710// ============================================================================
711// Virtual Destructor Variant Tests
712// ============================================================================
713
714// Note: Splay_Tree_Rk_Vtl test is disabled because BinNodeXtVtl has a private
715// sentinel constructor that prevents the splay() method from working correctly.
716// This is a design issue in the template that should be addressed separately.
717
718// ============================================================================
719// Swap Test
720// ============================================================================
721
723{
725 NodePool pool;
726
727 for (int k : {1, 2, 3})
728 tree1.insert(pool.make(k));
729
730 for (int k : {10, 20})
731 tree2.insert(pool.make(k));
732
733 EXPECT_EQ(tree1.size(), 3u);
734 EXPECT_EQ(tree2.size(), 2u);
735
737
738 EXPECT_EQ(tree1.size(), 2u);
739 EXPECT_EQ(tree2.size(), 3u);
740
741 EXPECT_NE(tree1.search(10), nullptr);
742 EXPECT_NE(tree2.search(1), nullptr);
743}
744
745// ============================================================================
746// Additional Stress and Fuzz Tests
747// ============================================================================
748
750{
751 Tree tree;
752 NodePool pool;
753
754 const int N = 5000;
755 for (int k = 0; k < N; ++k)
756 {
757 tree.insert(pool.make(k));
758 if (k % 500 == 0)
759 assert_valid_tree(tree);
760 }
761
762 EXPECT_EQ(tree.size(), static_cast<size_t>(N));
763 assert_valid_tree(tree);
764
765 // Verify select and position
766 for (int i = 0; i < 100; ++i)
767 {
768 int pos = rand() % N;
769 auto * node = tree.select(pos);
770 ASSERT_NE(node, Node::NullPtr);
771 EXPECT_EQ(KEY(node), pos);
772 }
773}
774
776{
777 Tree tree;
778 NodePool pool;
779
780 const int N = 5000;
781 for (int k = N - 1; k >= 0; --k)
782 tree.insert(pool.make(k));
783
784 EXPECT_EQ(tree.size(), static_cast<size_t>(N));
785 assert_valid_tree(tree);
786}
787
789{
790 Tree tree;
791 NodePool pool;
792
793 const int N = 3000;
794 for (int i = 0; i < N; ++i)
795 {
796 int k = (i % 2 == 0) ? i / 2 : N - 1 - i / 2;
797 tree.insert(pool.make(k));
798 }
799
800 EXPECT_EQ(tree.size(), static_cast<size_t>(N));
801 assert_valid_tree(tree);
802}
803
805{
806 Tree tree;
807 NodePool pool;
808 std::set<int> oracle;
809
810 std::mt19937 gen(98765);
811 std::uniform_int_distribution<> key_dist(0, 20000);
812 std::uniform_int_distribution<> op_dist(0, 2);
813
814 for (int iter = 0; iter < 10000; ++iter)
815 {
816 int key = key_dist(gen);
817 int op = op_dist(gen);
818
819 if (op == 0) // insert
820 {
821 auto * p = pool.make(key);
822 if (tree.insert(p) != nullptr)
823 oracle.insert(key);
824 else
825 {
826 pool.forget(p);
827 delete p;
828 }
829 }
830 else if (op == 1 && !oracle.empty()) // remove
831 {
832 auto it = oracle.begin();
833 std::advance(it, gen() % oracle.size());
834 int k = *it;
835
836 auto * removed = tree.remove(k);
837 ASSERT_NE(removed, nullptr) << "Failed to remove existing key " << k;
838 pool.forget(removed);
839 delete removed;
840 oracle.erase(k);
841 }
842 else // search
843 {
844 auto * found = tree.search(key);
845 if (oracle.count(key))
846 ASSERT_NE(found, nullptr);
847 else
848 EXPECT_EQ(found, nullptr);
849 }
850
851 EXPECT_EQ(tree.size(), oracle.size());
852
853 if (iter % 2000 == 0)
854 assert_valid_tree(tree);
855 }
856
857 assert_valid_tree(tree);
858}
859
861{
862 Tree tree;
863 NodePool pool;
864
865 const int N = 5000;
866
867 // Bulk insert
868 for (int k = 0; k < N; ++k)
869 tree.insert(pool.make(k));
870
871 EXPECT_EQ(tree.size(), static_cast<size_t>(N));
872 assert_valid_tree(tree);
873
874 // Bulk remove in random order
875 std::vector<int> keys_to_remove(N);
876 std::iota(keys_to_remove.begin(), keys_to_remove.end(), 0);
877 std::mt19937 gen(11111);
878 std::shuffle(keys_to_remove.begin(), keys_to_remove.end(), gen);
879
880 for (int k : keys_to_remove)
881 {
882 auto * removed = tree.remove(k);
883 ASSERT_NE(removed, nullptr) << "Failed to remove " << k;
884 pool.forget(removed);
885 delete removed;
886 }
887
888 EXPECT_TRUE(tree.is_empty());
889}
890
892{
893 Tree tree;
894 NodePool pool;
895
896 const int N = 100;
897 const int DUPS = 5;
898
899 for (int k = 0; k < N; ++k)
900 for (int d = 0; d < DUPS; ++d)
901 tree.insert_dup(pool.make(k));
902
903 size_t initial_size = tree.size();
905 assert_valid_tree(tree);
906
907 // Remove all elements until tree is empty
908 size_t total_removed = 0;
909 while (!tree.is_empty())
910 {
911 // Get any key from the tree via select
912 auto * node = tree.select(0);
913 ASSERT_NE(node, Node::NullPtr);
914 int k = KEY(node);
915
916 auto * removed = tree.remove(k);
917 ASSERT_NE(removed, nullptr);
918 pool.forget(removed);
919 delete removed;
921
922 // Validate tree structure periodically
923 if (total_removed % 50 == 0)
924 assert_valid_tree(tree);
925 }
926
928 EXPECT_TRUE(tree.is_empty());
929}
930
932{
933 Tree tree;
934 NodePool pool;
935 std::set<int> oracle;
936
937 std::mt19937 gen(22222);
938 std::uniform_int_distribution<> key_dist(0, 5000);
939
940 // Insert random keys
941 for (int i = 0; i < 2000; ++i)
942 {
943 int key = key_dist(gen);
944 auto * p = pool.make(key);
945 if (tree.insert(p) != nullptr)
946 oracle.insert(key);
947 else
948 {
949 pool.forget(p);
950 delete p;
951 }
952 }
953
954 std::vector<int> sorted(oracle.begin(), oracle.end());
955
956 // Test select and position consistency
957 for (size_t i = 0; i < sorted.size(); ++i)
958 {
959 auto * node = tree.select(i);
960 ASSERT_NE(node, Node::NullPtr);
961 EXPECT_EQ(KEY(node), sorted[i]);
962
963 auto pos_result = tree.position(sorted[i]);
964 EXPECT_EQ(pos_result.first, static_cast<long>(i));
965 }
966
967 assert_valid_tree(tree);
968}
969
971{
972 Tree tree;
973 NodePool pool;
974
975 const int N = 1000;
976 for (int k = 0; k < N; ++k)
977 tree.insert(pool.make(k));
978
979 std::mt19937 gen(33333);
980 std::uniform_int_distribution<> dist(0, N - 1);
981
982 // Simulate access pattern with some keys accessed frequently
983 int hot_key = 500;
984 for (int i = 0; i < 5000; ++i)
985 {
986 int key = (i % 3 == 0) ? hot_key : dist(gen);
987 auto * found = tree.search(key);
988 ASSERT_NE(found, nullptr);
989 EXPECT_EQ(KEY(found), key);
990 }
991
992 // Hot key should be near root due to splay property
993 assert_valid_tree(tree);
994}
WeightedDigraph::Node Node
@ KEY
Definition btreepic.C:169
T & insert(const T &item)
Insert a new item by copy.
Definition htlist.H:1502
void empty() noexcept
empty the list
Definition htlist.H:1689
DynList & swap(DynList &l) noexcept
Swap this with l.
Definition htlist.H:1448
bool is_empty() const noexcept
Return true if the tree is empty.
bool verify() const
Return true if this is a consistent randomized tree.
Node * remove(const Key &key) noexcept
Remove a key from the tree.
NodeType< Key > Node
Node * search_or_insert(Node *p) noexcept
Search or insert a key.
Node * insert_dup(Node *p) noexcept
Insert a node in the tree.
Node * insert(Node *p) noexcept
Insert a node in the tree.
size_t size() const noexcept
Return the number of nodes that have the tree.
Node * select(const size_t i) const
Return the i-th node in inorder sense.
Node *& getRoot() noexcept
Return the tree's root.
Node * search(const Key &key) const noexcept
Search a key.
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
Top-down splay tree with rank support.
void forget(Node *p)
Definition rand-tree.cc:93
Node * make(int key)
Definition rand-tree.cc:86
iterator end() noexcept
Return an STL-compatible end iterator.
iterator begin() noexcept
Return an STL-compatible iterator to the first element.
#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:4060
void delete_tree(Tree_Node< T > *node)
DynArray< Graph::Node * > nodes
Definition graphpic.C:406
std::pair< long, Node * > position(const Key &key) const noexcept
Compute the inorder position of a key.
constexpr Node *& RLINK(Node *p) noexcept
Return the right tree of p.
auto & COUNT(Node *p) noexcept
Return the number of nodes of the tree fron p is root.
constexpr Node *& LLINK(Node *p) noexcept
Return a pointer to left subtree.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
DynList< T > maps(const C &c, Op op)
Classic map operation.
std::vector< int > inorder_keys(NodeT *root)
Definition rand-tree.cc:59
Top-down splay tree with rank support.