Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_binNodeXt.H
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
43# ifndef TPL_BINNODEXT_H
44# define TPL_BINNODEXT_H
45
46# include <ah-concepts.H>
47
48# include <tpl_binNode.H>
49# include <tpl_binNodeUtils.H>
50
51using namespace Aleph;
52
53namespace Aleph {
54
56{
57 size_t count; // Cardinality of the tree
58
59public:
60
63
64 size_t & getCount() noexcept { return count; }
65 size_t size() const noexcept { return count; }
66
67 void reset() noexcept { count = 1; }
68};
69
77
83template <RankedBinNodeLike Node> inline auto & COUNT(Node * p) noexcept
84{
85 return p->getCount();
86}
87
88
89 template <RankedBinNodeLike Node> static inline
90Node * __select_rec(Node * r, const size_t i) noexcept
91{
92 assert(r != Node::NullPtr);
93 assert(COUNT(Node::NullPtr) == 0);
94
95 if (i == COUNT(LLINK(r)))
96 return r;
97
98 if (i < COUNT(LLINK(r)))
99 return __select_rec(LLINK(r), i);
100
101 return __select_rec(RLINK(r), i - COUNT(LLINK(r)) - 1);
102}
103
115 template <RankedBinNodeLike Node> inline
116Node * select_rec(Node * r, const size_t i)
117{
118 ah_out_of_range_error_if(i >= COUNT(r)) << "infix position out of range";
119
120 return __select_rec(r, i);
121}
122
133 template <RankedBinNodeLike Node> inline
134Node * select_ne(Node * r, const size_t pos) noexcept
135{
136 assert(COUNT(Node::NullPtr) == 0);
137 for (size_t i = pos; i != COUNT(LLINK(r)); /* nothing */)
138 {
139 assert(i < COUNT(r) and
140 COUNT(LLINK(r)) + COUNT(RLINK(r)) + 1 == COUNT(r));
141
142 if (i < COUNT(LLINK(r)))
143 r = LLINK(r);
144 else
145 {
146 i -= COUNT(LLINK(r)) + 1;
147 r = RLINK(r);
148 }
149 }
150
151 return r;
152}
153
165 template <RankedBinNodeLike Node> inline
166Node * select(Node * r, const size_t pos)
167{
168 ah_out_of_range_error_if(pos >= COUNT(r)) << "infix position out of range";
169
170 return select_ne(r, pos);
171}
172
186 template <RankedBinNodeLike Node> inline
187Node * select(Node * root, const size_t pos, Node *& parent)
188{
189 ah_out_of_range_error_if(pos >= COUNT(root)) << "infix position out of range";
190
191 parent = Node::NullPtr;
192 for (size_t i = pos; i != COUNT(LLINK(root)); /* nada */)
193 {
194 assert(i < COUNT(root) and
195 COUNT(LLINK(root)) + COUNT(RLINK(root)) + 1 == COUNT(root));
196
197 parent = root;
198 if (i < COUNT(LLINK(root)))
199 root = LLINK(root);
200 else
201 {
202 i -= COUNT(LLINK(root)) + 1;
203 root = RLINK(root);
204 }
205 }
206
207 return root;
208}
209
220 template <RankedBinNodeLike Node, class Compare> inline
222 const typename Node::key_type & key,
223 Node *& p, Compare & cmp) noexcept
224{
225 assert(COUNT(Node::NullPtr) == 0);
226
227 if (r == Node::NullPtr)
228 return -1;
229
230 if (cmp(key, KEY(r)))
231 return inorder_position(LLINK(r), key, p, cmp);
232 if (cmp(KEY(r), key))
233 {
234 long ret = inorder_position(RLINK(r), key, p, cmp);
235 if (ret != -1)
236 return ret + COUNT(LLINK(r)) + 1;
237 return ret;
238 }
239 p = r;
240 return COUNT(LLINK(r));
241}
242
244template <BinNodeLike Node, class Compare = Aleph::less<typename Node::key_type>>
245 inline long inorder_position(Node * r,
246 const typename Node::key_type & key,
247 Node *& p, Compare && cmp = Compare())
249{
250 return inorder_position(r, key, p, cmp);
251}
252
254 template <BinNodeLike Node, class Compare> inline
255long inorder_position(Node * r, const typename Node::key_type & key,
256 Compare & cmp) noexcept
257{
258 Node * p = nullptr;
259 return inorder_position(r, key, p, cmp);
260}
261
263 template <BinNodeLike Node, class Compare = Aleph::less<typename Node::key_type>>
264inline long inorder_position(Node * r, const typename Node::key_type & key,
265 Compare && cmp = Compare()) noexcept
266{
267 return inorder_position(r, key, cmp);
268}
269
296 template <RankedBinNodeLike Node,
297 class Compare = Aleph::less<typename Node::key_type>> inline
298long find_position(Node * r, const typename Node::key_type & key,
299 Node *& p, Compare & cmp) noexcept
300{
301 assert(COUNT(Node::NullPtr) == 0);
302
303 long offset = 0;
304 Node * candidate = Node::NullPtr;
305
306 while (r != Node::NullPtr)
307 if (cmp(key, KEY(r)))
308 {
309 candidate = r;
310 r = LLINK(r);
311 }
312 else if (cmp(KEY(r), key))
313 {
314 offset += static_cast<long>(COUNT(LLINK(r)) + 1);
315 r = RLINK(r);
316 }
317 else
318 {
319 p = r;
320 return offset + static_cast<long>(COUNT(LLINK(r)));
321 }
322
323 if (candidate != Node::NullPtr)
324 {
325 p = candidate;
326 return offset + static_cast<long>(COUNT(LLINK(candidate))) - 1;
327 }
328
329 p = Node::NullPtr;
330 return offset - 1;
331}
332
333template <BinNodeLike Node,
334 class Compare = Aleph::less<typename Node::key_type>> inline
335long find_position(Node * r, const typename Node::key_type & key,
336 Node *& p, Compare && cmp = Compare()) noexcept
337{
338 return find_position(r, key, p, cmp);
339}
340
354 template <RankedBinNodeLike Node, class Compare> inline
355Node * insert_by_key_xt(Node *& r, Node * p, Compare & cmp) noexcept
356{
357 assert(COUNT(Node::NullPtr) == 0);
358
359 if (r == Node::NullPtr)
360 return r = p;
361
362 Node * q = Node::NullPtr;
363 if (cmp(KEY(p), KEY(r)))
364 {
365 q = insert_by_key_xt(LLINK(r), p, cmp);
366 if (q != Node::NullPtr)
367 ++COUNT(r);
368 }
369 else if (cmp(KEY(r), KEY(p)))
370 {
371 q = insert_by_key_xt(RLINK(r), p, cmp);
372 if (q != Node::NullPtr)
373 ++COUNT(r);
374 }
375 // else return Node::NullPtr; is not needed
376
377 return q;
378}
379
381 template <BinNodeLike Node,
382 class Compare = Aleph::less<typename Node::key_type>> inline
383Node * insert_by_key_xt(Node *& r, Node * p, Compare && cmp = Compare())
385{
386 return insert_by_key_xt(r, p, cmp);
387}
388
399 template <RankedBinNodeLike Node, class Compare> inline
400Node * insert_dup_by_key_xt(Node *& r, Node * p, Compare & cmp) noexcept
401{
402 assert(COUNT(Node::NullPtr) == 0);
403
404 if (r == Node::NullPtr)
405 return r = p;
406
407 Node * q;
408 if (cmp(KEY(p), KEY(r)))
410 else
412
413 ++COUNT(r);
414
415 return q;
416}
417
419 template <BinNodeLike Node,
420 class Compare = Aleph::less<typename Node::key_type>> inline
421Node * insert_dup_by_key_xt(Node *& r, Node * p, Compare && cmp = Compare())
423{
424 return insert_dup_by_key_xt(r, p, cmp);
425}
426
440 template <RankedBinNodeLike Node, class Compare> inline
441Node * search_or_insert_by_key_xt(Node *& r, Node * p, Compare & cmp) noexcept
442{
443 assert(COUNT(Node::NullPtr) == 0);
444
445 if (r == Node::NullPtr)
446 return r = p;
447
448 Node * q;
449 if (cmp(KEY(p), KEY(r)))
450 {
452 if (q == p)
453 ++COUNT(r);
454 }
455 else if (cmp(KEY(r), KEY(p)))
456 {
458 if (q == p)
459 ++COUNT(r);
460 }
461 else
462 return r;
463
464 return q;
465}
466
468template <BinNodeLike Node,
469 class Compare = Aleph::less<typename Node::key_type>> inline
471 Compare && cmp = Compare()) noexcept
472{
473 return search_or_insert_by_key_xt(r, p, cmp);
474}
475
476
477 template <RankedBinNodeLike Node, class Compare> static inline
478bool __split_key_rec_xt(Node * root, const typename Node::key_type & key,
479 Node *& l, Node *& r, Compare & cmp) noexcept
480{
481 if (root == Node::NullPtr)
482 {
483 l = r = Node::NullPtr;
484 return true;
485 }
486
487 if (cmp(key, KEY(root)))
488 {
490 return false;
491
492 r = root;
493 COUNT(r) -= COUNT(l);
494 }
495 else if (cmp(KEY(root), key))
496 {
498 return false;
499
500 l = root;
501 COUNT(l) -= COUNT(r);
502 }
503 else
504 return false;
505
506 return true;
507}
508
524template <BinNodeLike Node, class Compare> inline
525bool split_key_rec_xt(Node *& root, const typename Node::key_type & key,
526 Node *& l, Node *& r, Compare & cmp) noexcept
527{
528 const bool ret = __split_key_rec_xt(root, key, l, r, cmp);
529 if (ret)
530 root = Node::NullPtr;
531 return ret;
532}
533
535template <BinNodeLike Node,
536 class Compare = Aleph::less<typename Node::key_type>> inline
537bool split_key_rec_xt(Node *& root, const typename Node::key_type & key,
538 Node *& l, Node *& r, Compare && cmp = Compare())
540{
541 return split_key_rec_xt(root, key, l, r, cmp);
542}
543
544
545 template <RankedBinNodeLike Node, class Compare> static inline
546void __split_key_dup_rec_xt(Node * root, const typename Node::key_type & key,
547 Node *& l, Node *& r, Compare & cmp) noexcept
548{
549 if (root == Node::NullPtr)
550 {
551 l = r = Node::NullPtr;
552 return;
553 }
554
555 if (cmp(key, KEY(root)))
556 {
558 r = root;
559 COUNT(r) -= COUNT(l);
560 }
561 else
562 {
564 l = root;
565 COUNT(l) -= COUNT(r);
566 }
567}
568
569
584 template <BinNodeLike Node, class Compare> inline
585void split_key_dup_rec_xt(Node *& root, const typename Node::key_type & key,
586 Node *& l, Node *& r, Compare & cmp) noexcept
587{
589 root = Node::NullPtr;
590}
591
593 template <BinNodeLike Node,
594 class Compare = Aleph::less<typename Node::key_type>> inline
595void split_key_dup_rec_xt(Node *& root, const typename Node::key_type & key,
596 Node *& l, Node *& r, Compare && cmp = Compare())
598{
599 return split_key_dup_rec_xt(root, key, l, r, cmp);
600}
601
617 template <RankedBinNodeLike Node, class Compare> inline
618Node * insert_root_xt(Node *& root, Node * p, Compare & cmp) noexcept
619{
620 if (root == Node::NullPtr)
621 {
622 root = p;
623 return p;
624 }
625
626 if (not split_key_rec_xt(root, KEY(p), LLINK(p), RLINK(p), cmp))
627 return Node::NullPtr;
628
629 COUNT(p) = COUNT(LLINK(p)) + COUNT(RLINK(p)) + 1;
630 root = p;
631
632 return p;
633}
634
636 template <BinNodeLike Node,
637 class Compare = Aleph::less<typename Node::key_type>> inline
638Node * insert_root_xt(Node *& root, Node * p, Compare && cmp = Compare())
640{
641 return insert_root_xt(root, p, cmp);
642}
643
658 template <RankedBinNodeLike Node, class Compare> inline
659Node * insert_dup_root_xt(Node *& root, Node * p, Compare & cmp) noexcept
660{
661 if (root == Node::NullPtr)
662 {
663 COUNT(p) = 1;
664 LLINK(p) = RLINK(p) = Node::NullPtr;
665 return root = p;
666 }
667
669 COUNT(p) = COUNT(LLINK(p)) + COUNT(RLINK(p)) + 1;
670
671 return root = p;
672}
673
675template <BinNodeLike Node,
676 class Compare = Aleph::less<typename Node::key_type>> inline
677Node * insert_dup_root_xt(Node *& root, Node * p, Compare && cmp = Compare())
679{
680 return insert_dup_root_xt(root, p, cmp);
681}
682
683
684 template <RankedBinNodeLike Node> static inline
685void __split_pos_rec(Node * r, size_t i, Node *& ts, Node *& tg) noexcept
686{
687 if (i == COUNT(LLINK(r)))
688 {
689 ts = LLINK(r);
690 tg = r;
691 LLINK(tg) = Node::NullPtr;
692 COUNT(tg) -= COUNT(ts);
693 return;
694 }
695
696 if (i < COUNT(LLINK(r)))
697 {
699 tg = r;
700 COUNT(r) -= COUNT(ts);
701 }
702 else
703 {
704 __split_pos_rec(RLINK(r), i - (COUNT(LLINK(r)) + 1), RLINK(r), tg);
705 ts = r;
706 COUNT(r) -= COUNT(tg);
707 }
708}
709
710
726template <RankedBinNodeLike Node> inline
727void split_pos_rec(Node *& r, const size_t i, Node *& ts, Node *& tg)
728{
729 ah_out_of_range_error_if(i > COUNT(r)) << "infix position out of range";
730
731 if (i == COUNT(r)) // Is it the last position?
732 {
733 ts = r;
734 r = tg = Node::NullPtr;
735 return;
736 }
737
739
740 r = Node::NullPtr;
741}
742
757 template <RankedBinNodeLike Node> inline
758void insert_by_pos_xt(Node *& r, Node * p, size_t pos)
759{
760 assert(COUNT(Node::NullPtr) == 0);
761
762 split_pos_rec(r, pos, LLINK(p), RLINK(p));
763 COUNT(p) = COUNT(LLINK(p)) + 1 + COUNT(RLINK(p));
764 r = p;
765}
766
779 template <RankedBinNodeLike Node> inline
781{
782 if (ts == Node::NullPtr)
783 return tg;
784
785 if (tg == Node::NullPtr)
786 return ts;
787
789 RLINK(ts) = tg;
790
791 // Update Counters
792 COUNT(tg) = COUNT(LLINK(tg)) + 1 + COUNT(RLINK(tg));
793 COUNT(ts) = COUNT(LLINK(ts)) + 1 + COUNT(RLINK(ts));
794
795 Node * ret_val = ts;
796 ts = tg = Node::NullPtr; // should be empty after joining
797
798 return ret_val;
799}
800
801
817 template <RankedBinNodeLike Node,
818 class Compare = Aleph::less<typename Node::key_type>> inline
819Node * remove_by_key_xt(Node *& root, const typename Node::key_type & key,
820 Compare & cmp) noexcept
821{
822 if (root == Node::NullPtr)
823 return Node::NullPtr;
824
825 Node * ret_val = Node::NullPtr;
826 if (cmp(key, KEY(root)))
827 {
829 if (ret_val != Node::NullPtr)
830 --COUNT(root);
831
832 return ret_val;
833 }
834 if (cmp(KEY(root), key))
835 {
837 if (ret_val != Node::NullPtr)
838 --COUNT(root);
839
840 return ret_val;
841 }
842
843 ret_val = root;
845
846 ret_val->reset();
847
848 return ret_val;
849}
850
852template <BinNodeLike Node, class Compare = Aleph::less<typename Node::key_type>>
854 const typename Node::key_type & key,
855 Compare && cmp = Compare()) noexcept
856{
857 return remove_by_key_xt(root, key, cmp);
858}
859
860
861 template <RankedBinNodeLike Node> static inline
862Node * __remove_by_pos_xt(Node *& root, size_t pos) noexcept
863{
864 if (COUNT(LLINK(root)) == pos) // found position?
865 {
866 Node * ret_val = root;
868
869 ret_val->reset();
870
871 return ret_val;
872 }
873
874 Node * ret_val;
875 if (pos < COUNT(LLINK(root)))
877 else
879
880 if (ret_val != Node::NullPtr) // removal was done?
881 --COUNT(root);
882
883 return ret_val;
884}
885
896 template <RankedBinNodeLike Node> inline
898{
899 ah_out_of_range_error_if(pos >= COUNT(root)) << "infix position out of range";
900
901 return __remove_by_pos_xt(root, pos);
902}
903
908 template <RankedBinNodeLike Node> inline
909bool check_rank_tree(Node * root) noexcept
910{
911 if (root == Node::NullPtr)
912 return true;
913
914 if (COUNT(LLINK(root)) + COUNT(RLINK(root)) + 1 != COUNT(root))
915 return false;
916
918}
919
926 template <RankedBinNodeLike Node> inline
928{
929 assert(p != Node::NullPtr);
930 assert(COUNT(LLINK(p)) + 1 + COUNT(RLINK(p)) == COUNT(p));
931
932 Node * q = LLINK(p);
933 LLINK(p) = RLINK(q);
934 RLINK(q) = p;
935 COUNT(p) -= 1 + COUNT(LLINK(q));
936 COUNT(q) += 1 + COUNT(RLINK(p));
937 assert(COUNT(LLINK(q)) + 1 + COUNT(RLINK(q)) == COUNT(q));
938 return q;
939}
940
947 template <RankedBinNodeLike Node> inline
949{
950 assert(p != Node::NullPtr);
951 assert(COUNT(LLINK(p)) + 1 + COUNT(RLINK(p)) == COUNT(p));
952
953 Node * q = RLINK(p);
954 RLINK(p) = LLINK(q);
955 LLINK(q) = p;
956 COUNT(p) -= 1 + COUNT(RLINK(q));
957 COUNT(q) += 1 + COUNT(LLINK(p));
958 assert(COUNT(LLINK(q)) + 1 + COUNT(RLINK(q)) == COUNT(q));
959 return q;
960}
961
962
973 template <RankedBinNodeLike Node, class Key, class Compare> inline
975 noexcept
976{
977 if (root == Node::NullPtr)
978 return p; // insertion in empty tree
979
980 if (cmp(KEY(p), KEY(root)))
981 { // insert in left subtree
983 if (left_branch == p) // p was inserted?
984 {
985 ++COUNT(root);
988 return p;
989 }
990
991 return left_branch;
992 }
993 if (cmp(KEY(root), KEY(p)))
994 { // insert in right subtree
996 if (right_branch == p) // p was inserted?
997 {
998 ++COUNT(root);
1001 return p;
1002 }
1003
1004 return right_branch;
1005 }
1006
1007 return root;
1008}
1009
1011template <BinNodeLike Node, class Key,
1012 class Compare = Aleph::less<typename Node::key_type>> inline
1014 Compare && cmp = Compare()) noexcept
1015{
1017}
1018
1019
1038template <class TreeType, class Node, typename Key, class Compare>
1040{
1041protected:
1042
1044 mutable Node * curr;
1045 mutable int curr_pos;
1046
1047 static constexpr int Pos_Not_Current = -1;
1048 static constexpr int Pos_Empty_Container = -2;
1049 static constexpr int Pos_Not_Updated = -3;
1050
1051private:
1052
1054 {
1055 return COUNT(tree_ptr->getRoot()) == 0;
1056 }
1057
1059 {
1060 return curr_pos != Pos_Not_Updated;
1061 }
1062
1064 {
1065 return curr != nullptr;
1066 }
1067
1069 {
1070 assert(curr != nullptr);
1072 inorder_position(tree_ptr->getRoot(), KEY(curr), curr);
1073 }
1074
1076 {
1078
1080 curr_pos == static_cast<int>(COUNT(tree_ptr->getRoot())))
1081 return;
1082
1083 curr = Aleph::select(tree_ptr->getRoot(), curr_pos);
1084 }
1085
1086public:
1087
1089 : tree_ptr(nullptr), curr(nullptr), curr_pos(Pos_Not_Current)
1090 { /* empty */ }
1091
1093 : tree_ptr(&const_cast<TreeType&>(__tree)), curr(nullptr)
1094 {
1096 }
1097
1099 : tree_ptr(&const_cast<TreeType&>(__tree)),
1101 { /* empty */ }
1102
1103 BinTreeXt_Iterator(const TreeType & __tree, const size_t pos) noexcept
1104 : tree_ptr(&const_cast<TreeType&>(__tree)),
1105 curr(nullptr), curr_pos(pos)
1106 { /* empty */ }
1107
1109 : tree_ptr(itor.tree_ptr), curr(itor.curr), curr_pos(itor.curr_pos)
1110 { /* empty */ }
1111
1113 {
1114 if (this == &itor)
1115 return *this;
1116
1118 curr = itor.curr;
1119 curr_pos = itor.curr_pos;
1120
1121 return *this;
1122 }
1123
1125 {
1126 curr = nullptr;
1128 }
1129
1131 {
1132 curr = nullptr;
1134 static_cast<int>(COUNT(tree_ptr->getRoot())) - 1;
1135 }
1136
1138 {
1139 put_itor_at_the_end(*this);
1140 }
1141
1142 void reset_to_key(const Key & key) noexcept
1143 {
1144 std::pair<long, Node*> p = tree_ptr->find_position(key);
1145 curr_pos = p.first;
1146 }
1147
1148 void reset_to_node(Node * node) noexcept
1149 {
1150 curr = node;
1152 }
1153
1154 void reset_to_pos(const size_t pos) noexcept
1155 {
1156 curr = nullptr;
1157 curr_pos = pos;
1158 }
1159
1161 {
1162 if (not curr_updated())
1163 update_curr();
1164 return curr;
1165 }
1166
1168 {
1169 return get_curr_ne();
1170 }
1171
1173 {
1174 if (not pos_updated())
1175 update_pos();
1176
1177 ah_range_error_if(curr_pos < -1) << "Iterator has no current";
1178 ah_range_error_if(curr_pos > static_cast<int>(COUNT(tree_ptr->getRoot())))
1179 << "Iterator has no current";
1180
1181 return curr_pos;
1182 }
1183
1184 size_t get_pos() const { return get_current_position(); }
1185
1187 {
1188 if (not pos_updated())
1189 update_pos();
1190
1191 return curr_pos >= 0 and
1193 }
1194
1195 void prev()
1196 {
1197 ah_underflow_error_if(not has_curr()) << "Iterator has no current";
1198 --curr_pos;
1199 curr = nullptr;
1200 }
1201
1203 {
1204 ++curr_pos;
1205 curr = nullptr;
1206 }
1207
1208 void next()
1209 {
1210 ah_overflow_error_if(not has_curr()) << "Iterator has no current";
1211 next_ne();
1212 }
1213
1215 {
1216 ah_underflow_error_if(not has_curr()) << "Iterator has no current";
1217
1218 if (not curr_updated())
1219 update_curr();
1220
1221 Node * ret_val = tree_ptr->remove(KEY(curr));
1222 curr = nullptr;
1223
1224 return ret_val;
1225 }
1226
1227 bool operator == (const BinTreeXt_Iterator & itor) const noexcept
1228 {
1229 if (is_container_empty() and itor.is_container_empty())
1230 return true;
1231
1232 if (pos_updated() and itor.pos_updated())
1233 return curr_pos == itor.curr_pos;
1234
1235 if (curr_updated() and itor.curr_updated())
1236 return curr == itor.curr;
1237
1238 if (not pos_updated())
1239 {
1240 update_pos();
1241 return curr_pos == itor.curr_pos;
1242 }
1243
1244 itor.update_pos();
1245 return curr_pos == itor.curr_pos;
1246 }
1247
1249 {
1250 return not (*this == itor);
1251 }
1252}; // end class BinTreeXt_Iterator
1253
1254
1255} // end namespace Aleph
1256
1257# endif // TPL_BINNODEXT_H
C++20 concepts hub: comparison, BST policy, and Aleph container concepts.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
Definition ah-errors.H:584
#define ah_underflow_error_if(C)
Throws std::underflow_error if condition holds.
Definition ah-errors.H:373
#define ah_overflow_error_if(C)
Throws std::overflow_error if condition holds.
Definition ah-errors.H:468
#define ah_range_error_if(C)
Throws std::range_error if condition holds.
Definition ah-errors.H:212
SentinelCtor
Tag type for sentinel node construction.
Definition ahDefs.H:83
void put_itor_at_the_end(Itor &it) noexcept
Definition aleph.H:54
WeightedDigraph::Node Node
@ KEY
Definition btreepic.C:169
BinNodeXt_Data(SentinelCtor) noexcept
size_t size() const noexcept
void reset() noexcept
size_t & getCount() noexcept
Node for extended binary search tree.
Base iterator template for ranked binary search trees.
static constexpr int Pos_Empty_Container
bool has_curr() const noexcept
bool operator==(const BinTreeXt_Iterator &itor) const noexcept
void update_curr() const noexcept
void update_pos() const noexcept
Node * get_curr_ne() const noexcept
BinTreeXt_Iterator(const TreeType &__tree, Node *__curr) noexcept
bool curr_updated() const noexcept
void reset_to_node(Node *node) noexcept
static constexpr int Pos_Not_Current
BinTreeXt_Iterator(const TreeType &__tree, const size_t pos) noexcept
BinTreeXt_Iterator & operator=(const BinTreeXt_Iterator &itor) noexcept
void reset_to_pos(const size_t pos) noexcept
bool is_container_empty() const noexcept
size_t get_current_position() const
static constexpr int Pos_Not_Updated
BinTreeXt_Iterator(const BinTreeXt_Iterator &itor) noexcept
bool pos_updated() const noexcept
void reset_to_key(const Key &key) noexcept
BinTreeXt_Iterator(const TreeType &__tree) noexcept
bool operator!=(const BinTreeXt_Iterator &itor) const
Node * get_curr() const noexcept
__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
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Definition gmpfrxx.h:4129
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
long inorder_position(Node *r, const typename Node::key_type &key, Node *&p, Compare &cmp) noexcept
Compute the inorder position of a key.
Node * insert_dup_by_key_xt(Node *&r, Node *p, Compare &cmp) noexcept
Insert a node in an extended binary search tree without testing for duplicity.
Node * insert_dup_root_xt(Node *&root, Node *p, Compare &cmp) noexcept
Insert a node as root of an extended binary search tree.
Node * insert_by_key_xt(Node *&r, Node *p, Compare &cmp) noexcept
Insert a node in an extended binary search tree.
bool check_rank_tree(Node *root) noexcept
Return true if root is a valid extended binary tree.
void split_pos_rec(Node *&r, const size_t i, Node *&ts, Node *&tg)
Split a extended binary tree according to a position.
#define DECLARE_BINNODE_SENTINEL(Name, height, Control_Data)
Specify tree node for a binary tree.
auto & COUNT(Node *p) noexcept
Return the number of nodes of the tree fron p is root.
Node * remove_by_pos_xt(Node *&root, size_t pos)
Remove from a extended binary tree the node whose inorder position is pos.
Node * remove_by_key_xt(Node *&root, const typename Node::key_type &key, Compare &cmp) noexcept
Remove a key of extended binary tree.
Node * insert_root_xt(Node *&root, Node *p, Compare &cmp) noexcept
Insert a node p as root of an extended binary search tree.
Node * rotate_to_left_xt(Node *p) noexcept
Rotate to left the extended binary tree with root p.
bool split_key_rec_xt(Node *&root, const typename Node::key_type &key, Node *&l, Node *&r, Compare &cmp) noexcept
Split an extended binary search tree according to a key.
Node * select(Node *r, const size_t pos)
Iterative selection of a node according to inorder position.
Node * select_ne(Node *r, const size_t pos) noexcept
Iterative selection of a node according to inorder position without exception.
Node * rotate_to_right_xt(Node *p) noexcept
Rotate to right the extended bianry tree with root p
void split_key_dup_rec_xt(Node *&root, const typename Node::key_type &key, Node *&l, Node *&r, Compare &cmp) noexcept
Split an extended binary search tree according to a key which can be in the tree.
void insert_by_pos_xt(Node *&r, Node *p, size_t pos)
Insert a node in a specific inorder position in a binary tree.
Node * select_rec(Node *r, const size_t i)
Recursively select the i-th node inorder sense.
Node * join_exclusive_xt(Node *&ts, Node *&tg) noexcept
Exclusive union of two extended binary search trees.
const long double offset[]
Offset values indexed by symbol string length (bounded by MAX_OFFSET_INDEX)
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
and
Check uniqueness with explicit hash + equality functors.
static Node * __remove_by_pos_xt(Node *&root, size_t pos) noexcept
Node * search_or_insert_root_rec_xt(Node *root, Node *p, Compare &cmp) noexcept
Search or insert a key in an extended binary search tree.
static void __split_key_dup_rec_xt(Node *root, const typename Node::key_type &key, Node *&l, Node *&r, Compare &cmp) noexcept
static Node * __select_rec(Node *r, const size_t i) noexcept
static bool __split_key_rec_xt(Node *root, const typename Node::key_type &key, Node *&l, Node *&r, Compare &cmp) noexcept
long find_position(Node *r, const typename Node::key_type &key, Node *&p, Compare &cmp) noexcept
Find the inorder position of a key in an extended binary search tree.
static void __split_pos_rec(Node *r, size_t i, Node *&ts, Node *&tg) noexcept
Node * search_or_insert_by_key_xt(Node *&r, Node *p, Compare &cmp) noexcept
Search or insert a node in an extended binary search tree.
TreeType
#define RLINK(i, n)
#define LLINK(i, n)
gsl_rng * r
Utility functions for binary tree operations.
Basic binary tree node definitions.
DynList< int > l