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)
140 ASSERT_TRUE(tree.verify()) <<
"Red-black tree invariant violated";
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";
187 EXPECT_EQ(tree.getRoot(), Node::NullPtr);
197 auto * p = pool.make(42);
198 auto * inserted = tree.
insert(p);
201 EXPECT_NE(tree.getRoot(), Node::NullPtr);
203 EXPECT_EQ(count_nodes(tree.getRoot()), 1u);
212 for (
int k : {5, 3, 7, 1, 4, 6, 8})
214 auto * p = pool.make(
k);
218 EXPECT_EQ(count_nodes(tree.getRoot()), 7u);
230 auto * p1 = pool.make(10);
233 auto * p2 = pool.make(10);
236 EXPECT_EQ(count_nodes(tree.getRoot()), 1u);
260 auto * dup = pool.make(5);
261 EXPECT_EQ(tree.
insert(dup),
nullptr) <<
"Should reject duplicate at intermediate level";
262 EXPECT_EQ(count_nodes(tree.getRoot()), 3u);
282 auto * dup = pool.make(10);
283 EXPECT_EQ(tree.
insert(dup),
nullptr) <<
"Should reject duplicate after left descents";
284 EXPECT_EQ(count_nodes(tree.getRoot()), 3u);
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";
305 EXPECT_EQ(count_nodes(tree.getRoot()), 11u);
314 for (
int i = 0; i < 5; ++i)
315 ASSERT_NE(tree.insert_dup(pool.make(42)),
nullptr);
317 EXPECT_EQ(count_nodes(tree.getRoot()), 5u);
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);
365 auto *
ret1 = tree.search_or_insert(p1);
367 EXPECT_EQ(count_nodes(tree.getRoot()), 1u);
370 auto * p2 = pool.make(10);
371 auto *
ret2 = tree.search_or_insert(p2);
374 EXPECT_EQ(count_nodes(tree.getRoot()), 1u);
388 for (
int k : {1, 2, 3, 4, 5})
397 EXPECT_EQ(count_nodes(tree.getRoot()), 4u);
410 for (
int k : {1, 3, 5})
415 EXPECT_EQ(count_nodes(tree.getRoot()), 3u);
433 tree.
insert(pool.make(5));
434 tree.
insert(pool.make(3));
435 tree.
insert(pool.make(7));
443 EXPECT_EQ(count_nodes(tree.getRoot()), 2u);
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)
515 ASSERT_NE(tree.insert_dup(pool.make(key)),
nullptr);
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)
614 EXPECT_EQ(count_nodes(tree.getRoot()), 10u);
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)
629 EXPECT_EQ(count_nodes(tree.getRoot()), 10u);
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;
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)
760 EXPECT_EQ(count_nodes(tree.getRoot()),
static_cast<size_t>(
N));
764 for (
int k = 0;
k <
N;
k += 2)
772 EXPECT_EQ(count_nodes(tree.getRoot()),
static_cast<size_t>(
N / 2));
783 Tree::Iterator it(tree);
793 std::vector<int>
expected = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
797 std::vector<int> result;
798 for (Tree::Iterator it(tree); it.has_curr(); it.next())
799 result.push_back(
KEY(it.get_curr()));
809 for (
int k : {1, 2, 3, 4, 5})
816 std::vector<int> result;
817 for (Tree::Iterator it(tree); it.has_curr(); it.next())
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)
868 EXPECT_EQ(tree.size(),
static_cast<size_t>(
k));
871 for (
int k = 1;
k <= 5; ++
k)
891 tree1.insert(pool.make(2));
892 tree1.insert(pool.make(3));
894 tree2.insert(pool.make(10));
895 tree2.insert(pool.make(11));
915 auto * p1 =
new Node(1);
916 auto * p2 =
new Node(2);
917 auto * p3 =
new Node(3);
929 delete tree2.remove(1);
930 delete tree2.remove(2);
931 delete tree2.remove(3);
938 auto * p1 =
new Node(1);
939 auto * p2 =
new Node(2);
949 delete tree2.remove(1);
950 delete tree2.remove(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})
1027 auto *
removed = tree.remove(3);
1041 HybridNodePool pool;
1043 tree.
insert(pool.make(42));
1046 auto *
removed = tree.remove(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;
1148 tree1.insert(pool.make(1));
1149 tree1.insert(pool.make(2));
1150 tree1.insert(pool.make(3));
1152 tree2.insert(pool.make(10));
1153 tree2.insert(pool.make(11));
1177 bool operator()(
int a,
int b)
const {
return std::abs(a) < std::abs(b); }
1181 using NodeAbs = TreeAbs::Node;
1187 auto * found = tree.
search(-1);
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);
1292 auto * inserted = tree.insert(p);
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);
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));
1367 auto *
removed = tree.remove(5);
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()));
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})
1486 auto *
removed = tree.remove(3);
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}));
1513 delete tree2.remove(1);
1514 delete tree2.remove(2);
1515 delete tree2.remove(3);
1533 delete tree2.remove(1);
1534 delete tree2.remove(2);
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})
1603 auto *
removed = tree.remove(3);
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)
1637 EXPECT_EQ(tree.size(),
static_cast<size_t>(
N));
1641 for (
int k = 0;
k <
N; ++
k)
1650 const int N = 10000;
1651 for (
int k =
N - 1;
k >= 0; --
k)
1658 EXPECT_EQ(tree.size(),
static_cast<size_t>(
N));
1669 for (
int i = 0; i <
N; ++i)
1671 int k = (i % 2 == 0) ? i / 2 :
N - 1 - i / 2;
1675 EXPECT_EQ(tree.size(),
static_cast<size_t>(
N));
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)
1705 else if (op == 1 && !
oracle.empty())
1708 auto it =
oracle.begin();
1709 std::advance(it,
gen() %
oracle.size());
1720 auto * found = tree.
search(key);
1729 if (
iter % 2000 == 0)
1744 const int N = 10000;
1747 for (
int k = 0;
k <
N; ++
k)
1750 EXPECT_EQ(tree.size(),
static_cast<size_t>(
N));
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)
1781 tree.insert_dup(pool.make(
k));
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)
1823 else if (!
oracle.empty())
1825 auto it =
oracle.begin();
1826 std::advance(it,
gen() %
oracle.size());
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)
1910 else if (op == 1 && !
oracle.empty())
1912 auto it =
oracle.begin();
1913 std::advance(it,
gen() %
oracle.size());
1924 auto * found = tree.search(key);
static string random_string(std::mt19937 &rng, size_t len)
WeightedDigraph::Node Node
Red-black binary search tree implementation (bottom-up).
Hybrid top-down/bottom-up red-black tree.
QuadTree - Hierarchical spatial index for 2D points.
void remove(const Point &p)
Remove a point from the tree.
Point * search(const Point &p) noexcept
Search for a point in the tree.
Point * insert(Node *&r, const Point &p)
Recursive insert helper.
__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.
Main namespace for Aleph-w library functions.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
std::vector< int > inorder_keys(NodeT *root)
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).