Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_binNodeGenerators_test.cc
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 https://github.com/lrleon/Aleph-w
6
7 This file is part of Aleph-w library
8
9 Copyright (c) 2002-2026 Leandro Rabindranath Leon
10
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28*/
29
41#include <vector>
42
43#include <gtest/gtest.h>
44
45#include <tpl_binNode.H>
47#include <tpl_binNodeUtils.H>
48
49using namespace Aleph;
50
51namespace
52{
53// Owns every node allocated for a test tree and frees them on destruction.
54struct NodePool
55{
56 std::vector<BinNode<int> *> allocated;
57
58 BinNode<int> *make(int k)
59 {
60 auto *p = new BinNode<int>(k);
61 allocated.push_back(p);
62 return p;
63 }
64
65 ~NodePool()
66 {
67 for (BinNode<int> *p : allocated)
68 delete p;
69 }
70};
71
72// Builds the complete binary tree with root 4, children 2 and 6, and
73// grandchildren 1, 3, 5, 7 (in that left-to-right order).
74BinNode<int> *build_balanced(NodePool &pool)
75{
76 BinNode<int> *n1 = pool.make(1);
77 BinNode<int> *n2 = pool.make(2);
78 BinNode<int> *n3 = pool.make(3);
79 BinNode<int> *n4 = pool.make(4);
80 BinNode<int> *n5 = pool.make(5);
81 BinNode<int> *n6 = pool.make(6);
82 BinNode<int> *n7 = pool.make(7);
83
84 n4->getL() = n2;
85 n4->getR() = n6;
86 n2->getL() = n1;
87 n2->getR() = n3;
88 n6->getL() = n5;
89 n6->getR() = n7;
90 return n4;
91}
92
93// Right-degenerate chain 1 -> 2 -> 3 -> ... -> n (every node's right child
94// is the next one; no left children). Exercises O(n)-deep traversal state.
95BinNode<int> *build_degenerate_chain(NodePool &pool, int n)
96{
97 BinNode<int> *root = pool.make(1);
98 BinNode<int> *tail = root;
99 for (int k = 2; k <= n; ++k)
100 {
101 BinNode<int> *next = pool.make(k);
102 tail->getR() = next;
103 tail = next;
104 }
105 return root;
106}
107
108template <class Node>
109std::vector<int> eager_in_order(Node *root)
110{
111 std::vector<int> keys;
112 for_each_in_order<Node>(root, [&](Node *p) { keys.push_back(KEY(p)); });
113 return keys;
114}
115
116template <class Node>
117std::vector<int> eager_pre_order(Node *root)
118{
119 std::vector<int> keys;
120 for_each_preorder<Node>(root, [&](Node *p) { keys.push_back(KEY(p)); });
121 return keys;
122}
123
124template <class Node>
125std::vector<int> eager_post_order(Node *root)
126{
127 std::vector<int> keys;
128 for_each_postorder<Node>(root, [&](Node *p) { keys.push_back(KEY(p)); });
129 return keys;
130}
131
132template <class Node>
133std::vector<int> lazy_in_order_keys(Node *root)
134{
135 std::vector<int> keys;
136 for (Node *n : lazy_in_order(root))
137 keys.push_back(KEY(n));
138 return keys;
139}
140
141template <class Node>
142std::vector<int> lazy_pre_order_keys(Node *root)
143{
144 std::vector<int> keys;
145 for (Node *n : lazy_pre_order(root))
146 keys.push_back(KEY(n));
147 return keys;
148}
149
150template <class Node>
151std::vector<int> lazy_post_order_keys(Node *root)
152{
153 std::vector<int> keys;
154 for (Node *n : lazy_post_order(root))
155 keys.push_back(KEY(n));
156 return keys;
157}
158} // namespace
159
166
168{
169 NodePool pool;
170 BinNode<int> *root = pool.make(42);
171 EXPECT_EQ(lazy_in_order_keys(root), (std::vector<int>{42}));
172 EXPECT_EQ(lazy_pre_order_keys(root), (std::vector<int>{42}));
173 EXPECT_EQ(lazy_post_order_keys(root), (std::vector<int>{42}));
174}
175
177{
178 NodePool pool;
179 BinNode<int> *root = build_balanced(pool);
181 EXPECT_EQ(lazy_in_order_keys(root), (std::vector<int>{1, 2, 3, 4, 5, 6, 7}));
182}
183
185{
186 NodePool pool;
187 BinNode<int> *root = build_balanced(pool);
189 EXPECT_EQ(lazy_pre_order_keys(root), (std::vector<int>{4, 2, 1, 3, 6, 5, 7}));
190}
191
193{
194 NodePool pool;
195 BinNode<int> *root = build_balanced(pool);
197 EXPECT_EQ(lazy_post_order_keys(root), (std::vector<int>{1, 3, 2, 5, 7, 6, 4}));
198}
199
201{
202 NodePool pool;
203 BinNode<int> *root = build_balanced(pool);
204
205 std::vector<int> seen;
207 {
208 seen.push_back(KEY(n));
209 if (KEY(n) == 3)
210 break;
211 }
212 // In-order of the balanced tree starts 1, 2, 3, ...; must stop right there.
213 EXPECT_EQ(seen, (std::vector<int>{1, 2, 3}));
214}
215
217{
218 constexpr int n = 500; // deep enough to exercise explicit stack state
219 NodePool pool;
221
222 std::vector<int> expected(n);
223 for (int i = 0; i < n; ++i)
224 expected[i] = i + 1;
225
226 // A right-only chain is its own pre-order, in-order and post-order... in
227 // different shapes: in-order and pre-order both visit root-then-right
228 // recursively so they coincide with the chain order; post-order visits
229 // right subtree fully before the (chain) root, i.e. reverse order.
235
236 std::vector<int> reversed(expected.rbegin(), expected.rend());
238}
WeightedDigraph::Node Node
@ KEY
Definition btreepic.C:169
Node for binary search tree.
BinNode *& getR() noexcept
BinNode *& getL() noexcept
Minimal std::expected-style result type for C++20.
Node * make(int key)
Definition rand-tree.cc:87
#define TEST(name)
__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:4071
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
Aleph::Generator< Node * > lazy_in_order(Node *root)
Lazily traverse a binary tree in-order (left, node, right).
Aleph::Generator< Node * > lazy_post_order(Node *root)
Lazily traverse a binary tree post-order (left, right, node).
Aleph::Generator< Node * > lazy_pre_order(Node *root)
Lazily traverse a binary tree pre-order (node, left, right).
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
void next()
Advance all underlying iterators (bounds-checked).
Definition ah-zip.H:171
int keys[]
static int * k
Lazy (coroutine-based) traversals of binary trees.
Utility functions for binary tree operations.
Basic binary tree node definitions.