Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
bin-node-utils.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 <cctype>
40#include <random>
41#include <sstream>
42#include <set>
43#include <stdexcept>
44#include <string>
45#include <vector>
46
47#include <gtest/gtest.h>
48
49#include <tpl_binNode.H>
50#include <tpl_binNodeUtils.H>
51#include <tpl_dynArray.H>
52
53using namespace Aleph;
54using namespace testing;
55
56namespace
57{
58 static std::vector<int> * g_visit_acc = nullptr;
59
60 static void visit_push_key(BinNode<int> * p)
61 {
62 if (g_visit_acc != nullptr)
63 g_visit_acc->push_back(KEY(p));
64 }
65
66 struct NodePool
67 {
68 std::vector<BinNode<int> *> allocated;
69
70 BinNode<int> * make(int k)
71 {
72 auto * p = new BinNode<int>(k);
73 allocated.push_back(p);
74 return p;
75 }
76 ~NodePool()
77 {
78 for (const auto * p : allocated)
79 delete p;
80 }
81 };
82
83 template <class Node>
84 std::vector<typename Node::key_type> inorder(Node * root)
85 {
86 std::vector<typename Node::key_type> keys;
87 Aleph::infix_for_each<Node>(root, [&] (Node * p) { keys.push_back(KEY(p)); });
88 return keys;
89 }
90
92 {
94 auto keys = inorder(root);
95 ASSERT_TRUE(std::is_sorted(keys.begin(), keys.end()));
96 }
97
98 template <class Node>
99 void delete_tree(Node * root) noexcept
100 {
101 if (root == Node::NullPtr)
102 return;
105 delete root;
106 }
107
108 struct LoadIntKey
109 {
110 bool operator()(BinNode<int> * p, const char * str) const
111 {
112 if (str == nullptr)
113 return false;
114 p->get_key() = std::stoi(str);
115 return true;
116 }
117 };
118
119 struct GetIntKey
120 {
121 std::string operator()(BinNode<int> * p) const
122 {
123 return std::to_string(KEY(p));
124 }
125 };
126
127 std::vector<BinNode<int> *> as_vector(const DynList<BinNode<int> *> & l)
128 {
129 std::vector<BinNode<int> *> v;
130 for (auto it = l.get_it(); it.has_curr(); it.next_ne())
131 v.push_back(it.get_curr_ne());
132 return v;
133 }
134
135 std::vector<BinNode<int> *> as_vector(const DynDlist<BinNode<int> *> & l)
136 {
137 std::vector<BinNode<int> *> v;
138 for (auto it = l.get_it(); it.has_curr(); it.next_ne())
139 v.push_back(it.get_curr_ne());
140 return v;
141 }
142
143 std::vector<int> keys_from_nodes(const std::vector<BinNode<int> *> & nodes)
144 {
145 std::vector<int> out;
146 out.reserve(nodes.size());
147 for (auto * p : nodes)
148 out.push_back(KEY(p));
149 return out;
150 }
151
152 std::vector<unsigned char> parse_uc_array(const std::string & s, const std::string & var_name)
153 {
154 const std::string needle = "const unsigned char " + var_name;
155 auto pos = s.find(needle);
156 if (pos == std::string::npos)
157 return {};
158
159 pos = s.find('{', pos);
160 if (pos == std::string::npos)
161 return {};
162
163 auto end = s.find('}', pos);
164 if (end == std::string::npos)
165 return {};
166
167 std::vector<unsigned char> bytes;
168 std::string inside = s.substr(pos + 1, end - pos - 1);
169 std::stringstream ss(inside);
170 while (ss)
171 {
172 int val;
173 if (!(ss >> val))
174 break;
175 bytes.push_back(static_cast<unsigned char>(val));
176 while (ss && (ss.peek() == ',' || std::isspace(ss.peek())))
177 ss.get();
178 }
179 return bytes;
180 }
181
182 std::vector<std::string> parse_key_array(const std::string & s, const std::string & var_name)
183 {
184 const std::string needle = "const char * " + var_name + "[]";
185 auto pos = s.find(needle);
186 if (pos == std::string::npos)
187 return {};
188
189 pos = s.find('{', pos);
190 if (pos == std::string::npos)
191 return {};
192
193 auto end = s.find("};", pos);
194 if (end == std::string::npos)
195 return {};
196
197 std::string inside = s.substr(pos + 1, end - pos - 1);
198
199 std::vector<std::string> storage;
200 size_t i = 0;
201 while (i < inside.size())
202 {
203 while (i < inside.size() &&
204 (std::isspace(static_cast<unsigned char>(inside[i])) || inside[i] == ','))
205 ++i;
206 if (i >= inside.size())
207 break;
208
209 if (inside.compare(i, 7, "nullptr") == 0)
210 {
211 i += 7;
212 break;
213 }
214
215 if (inside[i] != '"')
216 break;
217 ++i;
218
219 std::string token;
220 while (i < inside.size() && inside[i] != '"')
221 {
222 if (inside[i] == '\\' && i + 1 < inside.size())
223 {
224 char esc = inside[i + 1];
225 if (esc == 'n')
226 token.push_back('\n');
227 else if (esc == 't')
228 token.push_back('\t');
229 else
230 token.push_back(esc);
231 i += 2;
232 continue;
233 }
234 token.push_back(inside[i++]);
235 }
236 if (i >= inside.size())
237 break;
238 ++i;
239 storage.push_back(token);
240 }
241 return storage;
242 }
243}
244
246{
247 NodePool pool;
248 auto * root = pool.make(2);
249 LLINK(root) = pool.make(1);
250 RLINK(root) = pool.make(3);
251
253 auto in_nodes = Aleph::infix(root);
255
256 EXPECT_EQ(keys_from_nodes(as_vector(pre_nodes)), (std::vector<int>{2, 1, 3}));
257 EXPECT_EQ(keys_from_nodes(as_vector(in_nodes)), (std::vector<int>{1, 2, 3}));
258 EXPECT_EQ(keys_from_nodes(as_vector(post_nodes)), (std::vector<int>{1, 3, 2}));
259}
260
262{
263 NodePool pool;
264 auto * root = pool.make(2);
265 LLINK(root) = pool.make(1);
266 RLINK(root) = pool.make(3);
267
268 std::vector<int> in, pre, post;
269 Aleph::for_each_in_order<BinNode<int>>(root, [&] (BinNode<int> * p) { in.push_back(KEY(p)); });
270 Aleph::for_each_preorder<BinNode<int>>(root, [&] (BinNode<int> * p) { pre.push_back(KEY(p)); });
271 Aleph::for_each_postorder<BinNode<int>>(root, [&] (BinNode<int> * p) { post.push_back(KEY(p)); });
272
273 EXPECT_EQ(in, (std::vector<int>{1, 2, 3}));
274 EXPECT_EQ(pre, (std::vector<int>{2, 1, 3}));
275 EXPECT_EQ(post, (std::vector<int>{1, 3, 2}));
276}
277
279{
280 NodePool pool;
281 auto * root = pool.make(4);
282 LLINK(root) = pool.make(2);
283 RLINK(root) = pool.make(6);
284 LLINK(LLINK(root)) = pool.make(1);
285 RLINK(LLINK(root)) = pool.make(3);
286 LLINK(RLINK(root)) = pool.make(5);
287 RLINK(RLINK(root)) = pool.make(7);
288
289 auto l0 = compute_nodes_in_level(root, 0);
290 auto l1 = compute_nodes_in_level(root, 1);
291 auto l2 = compute_nodes_in_level(root, 2);
292
293 EXPECT_EQ(keys_from_nodes(as_vector(l0)), (std::vector<int>{4}));
294 EXPECT_EQ(keys_from_nodes(as_vector(l1)), (std::vector<int>{2, 6}));
295 EXPECT_EQ(keys_from_nodes(as_vector(l2)), (std::vector<int>{1, 3, 5, 7}));
296}
297
299{
300 NodePool pool;
301 auto * root = pool.make(2);
302 LLINK(root) = pool.make(1);
303 RLINK(root) = pool.make(3);
304
305 EXPECT_EQ(internal_path_length(root), 0u + 1u + 1u);
306}
307
309{
310 DynArray<int> pre(7);
311 pre[0] = 4; pre[1] = 2; pre[2] = 1; pre[3] = 3; pre[4] = 6; pre[5] = 5; pre[6] = 7;
312 DynArray<int> in(7);
313 in[0] = 1; in[1] = 2; in[2] = 3; in[3] = 4; in[4] = 5; in[5] = 6; in[6] = 7;
314
315 auto * root = build_tree<BinNode, int>(pre, 0, 6, in, 0, 6);
316 EXPECT_EQ(inorder(root), (std::vector<int>{1, 2, 3, 4, 5, 6, 7}));
319}
320
322{
324 post[0] = 1; post[1] = 3; post[2] = 2; post[3] = 5; post[4] = 7; post[5] = 6; post[6] = 4;
325 DynArray<int> in(7);
326 in[0] = 1; in[1] = 2; in[2] = 3; in[3] = 4; in[4] = 5; in[5] = 6; in[6] = 7;
327
328 auto * root = build_postorder<BinNode, int>(post, 0, 6, in, 0, 6);
329 EXPECT_EQ(inorder(root), (std::vector<int>{1, 2, 3, 4, 5, 6, 7}));
332}
333
335{
336 NodePool pool;
337 auto * root = pool.make(2);
338 LLINK(root) = pool.make(1);
339 RLINK(root) = pool.make(3);
340
341 std::stringstream ss;
342 save_tree(root, ss);
344
345 EXPECT_EQ(inorder(loaded), (std::vector<int>{1, 2, 3}));
348}
349
351{
352 auto * root = new BinNode<int>(0);
353 LLINK(root) = new BinNode<int>(0);
354
355 std::stringstream ss;
356 ss << 1;
357
358 EXPECT_THROW(load_tree_keys_in_prefix(root, ss), std::runtime_error);
359
361}
362
364{
365 NodePool pool;
366 auto * root = pool.make(2);
367 LLINK(root) = pool.make(1);
368 RLINK(root) = pool.make(3);
369
370 std::ostringstream out;
371 const std::string name = "t";
373
374 const std::string gen = out.str();
375
376 auto bytes = parse_uc_array(gen, name + "_cdp");
377 ASSERT_FALSE(bytes.empty());
378
379 const std::string key_var = name + "_k";
382
383 std::vector<const char *> keys;
384 for (auto & s : storage)
385 keys.push_back(s.c_str());
386 keys.push_back(nullptr);
387
388 auto * rebuilt = load_tree_from_array<BinNode<int>, LoadIntKey>(bytes.data(), tree_to_bits(root).size(), keys.data());
389 EXPECT_EQ(inorder(rebuilt), (std::vector<int>{1, 2, 3}));
392}
393
395{
396 auto * root = new BinNode<std::string>("root");
397 LLINK(root) = new BinNode<std::string>("a\"b");
398 RLINK(root) = new BinNode<std::string>("c\\d");
399
400 struct GetKey
401 {
402 std::string operator()(BinNode<std::string> * p) const { return KEY(p); }
403 };
404
405 struct LoadKey
406 {
407 bool operator()(BinNode<std::string> * p, const char * str) const
408 {
409 if (str == nullptr)
410 return false;
411 p->get_key() = str;
412 return true;
413 }
414 };
415
416 std::ostringstream out;
417 const std::string name = "s";
419
420 const std::string gen = out.str();
421 auto bytes = parse_uc_array(gen, name + "_cdp");
422 ASSERT_FALSE(bytes.empty());
423
424 auto storage = parse_key_array(gen, name + "_k");
426
427 std::vector<const char *> keys;
428 for (auto & s : storage)
429 keys.push_back(s.c_str());
430 keys.push_back(nullptr);
431
433 bytes.data(), tree_to_bits(root).size(), keys.data());
434
436 (std::vector<std::string>{"a\"b", "root", "c\\d"}));
437
440}
441
443{
444 NodePool pool;
445 auto * root = pool.make(4);
446 LLINK(root) = pool.make(2);
447 RLINK(root) = pool.make(6);
448 LLINK(LLINK(root)) = pool.make(1);
449 RLINK(LLINK(root)) = pool.make(3);
450 LLINK(RLINK(root)) = pool.make(5);
451 RLINK(RLINK(root)) = pool.make(7);
452
454 auto before_in = inorder(root);
455
456 std::vector<int> visited_in;
459 g_visit_acc = nullptr;
461
462 std::vector<int> visited_pre;
465 g_visit_acc = nullptr;
466 EXPECT_EQ(visited_pre, (std::vector<int>{4, 2, 1, 3, 6, 5, 7}));
467
471}
472
487
500
502{
503 NodePool pool;
504 auto * root = pool.make(10);
505 LLINK(root) = pool.make(5);
506 RLINK(root) = pool.make(15);
507 RLINK(LLINK(root)) = pool.make(12);
508
510}
511
513{
514 NodePool pool;
516
517 auto * p = pool.make(5);
519
520 auto * q = pool.make(5);
521 auto * got = search_or_insert_in_bst(root, q);
522 EXPECT_NE(got, q);
523 EXPECT_EQ(KEY(got), 5);
524
526}
527
547
549{
550 NodePool pool;
553
554 for (int k : {1, 2, 3})
556 for (int k : {4, 5, 6})
558
559 auto * out = join_exclusive<BinNode<int>>(a, b);
562
564 EXPECT_EQ(inorder(out), (std::vector<int>{1, 2, 3, 4, 5, 6}));
565}
566
568{
569 NodePool pool;
572
573 for (int k : {1, 2})
575 for (int k : {2, 3})
577
579 auto * out = join_preorder(t1, t2, dup);
580
582 EXPECT_EQ(inorder(out), (std::vector<int>{1, 2, 3}));
584 EXPECT_EQ(inorder(dup), (std::vector<int>{2}));
585}
586
588{
589 NodePool pool;
592
593 for (int k : {2, 1})
595 for (int k : {2, 3})
597
599 auto * out = join(t1, t2, dup);
600
602 EXPECT_EQ(inorder(out), (std::vector<int>{1, 2, 3}));
604 EXPECT_EQ(inorder(dup), (std::vector<int>{2}));
605}
606
625
627{
628 NodePool pool;
630 for (int k : {1, 2, 3, 4, 5})
632
635
636 split_key_dup_rec(root, 3, l, r);
638
641
642 EXPECT_EQ(inorder(l), (std::vector<int>{1, 2}));
643 EXPECT_EQ(inorder(r), (std::vector<int>{3, 4, 5}));
644}
645
647{
648 NodePool pool;
650 for (int k : {1, 2, 3, 5, 6})
652
655
656 split_key(root, 4, l, r);
658
661
662 EXPECT_EQ(inorder(l), (std::vector<int>{1, 2, 3}));
663 EXPECT_EQ(inorder(r), (std::vector<int>{5, 6}));
664}
665
667{
668 NodePool pool;
670
671 for (int k : {5, 3, 7, 2, 4, 6, 8})
673
675 std::vector<int> got;
676 while (it.has_curr())
677 {
678 got.push_back(KEY(it.get_curr_ne()));
679 it.next_ne();
680 }
681
682 EXPECT_EQ(got, (std::vector<int>{2, 3, 4, 5, 6, 7, 8}));
683}
684
686{
687 NodePool pool;
688
689 auto * p = pool.make(2);
690 LLINK(p) = pool.make(1);
691 RLINK(p) = pool.make(3);
692
693 auto before = inorder(p);
694 auto * q = rotate_to_right(p);
695 auto after = inorder(q);
697
698 auto * r = rotate_to_left(q);
699 auto after2 = inorder(r);
701}
702
704{
705 NodePool pool;
707 for (int k : {5, 3, 7, 2, 4, 6, 8})
709
712}
713
715{
716 NodePool pool;
718 for (int k : {5, 3, 7, 2, 4, 6, 8})
720
721 auto * p = searchInBinTree(root, 5);
723
725 auto * succ = find_successor(p, parent);
727 EXPECT_EQ(KEY(succ), 6);
728
729 auto * q = searchInBinTree(root, 5);
731 auto * pred = find_predecessor(q, parent2);
733 EXPECT_EQ(KEY(pred), 4);
734}
735
737{
738 NodePool pool;
740 for (int k : {5, 3, 7, 2, 4, 6, 8})
742
743 BinNode<int> head;
744 head.reset();
745 RLINK(&head) = root;
746
747 BinNode<int> * parent = &head;
748 auto * got = search_parent(root, 4, parent);
750 EXPECT_EQ(KEY(got), 4);
752 EXPECT_EQ(KEY(parent), 3);
753}
754
756{
757 NodePool pool;
759 for (int k : {5, 3, 7, 2, 4, 6, 8})
761
762 auto * p1 = search_rank_parent(root, 6);
764 EXPECT_EQ(KEY(p1), 6);
765
766 auto * p2 = search_rank_parent(root, 1);
768 EXPECT_EQ(KEY(p2), 2);
769}
770
772{
773 NodePool pool;
775 for (int k : {2, 1, 3})
777
778 auto * p = pool.make(4);
779 auto * new_root = insert_root_rec(root, p);
781 root = new_root;
782
783 EXPECT_EQ(KEY(root), 4);
785}
786
788{
789 NodePool pool;
791 for (int k : {2, 1, 3})
793
794 const auto before = inorder(root);
795 auto * dup = pool.make(2);
798}
799
801{
802 NodePool pool;
804 for (int k : {2, 1, 3})
806
807 auto * existing = pool.make(2);
809
810 auto * fresh = pool.make(4);
812 EXPECT_EQ(KEY(root), 4);
814}
815
817{
818 NodePool pool;
820 for (int k : {2, 1, 3})
822
823 auto * dup = pool.make(2);
826}
827
829{
830 struct Greater
831 {
832 bool operator()(int a, int b) const noexcept { return a > b; }
833 };
834
835 NodePool pool;
837 for (const int k : {1, 2, 3, 4, 5})
838 {
839 auto * inserted = insert_in_bst<BinNode<int>, Greater>(root, pool.make(k), Greater());
841 }
842
843 auto * removed = remove_from_bst<BinNode<int>, Greater>(root, 4, Greater());
845 EXPECT_EQ(KEY(removed), 4);
846
847 EXPECT_TRUE((check_bst<BinNode<int>, Greater>(root, Greater())));
848}
849
851{
852 NodePool pool;
853
854 // Build a small explicit shape:
855 // 2
856 // / right
857 // 1 3
858 auto * root = pool.make(2);
859 LLINK(root) = pool.make(1);
860 RLINK(root) = pool.make(3);
861
862 BitArray bits;
863 tree_to_bits(root, bits);
864
865 int idx = 0;
867
868 const char * keys[] = {"2", "1", "3", nullptr};
869 int key_idx = 0;
871
872 EXPECT_EQ(inorder(rebuilt), (std::vector<int>{1, 2, 3}));
874
876}
877
879{
880 BitArray bits;
881 bits.push(0);
882
883 // bits_to_tree should throw domain_error on malformed/truncated bit array
884 EXPECT_THROW((bits_to_tree<BinNode<int>>(bits)), std::domain_error);
885}
886
888{
889 DynArray<int> pre(7);
890 pre[0] = 5;
891 pre[1] = 3;
892 pre[2] = 2;
893 pre[3] = 4;
894 pre[4] = 7;
895 pre[5] = 6;
896 pre[6] = 8;
897
900 EXPECT_EQ(inorder(root), (std::vector<int>{2, 3, 4, 5, 6, 7, 8}));
901
903}
904
906{
907 NodePool pool;
909
910 std::mt19937 rng(12345);
911 std::uniform_int_distribution<int> dist(0, 200);
912
913 std::set<int> present;
914
915 for (int i = 0; i < 200; ++i)
916 {
917 int k = dist(rng);
918 auto * p = pool.make(k);
919 auto * ins = insert_in_bst(root, p);
922 }
923
925
926 for (int i = 0; i < 100; ++i)
927 {
928 int k = dist(rng);
929 auto * removed = remove_from_bst(root, k);
931 {
933 present.erase(k);
934 }
936 }
937}
WeightedDigraph::Node Node
@ KEY
Definition btreepic.C:169
Inorder iterator on the nodes of a binary tree.
Node * get_curr_ne() const noexcept
Return the current link guaranteeing no exception. Be careful.
bool has_curr() const noexcept
Return true the iterator has current node.
Node for binary search tree.
Key & get_key() noexcept
void reset() noexcept
Contiguous array of bits.
Definition bitArray.H:189
void push(const unsigned int value)
Inserts the value at the end of the array.
Definition bitArray.H:450
constexpr size_t size() const noexcept
Returns the dimension of the bit array.
Definition bitArray.H:334
Dynamic doubly linked list with O(1) size and bidirectional access.
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
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
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
Definition ah-dry.H:190
Node * make(int key)
Definition rand-tree.cc:86
#define TEST(name)
static mt19937 rng
__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
DynList< typename GT::Node * > in_nodes(typename GT::Node *p, SA sa=SA())
Return the nodes connected to the filtered incoming arcs to p.
Definition tpl_graph.H:1856
Node * rotate_to_left(Node *p) noexcept
Rotate to the left the tree with root p
Node * search_rank_parent(Node *root, const typename Node::key_type &key, const Compare &cmp=Compare()) noexcept
Rank search of a key in a binary search tree.
void load_tree_keys_in_prefix(Node *root, std::istream &input)
Load the keys stored in preorder from an input stream.
DynDlist< Node * > compute_nodes_in_level(Node *root, const int &level)
Count the number of nodes in a specific tree level.
Node * join_preorder(Node *t1, Node *t2, Node *&dup, const Compare &cmp=Compare()) noexcept
Union of two binary search trees.
Node * remove_from_bst(Node *&root, const typename Node::key_type &key, const Compare &cmp=Compare()) noexcept
Remove a key from a binary search tree.
Node * find_predecessor(Node *p, Node *&pp) noexcept
Find the inorder predecessor of p
Node * search_parent(Node *root, const typename Node::key_type &key, Node *&parent, const Compare &cmp=Compare()) noexcept
Search a key and find its node and parent.
Node * find_min(Node *root) noexcept
Return the minimum key contained in a binary search tree.
Node * rotate_to_right(Node *p) noexcept
Rotate to the right the tree with root p
bool split_key_rec(Node *&root, const typename Node::key_type &key, Node *&ts, Node *&tg, const Compare &cmp=Compare()) noexcept
Split recursively according to a key.
Node * find_successor(Node *p, Node *&pp) noexcept
Find the inorder successor of p
Node * search_or_insert_in_bst(Node *&r, Node *p, const Compare &cmp=Compare()) noexcept
Search or insert a node in a binary search tree.
void save_tree(Node *root, std::ostream &output)
Store a binary tree in a stream.
void split_key_dup_rec(Node *&root, const typename Node::key_type &key, Node *&ts, Node *&tg, const Compare &cmp=Compare()) noexcept
Split a tree according to a key value.
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.
Node * bits_to_tree(const BitArray &array, int idx=0)
Build a binary tree given its bits code.
Node * insert_in_bst(Node *&r, Node *p, const Compare &cmp=Compare()) noexcept
Insert a node p in a binary search tree.
void tree_to_bits(Node *root, BitArray &array)
Compute a bit code for the binary tree.
size_t internal_path_length(Node *p) noexcept
Compute the internal path length.
void preOrderThreaded(Node *node, void(*visitFct)(Node *))
Traverse preorder a binary tree without recursion and without stack.
void inOrderThreaded(Node *root, void(*visitFct)(Node *))
Traverse inorder a binary tree without recursion and without stack.
Node * searchInBinTree(Node *root, const typename Node::key_type &key, const Compare &cmp=Compare()) noexcept
Search a key in a binary search tree.
Node * insert_dup_in_bst(Node *&root, Node *p, const Compare &cmp=Compare()) noexcept
Insert a node p in a binary search tree.
Node * insert_root(Node *&root, Node *p, const Compare &cmp=Compare()) noexcept
Insert the node p as root of a binary search tree.
Node * insert_dup_root(Node *&root, Node *p, const Compare &cmp=Compare()) noexcept
Insert node p as root of a binary search tree.
constexpr Node *& LLINK(Node *p) noexcept
Return a pointer to left subtree.
Node * insert_root_rec(Node *root, Node *p, const Compare &cmp=Compare()) noexcept
Insert a node as root in a binary search tree.
Node * find_max(Node *root) noexcept
Return the maximum key contained in a binary search tree.
void split_key(Node *&root, const Key &key, Node *&l, Node *&r, const Compare &cmp=Compare()) noexcept
Split a binary search tree according to a key.
Freq_Node * pred
Predecessor node in level-order traversal.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
size_t size(Node *root) noexcept
static void infix(Node *root, DynList< Node * > &acc)
static void suffix(Node *root, DynList< Node * > &acc)
static void prefix(Node *root, DynList< Node * > &acc)
std::ostream & join(const C &c, const std::string &sep, std::ostream &out)
Join elements of an Aleph-style container into a stream.
DynList< T > maps(const C &c, Op op)
Classic map operation.
Utility functions for binary tree operations.
Basic binary tree node definitions.
Lazy and scalable dynamic array implementation.
DynList< int > l
void inorder(int v[], int n, int i)
Write inorder traversal of heap.
Definition writeHeap.C:242