45#include <gtest/gtest.h>
51using namespace testing;
63 std::vector<Node *> allocated;
67 auto * p =
new Node(
k);
68 allocated.push_back(p);
74 for (
auto & q : allocated)
84 for (
const auto * p : allocated)
91 std::vector<HybridNode *> allocated;
96 allocated.push_back(p);
102 for (
auto & q : allocated)
112 for (
const auto * p : allocated)
119 std::vector<int> keys;
120 if (
root == Node::NullPtr)
124 keys.insert(keys.end(), left.begin(), left.end());
127 keys.insert(keys.end(), right.begin(), right.end());
133 if (
root == Node::NullPtr)
146 return tree.
getRoot() == Node::NullPtr;
149 template <
typename NodeT>
152 if (
root == NodeT::NullPtr)
157 template <
typename NodeT>
160 std::vector<int> keys;
161 if (
root == NodeT::NullPtr)
165 keys.insert(keys.end(), left.begin(), left.end());
168 keys.insert(keys.end(), right.begin(), right.end());
174 ASSERT_TRUE(tree.verify()) <<
"HtdRbTree red-black invariant violated";
197 auto * p = pool.make(42);
212 for (
int k : {5, 3, 7, 1, 4, 6, 8})
214 auto * p = pool.make(
k);
222 EXPECT_EQ(keys, (std::vector<int>{1, 3, 4, 5, 6, 7, 8}));
230 auto * p1 = pool.make(10);
233 auto * p2 = pool.make(10);
260 auto * dup = pool.make(5);
261 EXPECT_EQ(tree.
insert(dup),
nullptr) <<
"Should reject duplicate at intermediate level";
282 auto * dup = pool.make(10);
283 EXPECT_EQ(tree.
insert(dup),
nullptr) <<
"Should reject duplicate after left descents";
295 for (
int k : {50, 25, 75, 10, 30, 60, 80, 5, 15, 27, 35})
300 EXPECT_EQ(tree.
insert(pool.make(25)),
nullptr) <<
"Duplicate at level 1";
301 EXPECT_EQ(tree.
insert(pool.make(10)),
nullptr) <<
"Duplicate at level 2";
302 EXPECT_EQ(tree.
insert(pool.make(5)),
nullptr) <<
"Duplicate at deepest level";
303 EXPECT_EQ(tree.
insert(pool.make(35)),
nullptr) <<
"Duplicate after mixed descent";
314 for (
int i = 0; i < 5; ++i)
321 EXPECT_EQ(keys, (std::vector<int>{42, 42, 42, 42, 42}));
329 for (
int k : {1, 2, 3, 4, 5})
332 for (
int k : {1, 2, 3, 4, 5})
347 for (
int k : {1, 3, 5})
364 auto * p1 = pool.make(10);
370 auto * p2 = pool.make(10);
388 for (
int k : {1, 2, 3, 4, 5})
402 EXPECT_EQ(keys, (std::vector<int>{1, 2, 4, 5}));
410 for (
int k : {1, 3, 5})
433 tree.
insert(pool.make(5));
434 tree.
insert(pool.make(3));
435 tree.
insert(pool.make(7));
452 std::vector<int> keys = {5, 3, 7, 1, 4, 6, 8};
473 for (
int k = 1;
k <= 10; ++
k)
476 for (
int k = 1;
k <= 10; ++
k)
493 for (
int k = 1;
k <= 10; ++
k)
496 for (
int k = 10;
k >= 1; --
k)
513 constexpr int key = 7;
514 for (
int i = 0; i < 4; ++i)
517 for (
int remaining = 4; remaining > 0; --remaining)
526 static_cast<size_t>(remaining - 1));
543 tree.
insert(pool.make(5));
546 tree.
insert(pool.make(3));
547 tree.
insert(pool.make(7));
548 tree.
insert(pool.make(1));
549 tree.
insert(pool.make(4));
560 for (
int k : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
572 std::mt19937
rng(42);
573 std::uniform_int_distribution<int> dist(0, 1000);
575 for (
int i = 0; i < 100; ++i)
577 auto * p = pool.make(dist(
rng));
594 auto * p = pool.make(42);
611 for (
int k = 10;
k >= 1; --
k)
618 EXPECT_EQ(keys, (std::vector<int>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
626 for (
int k = 1;
k <= 10; ++
k)
633 EXPECT_EQ(keys, (std::vector<int>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
643 using NodeGt = TreeGt::Node;
646 std::vector<NodeGt *>
nodes;
648 for (
int k : {1, 2, 3, 4, 5})
655 EXPECT_EQ(count_nodes(tree.getRoot()), 5u);
659 std::vector<int> keys;
661 if (r == NodeGt::NullPtr)
return;
663 keys.push_back(
KEY(r));
668 EXPECT_EQ(keys, (std::vector<int>{5, 4, 3, 2, 1}));
670 for (
auto * p :
nodes)
684 std::mt19937
rng(42);
685 std::uniform_int_distribution<int> dist(0, 500);
688 for (
int i = 0; i < 200; ++i)
691 auto * p = pool.make(
k);
692 if (tree.
insert(p) !=
nullptr)
709 for (
int i = 0; i < 100; ++i)
725 for (
int i = 0; i < 150; ++i)
757 for (
int k = 0;
k <
N; ++
k)
764 for (
int k = 0;
k <
N;
k += 2)
793 std::vector<int>
expected = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
797 std::vector<int> result;
799 result.push_back(
KEY(it.get_curr()));
809 for (
int k : {1, 2, 3, 4, 5})
816 std::vector<int> result;
818 result.push_back(
KEY(it.get_curr()));
820 EXPECT_EQ(result, (std::vector<int>{1, 2, 4, 5}));
832 for (
int k : {5, 3, 7, 1, 4, 6, 8})
849 tree.
insert(pool.make(1));
865 for (
int k = 1;
k <= 10; ++
k)
871 for (
int k = 1;
k <= 5; ++
k)
915 auto * p1 =
new Node(1);
916 auto * p2 =
new Node(2);
917 auto * p3 =
new Node(3);
938 auto * p1 =
new Node(1);
939 auto * p2 =
new Node(2);
960 EXPECT_EQ(tree.getRoot(), HybridNode::NullPtr);
973 auto * p1 = pool.make(10);
977 auto * p2 = pool.make(10);
990 for (
int i = 0; i < 5; ++i)
991 ASSERT_NE(tree.insert_dup(pool.make(42)),
nullptr);
1002 HybridNodePool pool;
1004 auto * p1 = pool.make(10);
1005 auto *
ret1 = tree.search_or_insert(p1);
1009 auto * p2 = pool.make(10);
1010 auto *
ret2 = tree.search_or_insert(p2);
1022 HybridNodePool pool;
1024 for (
int k : {1, 2, 3, 4, 5})
1041 HybridNodePool pool;
1043 tree.
insert(pool.make(42));
1059 HybridNodePool pool;
1061 std::vector<int> keys = {5, 3, 7, 1, 4, 6, 8};
1065 std::sort(keys.begin(), keys.end());
1081 HybridNodePool pool;
1083 for (
int k : {1, 3, 5})
1095 HybridNodePool pool;
1097 constexpr int key = 5;
1098 for (
int i = 0; i < 3; ++i)
1099 ASSERT_NE(tree.insert_dup(pool.make(key)),
nullptr);
1101 for (
int remaining = 3; remaining > 0; --remaining)
1109 EXPECT_EQ(tree.size(),
static_cast<size_t>(remaining - 1));
1120 HybridNodePool pool;
1122 std::vector<int>
expected = {1, 2, 3, 4, 5, 6, 7};
1123 for (
int k : {4, 2, 6, 1, 3, 5, 7})
1126 std::vector<int>
got;
1127 for (HybridTree::Iterator it(tree); it.has_curr(); it.next())
1128 got.push_back(
KEY(it.get_curr()));
1137 HybridTree::Iterator it(tree);
1146 HybridNodePool pool;
1177 bool operator()(
int a,
int b)
const {
return std::abs(a) < std::abs(b); }
1181 using NodeAbs = TreeAbs::Node;
1201 HybridNodePool pool;
1203 for (
int k : {-5, -3, -1, 0, 1, 3, 5})
1210 EXPECT_EQ(keys, (std::vector<int>{-5, -3, -1, 0, 1, 3, 5}));
1220 HybridNodePool pool;
1223 std::mt19937
rng(123);
1224 std::uniform_int_distribution<int> dist(0, 500);
1227 for (
int i = 0; i < 200; ++i)
1230 auto * p = pool.make(
k);
1231 if (tree.insert(p) !=
nullptr)
1248 for (
int i = 0; i < 100; ++i)
1251 auto *
found = tree.search(
k);
1262 for (
int i = 0; i < 150; ++i)
1289 HybridNodePool pool;
1291 auto * p = pool.make(42);
1295 EXPECT_NE(tree.getRoot(), HybridNode::NullPtr);
1304 HybridNodePool pool;
1306 for (
int k : {5, 3, 7, 1, 4, 6, 8})
1307 ASSERT_NE(tree.insert(pool.make(
k)),
nullptr);
1313 EXPECT_EQ(keys, (std::vector<int>{1, 3, 4, 5, 6, 7, 8}));
1319 HybridNodePool pool;
1321 for (
int k : {1, 2, 3, 4, 5})
1324 for (
int k : {1, 2, 3, 4, 5})
1326 auto *
found = tree.search(
k);
1337 HybridNodePool pool;
1339 for (
int k : {1, 3, 5})
1361 HybridNodePool pool;
1363 tree.
insert(pool.make(5));
1364 tree.insert(pool.make(3));
1365 tree.insert(pool.make(7));
1380 HybridNodePool pool;
1382 for (
int k = 1;
k <= 10; ++
k)
1385 for (
int k = 10;
k >= 1; --
k)
1400 HybridNodePool pool;
1402 for (
int k = 10;
k >= 1; --
k)
1409 EXPECT_EQ(keys, (std::vector<int>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
1415 HybridNodePool pool;
1417 for (
int k = 1;
k <= 10; ++
k)
1424 EXPECT_EQ(keys, (std::vector<int>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
1430 HybridNodePool pool;
1434 for (
int k = 0;
k <
N; ++
k)
1437 EXPECT_EQ(tree.size(),
static_cast<size_t>(
N));
1441 for (
int k = 0;
k <
N;
k += 2)
1449 EXPECT_EQ(tree.size(),
static_cast<size_t>(
N / 2));
1456 using NodeGt = TreeGt::Node;
1460 for (
int k : {1, 2, 3, 4, 5})
1467 std::vector<int> keys;
1468 for (TreeGt::Iterator it(tree); it.has_curr(); it.next())
1469 keys.push_back(
KEY(it.get_curr()));
1471 EXPECT_EQ(keys, (std::vector<int>{5, 4, 3, 2, 1}));
1474 for (
int k : {1, 2, 3, 4, 5})
1475 delete tree.remove(
k);
1481 HybridNodePool pool;
1483 for (
int k : {1, 2, 3, 4, 5})
1490 std::vector<int> result;
1491 for (HybridTree::Iterator it(tree); it.has_curr(); it.next())
1492 result.push_back(
KEY(it.get_curr()));
1494 EXPECT_EQ(result, (std::vector<int>{1, 2, 4, 5}));
1542 using NodeVtl = TreeVtl::Node;
1546 for (
int k : {1, 2, 3, 4, 5})
1556 auto *
found = tree.search(3);
1561 for (
int k : {1, 2, 3, 4, 5})
1576 for (
int k : {-5, -3, -1, 0, 1, 3, 5})
1583 EXPECT_EQ(keys, (std::vector<int>{-5, -3, -1, 0, 1, 3, 5}));
1592 using NodeGt = TreeGt::Node;
1596 for (
int k : {1, 2, 3, 4, 5})
1615 for (
int k : {2, 4, 5})
1616 delete tree.remove(
k);
1629 const int N = 10000;
1630 for (
int k = 0;
k <
N; ++
k)
1641 for (
int k = 0;
k <
N; ++
k)
1650 const int N = 10000;
1651 for (
int k =
N - 1;
k >= 0; --
k)
1669 for (
int i = 0; i <
N; ++i)
1671 int k = (i % 2 == 0) ? i / 2 :
N - 1 - i / 2;
1685 std::mt19937
gen(98765);
1686 std::uniform_int_distribution<>
key_dist(0, 50000);
1687 std::uniform_int_distribution<>
op_dist(0, 2);
1696 auto * p = pool.make(key);
1697 if (tree.
insert(p) !=
nullptr)
1729 if (
iter % 2000 == 0)
1744 const int N = 10000;
1747 for (
int k = 0;
k <
N; ++
k)
1756 std::mt19937
gen(11111);
1777 const int DUPS = 10;
1779 for (
int k = 0;
k <
N; ++
k)
1780 for (
int d = 0; d <
DUPS; ++d)
1787 for (
int k = 0;
k <
N; ++
k)
1788 for (
int d = 0; d <
DUPS; ++d)
1805 std::mt19937
gen(22222);
1806 std::uniform_int_distribution<>
key_dist(0, 1000);
1814 auto * p = pool.make(key);
1815 if (tree.
insert(p) !=
nullptr)
1845 using StrNode = StrTree::Node;
1848 std::vector<StrNode*>
nodes;
1849 std::set<std::string>
oracle;
1851 std::mt19937
gen(33333);
1855 int len = 5 +
gen() % 20;
1856 for (
int i = 0; i < len; ++i)
1857 s +=
'a' +
gen() % 26;
1862 for (
int i = 0; i < 2000; ++i)
1867 if (tree.insert(p) !=
nullptr)
1875 for (
const auto & key :
oracle)
1879 for (
auto * p :
nodes)
1887 HybridNodePool pool;
1890 std::mt19937
gen(44444);
1891 std::uniform_int_distribution<>
key_dist(0, 10000);
1892 std::uniform_int_distribution<>
op_dist(0, 2);
1901 auto * p = pool.make(key);
1902 if (tree.insert(p) !=
nullptr)
1924 auto *
found = tree.search(key);
static string random_string(std::mt19937 &rng, size_t len)
WeightedDigraph::Node Node
bool has_curr() const noexcept
Return true the iterator has current node.
T & insert(const T &item)
Insert a new item by copy.
T remove()
Remove the first item of the list.
void empty() noexcept
empty the list
DynList & swap(DynList &l) noexcept
Swap this with l.
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.
Node * search_or_insert(Node *p) noexcept
Search or insert a key.
Compare & key_comp() noexcept
return the comparison criteria
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 *& getRoot() noexcept
Return the tree's root.
Node * search(const Key &key) const noexcept
Search a key.
Red-black binary search tree implementation (bottom-up).
constexpr bool is_empty() const noexcept
Return true if list is empty.
size_t size() const noexcept
Count the number of elements of the list.
Hybrid top-down/bottom-up red-black tree.
iterator end() noexcept
Return an STL-compatible end iterator.
iterator begin() noexcept
Return an STL-compatible iterator to the first element.
__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)
DynArray< Graph::Node * > nodes
bool check_bst(Node *p, const Compare &cmp=Compare())
Return true if p is a binary search tree.
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.
DynList< T > maps(const C &c, Op op)
Classic map operation.
std::vector< int > inorder_keys(NodeT *root)
Iterator on nodes of the tree.
Red-black tree with virtual destructor in nodes.
Red-black tree with nodes without virtual destructor.
Hybrid top-down/bottom-up red-black tree implementation.
Red-Black tree implementation (bottom-up balancing).