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 <tpl_binNode.H>
47# include <tpl_binNodeUtils.H>
48
49using namespace Aleph;
50
51namespace Aleph {
52
54{
55 size_t count; // Cardinality of the tree
56
57public:
58
61
62 size_t & getCount() noexcept { return count; }
63 size_t size() const noexcept { return count; }
64
65 void reset() noexcept { count = 1; }
66};
67
75
81template <class Node> inline auto & COUNT(Node * p) noexcept
82{
83 return p->getCount();
84}
85
86
87 template <class Node> static inline
88Node * __select_rec(Node * r, const size_t i) noexcept
89{
90 assert(r != Node::NullPtr);
91 assert(COUNT(Node::NullPtr) == 0);
92
93 if (i == COUNT(LLINK(r)))
94 return r;
95
96 if (i < COUNT(LLINK(r)))
97 return __select_rec(LLINK(r), i);
98
99 return __select_rec(RLINK(r), i - COUNT(LLINK(r)) - 1);
100}
101
113 template <class Node> inline
114Node * select_rec(Node * r, const size_t i)
115{
116 ah_out_of_range_error_if(i >= COUNT(r)) << "infix position out of range";
117
118 return __select_rec(r, i);
119}
120
131 template <class Node> inline
132Node * select_ne(Node * r, const size_t pos) noexcept
133{
134 assert(COUNT(Node::NullPtr) == 0);
135 for (size_t i = pos; i != COUNT(LLINK(r)); /* nothing */)
136 {
137 assert(i < COUNT(r) and
138 COUNT(LLINK(r)) + COUNT(RLINK(r)) + 1 == COUNT(r));
139
140 if (i < COUNT(LLINK(r)))
141 r = LLINK(r);
142 else
143 {
144 i -= COUNT(LLINK(r)) + 1;
145 r = RLINK(r);
146 }
147 }
148
149 return r;
150}
151
163 template <class Node> inline
164Node * select(Node * r, const size_t pos)
165{
166 ah_out_of_range_error_if(pos >= COUNT(r)) << "infix position out of range";
167
168 return select_ne(r, pos);
169}
170
184 template <class Node> inline
185Node * select(Node * root, const size_t pos, Node *& parent)
186{
187 ah_out_of_range_error_if(pos >= COUNT(root)) << "infix position out of range";
188
189 parent = Node::NullPtr;
190 for (size_t i = pos; i != COUNT(LLINK(root)); /* nada */)
191 {
192 assert(i < COUNT(root) and
193 COUNT(LLINK(root)) + COUNT(RLINK(root)) + 1 == COUNT(root));
194
195 parent = root;
196 if (i < COUNT(LLINK(root)))
197 root = LLINK(root);
198 else
199 {
200 i -= COUNT(LLINK(root)) + 1;
201 root = RLINK(root);
202 }
203 }
204
205 return root;
206}
207
218 template <class Node, class Compare> inline
220 const typename Node::key_type & key,
221 Node *& p, Compare & cmp) noexcept
222{
223 assert(COUNT(Node::NullPtr) == 0);
224
225 if (r == Node::NullPtr)
226 return -1;
227
228 if (cmp(key, KEY(r)))
229 return inorder_position(LLINK(r), key, p, cmp);
230 if (cmp(KEY(r), key))
231 {
232 long ret = inorder_position(RLINK(r), key, p, cmp);
233 if (ret != -1)
234 return ret + COUNT(LLINK(r)) + 1;
235 return ret;
236 }
237 p = r;
238 return COUNT(LLINK(r));
239}
240
242template <class Node, class Compare = Aleph::less<typename Node::key_type>>
243 inline long inorder_position(Node * r,
244 const typename Node::key_type & key,
245 Node *& p, Compare && cmp = Compare())
247{
248 return inorder_position(r, key, p, cmp);
249}
250
252 template <class Node, class Compare> inline
253long inorder_position(Node * r, const typename Node::key_type & key,
254 Compare & cmp) noexcept
255{
256 Node * p = nullptr;
257 return inorder_position(r, key, p, cmp);
258}
259
261 template <class Node, class Compare = Aleph::less<typename Node::key_type>>
262inline long inorder_position(Node * r, const typename Node::key_type & key,
263 Compare && cmp = Compare()) noexcept
264{
265 return inorder_position(r, key, cmp);
266}
267
294 template <class Node,
295 class Compare = Aleph::less<typename Node::key_type>> inline
296long find_position(Node * r, const typename Node::key_type & key,
297 Node *& p, Compare & cmp) noexcept
298{
299 assert(COUNT(Node::NullPtr) == 0);
300
301 long offset = 0;
302 Node * candidate = Node::NullPtr;
303
304 while (r != Node::NullPtr)
305 if (cmp(key, KEY(r)))
306 {
307 candidate = r;
308 r = LLINK(r);
309 }
310 else if (cmp(KEY(r), key))
311 {
312 offset += static_cast<long>(COUNT(LLINK(r)) + 1);
313 r = RLINK(r);
314 }
315 else
316 {
317 p = r;
318 return offset + static_cast<long>(COUNT(LLINK(r)));
319 }
320
321 if (candidate != Node::NullPtr)
322 {
323 p = candidate;
324 return offset + static_cast<long>(COUNT(LLINK(candidate))) - 1;
325 }
326
327 p = Node::NullPtr;
328 return offset - 1;
329}
330
331template <class Node,
332 class Compare = Aleph::less<typename Node::key_type>> inline
333long find_position(Node * r, const typename Node::key_type & key,
334 Node *& p, Compare && cmp = Compare()) noexcept
335{
336 return find_position(r, key, p, cmp);
337}
338
352 template <class Node, class Compare> inline
353Node * insert_by_key_xt(Node *& r, Node * p, Compare & cmp) noexcept
354{
355 assert(COUNT(Node::NullPtr) == 0);
356
357 if (r == Node::NullPtr)
358 return r = p;
359
360 Node * q = Node::NullPtr;
361 if (cmp(KEY(p), KEY(r)))
362 {
363 q = insert_by_key_xt(LLINK(r), p, cmp);
364 if (q != Node::NullPtr)
365 ++COUNT(r);
366 }
367 else if (cmp(KEY(r), KEY(p)))
368 {
369 q = insert_by_key_xt(RLINK(r), p, cmp);
370 if (q != Node::NullPtr)
371 ++COUNT(r);
372 }
373 // else return Node::NullPtr; is not needed
374
375 return q;
376}
377
379 template <class Node,
380 class Compare = Aleph::less<typename Node::key_type>> inline
381Node * insert_by_key_xt(Node *& r, Node * p, Compare && cmp = Compare())
383{
384 return insert_by_key_xt(r, p, cmp);
385}
386
397 template <class Node, class Compare> inline
398Node * insert_dup_by_key_xt(Node *& r, Node * p, Compare & cmp) noexcept
399{
400 assert(COUNT(Node::NullPtr) == 0);
401
402 if (r == Node::NullPtr)
403 return r = p;
404
405 Node * q;
406 if (cmp(KEY(p), KEY(r)))
407 q = insert_dup_by_key_xt(LLINK(r), p, cmp);
408 else
409 q = insert_dup_by_key_xt(RLINK(r), p, cmp);
410
411 ++COUNT(r);
412
413 return q;
414}
415
417 template <class Node,
418 class Compare = Aleph::less<typename Node::key_type>> inline
419Node * insert_dup_by_key_xt(Node *& r, Node * p, Compare && cmp = Compare())
421{
422 return insert_dup_by_key_xt(r, p, cmp);
423}
424
438 template <class Node, class Compare> inline
439Node * search_or_insert_by_key_xt(Node *& r, Node * p, Compare & cmp) noexcept
440{
441 assert(COUNT(Node::NullPtr) == 0);
442
443 if (r == Node::NullPtr)
444 return r = p;
445
446 Node * q;
447 if (cmp(KEY(p), KEY(r)))
448 {
450 if (q == p)
451 ++COUNT(r);
452 }
453 else if (cmp(KEY(r), KEY(p)))
454 {
456 if (q == p)
457 ++COUNT(r);
458 }
459 else
460 return r;
461
462 return q;
463}
464
466template <class Node,
467 class Compare = Aleph::less<typename Node::key_type>> inline
469 Compare && cmp = Compare()) noexcept
470{
471 return search_or_insert_by_key_xt(r, p, cmp);
472}
473
474
475 template <class Node, class Compare> static inline
476bool __split_key_rec_xt(Node * root, const typename Node::key_type & key,
477 Node *& l, Node *& r, Compare & cmp) noexcept
478{
479 if (root == Node::NullPtr)
480 {
481 l = r = Node::NullPtr;
482 return true;
483 }
484
485 if (cmp(key, KEY(root)))
486 {
488 return false;
489
490 r = root;
491 COUNT(r) -= COUNT(l);
492 }
493 else if (cmp(KEY(root), key))
494 {
495 if (not __split_key_rec_xt(RLINK(root), key, RLINK(root), r, cmp))
496 return false;
497
498 l = root;
499 COUNT(l) -= COUNT(r);
500 }
501 else
502 return false;
503
504 return true;
505}
506
522template <class Node, class Compare> inline
523bool split_key_rec_xt(Node *& root, const typename Node::key_type & key,
524 Node *& l, Node *& r, Compare & cmp) noexcept
525{
526 const bool ret = __split_key_rec_xt(root, key, l, r, cmp);
527 if (ret)
528 root = Node::NullPtr;
529 return ret;
530}
531
533template <class Node,
534 class Compare = Aleph::less<typename Node::key_type>> inline
535bool split_key_rec_xt(Node *& root, const typename Node::key_type & key,
536 Node *& l, Node *& r, Compare && cmp = Compare())
538{
539 return split_key_rec_xt(root, key, l, r, cmp);
540}
541
542
543 template <class Node, class Compare> static inline
544void __split_key_dup_rec_xt(Node * root, const typename Node::key_type & key,
545 Node *& l, Node *& r, Compare & cmp) noexcept
546{
547 if (root == Node::NullPtr)
548 {
549 l = r = Node::NullPtr;
550 return;
551 }
552
553 if (cmp(key, KEY(root)))
554 {
556 r = root;
557 COUNT(r) -= COUNT(l);
558 }
559 else
560 {
562 l = root;
563 COUNT(l) -= COUNT(r);
564 }
565}
566
567
582 template <class Node, class Compare> inline
583void split_key_dup_rec_xt(Node *& root, const typename Node::key_type & key,
584 Node *& l, Node *& r, Compare & cmp) noexcept
585{
587 root = Node::NullPtr;
588}
589
591 template <class Node,
592 class Compare = Aleph::less<typename Node::key_type>> inline
593void split_key_dup_rec_xt(Node *& root, const typename Node::key_type & key,
594 Node *& l, Node *& r, Compare && cmp = Compare())
596{
597 return split_key_dup_rec_xt(root, key, l, r, cmp);
598}
599
615 template <class Node, class Compare> inline
616Node * insert_root_xt(Node *& root, Node * p, Compare & cmp) noexcept
617{
618 if (root == Node::NullPtr)
619 {
620 root = p;
621 return p;
622 }
623
624 if (not split_key_rec_xt(root, KEY(p), LLINK(p), RLINK(p), cmp))
625 return Node::NullPtr;
626
627 COUNT(p) = COUNT(LLINK(p)) + COUNT(RLINK(p)) + 1;
628 root = p;
629
630 return p;
631}
632
634 template <class Node,
635 class Compare = Aleph::less<typename Node::key_type>> inline
636Node * insert_root_xt(Node *& root, Node * p, Compare && cmp = Compare())
638{
639 return insert_root_xt(root, p, cmp);
640}
641
656 template <class Node, class Compare> inline
657Node * insert_dup_root_xt(Node *& root, Node * p, Compare & cmp) noexcept
658{
659 if (root == Node::NullPtr)
660 {
661 COUNT(p) = 1;
662 LLINK(p) = RLINK(p) = Node::NullPtr;
663 return root = p;
664 }
665
667 COUNT(p) = COUNT(LLINK(p)) + COUNT(RLINK(p)) + 1;
668
669 return root = p;
670}
671
673template <class Node,
674 class Compare = Aleph::less<typename Node::key_type>> inline
675Node * insert_dup_root_xt(Node *& root, Node * p, Compare && cmp = Compare())
677{
678 return insert_dup_root_xt(root, p, cmp);
679}
680
681
682 template <class Node> static inline
683void __split_pos_rec(Node * r, size_t i, Node *& ts, Node *& tg) noexcept
684{
685 if (i == COUNT(LLINK(r)))
686 {
687 ts = LLINK(r);
688 tg = r;
689 LLINK(tg) = Node::NullPtr;
690 COUNT(tg) -= COUNT(ts);
691 return;
692 }
693
694 if (i < COUNT(LLINK(r)))
695 {
696 __split_pos_rec(LLINK(r), i, ts, LLINK(r));
697 tg = r;
698 COUNT(r) -= COUNT(ts);
699 }
700 else
701 {
702 __split_pos_rec(RLINK(r), i - (COUNT(LLINK(r)) + 1), RLINK(r), tg);
703 ts = r;
704 COUNT(r) -= COUNT(tg);
705 }
706}
707
708
724template <class Node> inline
725void split_pos_rec(Node *& r, const size_t i, Node *& ts, Node *& tg)
726{
727 ah_out_of_range_error_if(i > COUNT(r)) << "infix position out of range";
728
729 if (i == COUNT(r)) // Is it the last position?
730 {
731 ts = r;
732 r = tg = Node::NullPtr;
733 return;
734 }
735
737
738 r = Node::NullPtr;
739}
740
755 template <class Node> inline
756void insert_by_pos_xt(Node *& r, Node * p, size_t pos)
757{
758 assert(COUNT(Node::NullPtr) == 0);
759
760 split_pos_rec(r, pos, LLINK(p), RLINK(p));
761 COUNT(p) = COUNT(LLINK(p)) + 1 + COUNT(RLINK(p));
762 r = p;
763}
764
777 template <class Node> inline
779{
780 if (ts == Node::NullPtr)
781 return tg;
782
783 if (tg == Node::NullPtr)
784 return ts;
785
787 RLINK(ts) = tg;
788
789 // Update Counters
790 COUNT(tg) = COUNT(LLINK(tg)) + 1 + COUNT(RLINK(tg));
791 COUNT(ts) = COUNT(LLINK(ts)) + 1 + COUNT(RLINK(ts));
792
793 Node * ret_val = ts;
794 ts = tg = Node::NullPtr; // should be empty after joining
795
796 return ret_val;
797}
798
799
815 template <class Node,
816 class Compare = Aleph::less<typename Node::key_type>> inline
817Node * remove_by_key_xt(Node *& root, const typename Node::key_type & key,
818 Compare & cmp) noexcept
819{
820 if (root == Node::NullPtr)
821 return Node::NullPtr;
822
823 Node * ret_val = Node::NullPtr;
824 if (cmp(key, KEY(root)))
825 {
827 if (ret_val != Node::NullPtr)
828 --COUNT(root);
829
830 return ret_val;
831 }
832 if (cmp(KEY(root), key))
833 {
835 if (ret_val != Node::NullPtr)
836 --COUNT(root);
837
838 return ret_val;
839 }
840
841 ret_val = root;
843
844 ret_val->reset();
845
846 return ret_val;
847}
848
850template <class Node, class Compare = Aleph::less<typename Node::key_type>>
852 const typename Node::key_type & key,
853 Compare && cmp = Compare()) noexcept
854{
855 return remove_by_key_xt(root, key, cmp);
856}
857
858
859 template <class Node> static inline
860Node * __remove_by_pos_xt(Node *& root, size_t pos) noexcept
861{
862 if (COUNT(LLINK(root)) == pos) // found position?
863 {
864 Node * ret_val = root;
866
867 ret_val->reset();
868
869 return ret_val;
870 }
871
872 Node * ret_val;
873 if (pos < COUNT(LLINK(root)))
875 else
877
878 if (ret_val != Node::NullPtr) // removal was done?
879 --COUNT(root);
880
881 return ret_val;
882}
883
894 template <class Node> inline
896{
897 ah_out_of_range_error_if(pos >= COUNT(root)) << "infix position out of range";
898
899 return __remove_by_pos_xt(root, pos);
900}
901
906 template <class Node> inline
907bool check_rank_tree(Node * root) noexcept
908{
909 if (root == Node::NullPtr)
910 return true;
911
912 if (COUNT(LLINK(root)) + COUNT(RLINK(root)) + 1 != COUNT(root))
913 return false;
914
916}
917
924 template <class Node> inline
926{
927 assert(p != Node::NullPtr);
928 assert(COUNT(LLINK(p)) + 1 + COUNT(RLINK(p)) == COUNT(p));
929
930 Node * q = LLINK(p);
931 LLINK(p) = RLINK(q);
932 RLINK(q) = p;
933 COUNT(p) -= 1 + COUNT(LLINK(q));
934 COUNT(q) += 1 + COUNT(RLINK(p));
935 assert(COUNT(LLINK(q)) + 1 + COUNT(RLINK(q)) == COUNT(q));
936 return q;
937}
938
945 template <class Node> inline
947{
948 assert(p != Node::NullPtr);
949 assert(COUNT(LLINK(p)) + 1 + COUNT(RLINK(p)) == COUNT(p));
950
951 Node * q = RLINK(p);
952 RLINK(p) = LLINK(q);
953 LLINK(q) = p;
954 COUNT(p) -= 1 + COUNT(RLINK(q));
955 COUNT(q) += 1 + COUNT(LLINK(p));
956 assert(COUNT(LLINK(q)) + 1 + COUNT(RLINK(q)) == COUNT(q));
957 return q;
958}
959
960
971 template <class Node, class Key, class Compare> inline
973 noexcept
974{
975 if (root == Node::NullPtr)
976 return p; // insertion in empty tree
977
978 if (cmp(KEY(p), KEY(root)))
979 { // insert in left subtree
981 if (left_branch == p) // p was inserted?
982 {
983 ++COUNT(root);
986 return p;
987 }
988
989 return left_branch;
990 }
991 if (cmp(KEY(root), KEY(p)))
992 { // insert in right subtree
994 if (right_branch == p) // p was inserted?
995 {
996 ++COUNT(root);
999 return p;
1000 }
1001
1002 return right_branch;
1003 }
1004
1005 return root;
1006}
1007
1009template <class Node, class Key,
1010 class Compare = Aleph::less<typename Node::key_type>> inline
1012 Compare && cmp = Compare()) noexcept
1013{
1015}
1016
1017
1036template <class TreeType, class Node, typename Key, class Compare>
1038{
1039protected:
1040
1042 mutable Node * curr;
1043 mutable int curr_pos;
1044
1045 static constexpr int Pos_Not_Current = -1;
1046 static constexpr int Pos_Empty_Container = -2;
1047 static constexpr int Pos_Not_Updated = -3;
1048
1049private:
1050
1052 {
1053 return COUNT(tree_ptr->getRoot()) == 0;
1054 }
1055
1057 {
1058 return curr_pos != Pos_Not_Updated;
1059 }
1060
1062 {
1063 return curr != nullptr;
1064 }
1065
1067 {
1068 assert(curr != nullptr);
1070 inorder_position(tree_ptr->getRoot(), KEY(curr), curr);
1071 }
1072
1074 {
1076
1078 curr_pos == static_cast<int>(COUNT(tree_ptr->getRoot())))
1079 return;
1080
1081 curr = Aleph::select(tree_ptr->getRoot(), curr_pos);
1082 }
1083
1084public:
1085
1087 : tree_ptr(nullptr), curr(nullptr), curr_pos(Pos_Not_Current)
1088 { /* empty */ }
1089
1091 : tree_ptr(&const_cast<TreeType&>(__tree)), curr(nullptr)
1092 {
1094 }
1095
1097 : tree_ptr(&const_cast<TreeType&>(__tree)),
1099 { /* empty */ }
1100
1101 BinTreeXt_Iterator(const TreeType & __tree, const size_t pos) noexcept
1102 : tree_ptr(&const_cast<TreeType&>(__tree)),
1103 curr(nullptr), curr_pos(pos)
1104 { /* empty */ }
1105
1107 : tree_ptr(itor.tree_ptr), curr(itor.curr), curr_pos(itor.curr_pos)
1108 { /* empty */ }
1109
1111 {
1112 if (this == &itor)
1113 return *this;
1114
1115 tree_ptr = itor.tree_ptr;
1116 curr = itor.curr;
1117 curr_pos = itor.curr_pos;
1118
1119 return *this;
1120 }
1121
1123 {
1124 curr = nullptr;
1126 }
1127
1129 {
1130 curr = nullptr;
1132 static_cast<int>(COUNT(tree_ptr->getRoot())) - 1;
1133 }
1134
1136 {
1137 put_itor_at_the_end(*this);
1138 }
1139
1140 void reset_to_key(const Key & key) noexcept
1141 {
1142 std::pair<long, Node*> p = tree_ptr->find_position(key);
1143 curr_pos = p.first;
1144 }
1145
1146 void reset_to_node(Node * node) noexcept
1147 {
1148 curr = node;
1150 }
1151
1152 void reset_to_pos(const size_t pos) noexcept
1153 {
1154 curr = nullptr;
1155 curr_pos = pos;
1156 }
1157
1159 {
1160 if (not curr_updated())
1161 update_curr();
1162 return curr;
1163 }
1164
1166 {
1167 return get_curr_ne();
1168 }
1169
1171 {
1172 if (not pos_updated())
1173 update_pos();
1174
1175 ah_range_error_if(curr_pos < -1) << "Iterator has no current";
1176 ah_range_error_if(curr_pos > static_cast<int>(COUNT(tree_ptr->getRoot())))
1177 << "Iterator has no current";
1178
1179 return curr_pos;
1180 }
1181
1182 size_t get_pos() const { return get_current_position(); }
1183
1185 {
1186 if (not pos_updated())
1187 update_pos();
1188
1189 return curr_pos >= 0 and
1191 }
1192
1193 void prev()
1194 {
1195 ah_underflow_error_if(not has_curr()) << "Iterator has no current";
1196 --curr_pos;
1197 curr = nullptr;
1198 }
1199
1201 {
1202 ++curr_pos;
1203 curr = nullptr;
1204 }
1205
1206 void next()
1207 {
1208 ah_overflow_error_if(not has_curr()) << "Iterator has no current";
1209 next_ne();
1210 }
1211
1213 {
1214 ah_underflow_error_if(not has_curr()) << "Iterator has no current";
1215
1216 if (not curr_updated())
1217 update_curr();
1218
1220 curr = nullptr;
1221
1222 return ret_val;
1223 }
1224
1225 bool operator == (const BinTreeXt_Iterator & itor) const noexcept
1226 {
1227 if (is_container_empty() and itor.is_container_empty())
1228 return true;
1229
1230 if (pos_updated() and itor.pos_updated())
1231 return curr_pos == itor.curr_pos;
1232
1233 if (curr_updated() and itor.curr_updated())
1234 return curr == itor.curr;
1235
1236 if (not pos_updated())
1237 {
1238 update_pos();
1239 return curr_pos == itor.curr_pos;
1240 }
1241
1242 itor.update_pos();
1243 return curr_pos == itor.curr_pos;
1244 }
1245
1247 {
1248 return not (*this == itor);
1249 }
1250}; // end class BinTreeXt_Iterator
1251
1252
1253} // end namespace Aleph
1254
1255# endif // TPL_BINNODEXT_H
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
Definition ah-errors.H:579
#define ah_underflow_error_if(C)
Throws std::underflow_error if condition holds.
Definition ah-errors.H:368
#define ah_overflow_error_if(C)
Throws std::overflow_error if condition holds.
Definition ah-errors.H:463
#define ah_range_error_if(C)
Throws std::range_error if condition holds.
Definition ah-errors.H:207
SentinelCtor
Tag type for sentinel node construction.
Definition ahDefs.H:81
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
T remove()
Remove the first item of the list.
Definition htlist.H:1611
void reset() noexcept
Definition htlist.H:516
__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
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Definition gmpfrxx.h:4118
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.
constexpr Node *& RLINK(Node *p) noexcept
Return the right tree of p.
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.
constexpr Node *& LLINK(Node *p) noexcept
Return a pointer to left subtree.
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
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.
DynList< T > maps(const C &c, Op op)
Classic map operation.
TreeType
Utility functions for binary tree operations.
Basic binary tree node definitions.
DynList< int > l