Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_tdRbTree.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
52# ifndef TPL_TDRBTREE_H
53# define TPL_TDRBTREE_H
54
55# include <functional>
56# include <tpl_binNode.H>
57# include <tpl_binNodeUtils.H>
58# include <tpl_arrayStack.H>
59# include <rbNode.H>
60
61namespace Aleph
62{
63
94template <template <class> class NodeType, typename Key,
95 class Compare = std::less<Key>>
97{
98public:
100 using key_type = Key;
101 using compare_type = Compare;
102
103private:
109 Compare cmp;
110 size_t num_nodes;
111
113 bool less(const Key& a, const Key& b) const noexcept
114 {
115 return cmp(a, b);
116 }
117
119 bool equals(const Key& a, const Key& b) const noexcept
120 {
121 return not cmp(a, b) and not cmp(b, a);
122 }
123
125 static Node* getSibling(Node *p, Node *fp) noexcept
126 {
127 assert(LLINK(fp) == p or RLINK(fp) == p);
128 return LLINK(fp) == p ? RLINK(fp) : LLINK(fp);
129 }
130
132 void restoreRedCondition(Node *p, Node *&fp, Node *ffp, Node *fffp) noexcept
133 {
134 assert(LLINK(fp) == p or RLINK(fp) == p);
135 assert(COLOR(fp) == RED);
136 assert(COLOR(p) == RED);
137
138 if (fp == root)
139 {
140 COLOR(fp) = BLACK;
141 return;
142 }
143
144 assert(LLINK(ffp) == fp or RLINK(ffp) == fp);
145 assert(COLOR(ffp) == BLACK);
146 assert(LLINK(fffp) == ffp or RLINK(fffp) == ffp);
147
148 COLOR(ffp) = RED;
149
150 if (LLINK(fp) == p and LLINK(ffp) == fp)
151 {
152 COLOR(fp) = BLACK;
154 }
155 else if (RLINK(fp) == p and RLINK(ffp) == fp)
156 {
157 COLOR(fp) = BLACK;
159 }
160 else
161 {
162 COLOR(p) = BLACK;
163 if (RLINK(fp) == p)
164 {
167 }
168 else
169 {
172 }
173 fp = fffp;
174 }
175 }
176
178 static void flipColors(Node* p) noexcept
179 {
180 assert(p != Node::NullPtr);
181 assert(COLOR(p) == BLACK);
182 assert(COLOR(LLINK(p)) == RED and COLOR(RLINK(p)) == RED);
183
184 COLOR(p) = RED;
185 COLOR(LLINK(p)) = COLOR(RLINK(p)) = BLACK;
186 }
187
190 {
191 assert(q != Node::NullPtr);
192 assert(root != Node::NullPtr);
193 assert(COLOR(q) == RED);
194 assert(LLINK(q) == Node::NullPtr and RLINK(q) == Node::NullPtr);
195
196 Node *p = root; // Current node
197 Node *fp = head; // p's parent
198 Node *ffp = fHead; // p's grandparent
199 Node *fffp = Node::NullPtr; // p's great-grandparent
200 Node *nextNode;
201
202 while (true)
203 {
204 if (equals(KEY(q), KEY(p)))
205 return nullptr; // Duplicated key, insertion not possible
206
207 // Proactive color flip: if p is black with two red children, flip
208 if (COLOR(p) == BLACK and COLOR(LLINK(p)) == RED
209 and COLOR(RLINK(p)) == RED)
210 {
211 flipColors(p);
212 if (COLOR(fp) == RED) // May violate red condition
213 {
214 assert(fffp != Node::NullPtr);
216 }
217 }
218
219 // Descend to appropriate child
220 if (less(KEY(q), KEY(p)))
221 {
222 if (LLINK(p) == Node::NullPtr)
223 break;
224 nextNode = LLINK(p);
225 }
226 else
227 {
228 if (RLINK(p) == Node::NullPtr)
229 break;
230 nextNode = RLINK(p);
231 }
232
233 // Update ancestor chain
234 fffp = ffp;
235 ffp = fp;
236 fp = p;
237 p = nextNode;
238 }
239
240 ++num_nodes;
241
242 // Perform insertion
243 if (less(KEY(q), KEY(p)))
244 LLINK(p) = q;
245 else
246 RLINK(p) = q;
247
248 if (COLOR(p) == RED) // May violate red condition
249 restoreRedCondition(q, p, fp, ffp);
250
251 return q;
252 }
253
256 {
257 assert(q != Node::NullPtr);
258 assert(root != Node::NullPtr);
259 assert(COLOR(q) == RED);
260 assert(LLINK(q) == Node::NullPtr and RLINK(q) == Node::NullPtr);
261
262 Node *p = root;
263 Node *fp = head;
264 Node *ffp = fHead;
265 Node *fffp = Node::NullPtr;
266 Node *nextNode;
267
268 while (true)
269 {
270 // Proactive color flip
271 if (COLOR(p) == BLACK and COLOR(LLINK(p)) == RED
272 and COLOR(RLINK(p)) == RED)
273 {
274 flipColors(p);
275 if (COLOR(fp) == RED)
276 {
277 assert(fffp != Node::NullPtr);
279 }
280 }
281
282 // Descend (duplicates go right)
283 if (less(KEY(q), KEY(p)))
284 {
285 if (LLINK(p) == Node::NullPtr)
286 break;
287 nextNode = LLINK(p);
288 }
289 else // >= goes right
290 {
291 if (RLINK(p) == Node::NullPtr)
292 break;
293 nextNode = RLINK(p);
294 }
295
296 fffp = ffp;
297 ffp = fp;
298 fp = p;
299 p = nextNode;
300 }
301
302 ++num_nodes;
303
304 if (less(KEY(q), KEY(p)))
305 LLINK(p) = q;
306 else
307 RLINK(p) = q;
308
309 if (COLOR(p) == RED)
310 restoreRedCondition(q, p, fp, ffp);
311
312 return q;
313 }
314
316 static Node* gotoLeftAndColorRed(Node *fp, Node *&ffp) noexcept
317 {
318 assert(fp != Node::NullPtr);
319 assert(ffp != Node::NullPtr);
320 assert(LLINK(ffp) == fp or RLINK(ffp) == fp);
321 assert(LLINK(fp) != Node::NullPtr);
322
323 Node *p = LLINK(fp);
324
325 if (COLOR(p) == RED)
326 return p;
327
328 Node *sp = RLINK(fp);
329
330 // fp black means we came from another black node
331 if (COLOR(fp) == BLACK)
332 {
333 assert(COLOR(sp) == RED);
335 COLOR(fp) = RED;
336 COLOR(sp) = BLACK;
337 ffp = sp;
338 sp = RLINK(fp);
339 }
340
341 if (COLOR(LLINK(p)) == BLACK and COLOR(RLINK(p)) == BLACK)
342 {
343 assert(COLOR(LLINK(fp)) == BLACK);
344 assert(COLOR(RLINK(fp)) == BLACK);
345 assert(COLOR(fp) == RED);
346
347 COLOR(p) = RED;
348 COLOR(fp) = BLACK;
349
350 Node *np = RLINK(sp); // Nephew of p
351 Node *snp = LLINK(sp); // Sibling-nephew of p
352
353 if (COLOR(snp) == BLACK and COLOR(np) == BLACK)
354 {
355 COLOR(sp) = RED;
356 return p;
357 }
358
359 if (COLOR(np) == RED)
360 {
362 COLOR(sp) = RED;
363 COLOR(np) = BLACK;
364 assert(ffp == sp);
365 return p;
366 }
367
368 assert(COLOR(snp) == RED);
369
372 assert(ffp == snp);
373 }
374 return p;
375 }
376
378 static Node* gotoRightAndColorRed(Node *fp, Node *&ffp) noexcept
379 {
380 assert(fp != Node::NullPtr);
381 assert(ffp != Node::NullPtr);
382 assert(LLINK(ffp) == fp or RLINK(ffp) == fp);
383 assert(RLINK(fp) != Node::NullPtr);
384
385 Node *p = RLINK(fp);
386
387 if (COLOR(p) == RED)
388 return p;
389
390 Node *sp = LLINK(fp);
391
392 if (COLOR(fp) == BLACK)
393 {
394 assert(COLOR(sp) == RED);
396 COLOR(fp) = RED;
397 COLOR(sp) = BLACK;
398 ffp = sp;
399 sp = LLINK(fp);
400 }
401
402 if (COLOR(LLINK(p)) == BLACK and COLOR(RLINK(p)) == BLACK)
403 {
404 assert(COLOR(RLINK(fp)) == BLACK);
405 assert(COLOR(LLINK(fp)) == BLACK);
406 assert(COLOR(fp) == RED);
407
408 COLOR(p) = RED;
409 COLOR(fp) = BLACK;
410
411 Node *np = LLINK(sp); // Nephew of p
412 Node *snp = RLINK(sp); // Sibling-nephew of p
413
414 if (COLOR(snp) == BLACK and COLOR(np) == BLACK)
415 {
416 COLOR(sp) = RED;
417 return p;
418 }
419
420 if (COLOR(np) == RED)
421 {
423 COLOR(sp) = RED;
424 COLOR(np) = BLACK;
425 assert(ffp == sp);
426 return p;
427 }
428
429 assert(COLOR(snp) == RED);
430
433 assert(ffp == snp);
434 }
435 return p;
436 }
437
439 static void findSuccAndSwap(Node *p, Node *&fp) noexcept
440 {
441 assert(p != Node::NullPtr);
442 assert(RLINK(p) != Node::NullPtr);
443 assert(fp != Node::NullPtr);
444 assert(LLINK(fp) == p or RLINK(fp) == p);
445
446 Node *fSucc = p;
447 Node *succ = gotoRightAndColorRed(p, fp);
448 Node *ffSucc = fp;
449
450 while (LLINK(succ) != Node::NullPtr)
451 {
452 ffSucc = fSucc;
453 fSucc = succ;
455 }
456
457 // Update parent of p to point to succ
458 if (LLINK(fp) == p)
459 LLINK(fp) = succ;
460 else
461 RLINK(fp) = succ;
462
463 // Swap left branches
464 LLINK(succ) = LLINK(p);
465 LLINK(p) = Node::NullPtr;
466
467 // Swap right branches (two cases)
468 if (RLINK(p) == succ)
469 {
470 RLINK(p) = RLINK(succ);
471 RLINK(succ) = p;
472 fSucc = fp;
473 fp = succ;
474 }
475 else
476 {
477 Node *tmp = fp;
478 Node *succr = RLINK(succ);
479
480 RLINK(succ) = RLINK(p);
481 LLINK(fSucc) = p;
482 RLINK(p) = succr;
483 fp = fSucc;
484 fSucc = tmp;
485 }
486
487 // Swap colors
488 Color tmp = COLOR(succ);
489 COLOR(succ) = COLOR(p);
490 COLOR(p) = tmp;
491 }
492
494 static void findPredAndSwap(Node *p, Node *&fp) noexcept
495 {
496 assert(p != Node::NullPtr);
497 assert(LLINK(p) != Node::NullPtr);
498 assert(fp != Node::NullPtr);
499 assert(LLINK(fp) == p or RLINK(fp) == p);
500
501 Node *fPred = p;
503 Node *ffPred = fp;
504
505 while (RLINK(pred) != Node::NullPtr)
506 {
507 ffPred = fPred;
508 fPred = pred;
510 }
511
512 // Update parent of p to point to pred
513 if (LLINK(fp) == p)
514 LLINK(fp) = pred;
515 else
516 RLINK(fp) = pred;
517
518 // Swap right branches
519 RLINK(pred) = RLINK(p);
520 RLINK(p) = Node::NullPtr;
521
522 // Swap left branches (two cases)
523 if (LLINK(p) == pred)
524 {
525 LLINK(p) = LLINK(pred);
526 LLINK(pred) = p;
527 fPred = fp;
528 fp = pred;
529 }
530 else
531 {
532 Node *tmp = fp;
533 Node *predl = LLINK(pred);
534
535 LLINK(pred) = LLINK(p);
536 RLINK(fPred) = p;
537 LLINK(p) = predl;
538 fp = fPred;
539 fPred = tmp;
540 }
541
542 // Swap colors
543 Color tmp = COLOR(pred);
544 COLOR(pred) = COLOR(p);
545 COLOR(p) = tmp;
546 }
547
550 {
551 if (COLOR(root) == RED)
552 return;
553
554 if (COLOR(LLINK(root)) == BLACK and COLOR(RLINK(root)) == BLACK)
555 COLOR(root) = RED;
556 }
557
559 Node* searchAndColorRed(const Key& key, Node *&fp) noexcept
560 {
561 Node *p = root;
562 fp = head;
563 Node *ffp = fHead;
564
566
567 while (true)
568 {
569 if (equals(key, KEY(p)))
570 return p;
571
572 ffp = fp;
573 fp = p;
574
575 if (less(key, KEY(p)))
576 {
577 if (LLINK(p) == Node::NullPtr)
578 return p;
580 }
581 else
582 {
583 if (RLINK(p) == Node::NullPtr)
584 return p;
586 }
587 }
588 }
589
591 static void removeAndRendLeafRed(Node *p, Node *fp) noexcept
592 {
593 assert(p != Node::NullPtr);
594 assert(fp != Node::NullPtr);
595 assert(LLINK(fp) == p or RLINK(fp) == p);
596
597 while (LLINK(p) != Node::NullPtr or RLINK(p) != Node::NullPtr)
598 {
599 if (RLINK(p) != Node::NullPtr)
601 else if (LLINK(p) != Node::NullPtr)
603 }
604
605 if (LLINK(fp) == p)
606 LLINK(fp) = Node::NullPtr;
607 else
608 RLINK(fp) = Node::NullPtr;
609 }
610
613 {
614 RLINK(fHead) = head;
615 COLOR(Node::NullPtr) = BLACK;
616 COLOR(head) = BLACK;
617 num_nodes = 0;
618 }
619
620public:
623 : head(&headNode), fHead(&headParent), root(headNode.getR()), cmp()
624 {
625 init();
626 }
627
629 explicit GenTdRbTree(const Compare & __cmp) noexcept
631 {
632 init();
633 }
634
637 : head(&headNode), fHead(&headParent), root(headNode.getR()),
638 cmp(std::move(other.cmp)), num_nodes(other.num_nodes)
639 {
640 RLINK(fHead) = head;
641 COLOR(Node::NullPtr) = BLACK;
642 COLOR(head) = BLACK;
643 root = other.root;
644 other.root = Node::NullPtr;
645 other.num_nodes = 0;
646 }
647
650 {
651 if (this != &other)
652 {
653 root = other.root;
654 num_nodes = other.num_nodes;
655 cmp = std::move(other.cmp);
656 other.root = Node::NullPtr;
657 other.num_nodes = 0;
658 }
659 return *this;
660 }
661
663 GenTdRbTree(const GenTdRbTree &) = delete;
664
666 GenTdRbTree & operator=(const GenTdRbTree &) = delete;
667
670 {
671 root = Node::NullPtr;
672 num_nodes = 0;
673 }
674
676 void swap(GenTdRbTree & other) noexcept
677 {
678 std::swap(root, other.root);
679 std::swap(num_nodes, other.num_nodes);
680 std::swap(cmp, other.cmp);
681 }
682
683 virtual ~GenTdRbTree() = default;
684
686 size_t size() const noexcept { return num_nodes; }
687
689 bool is_empty() const noexcept { return root == Node::NullPtr; }
690
692 Compare & get_compare() noexcept { return cmp; }
693 const Compare & get_compare() const noexcept { return cmp; }
694
700 Node* insert(Node *p) noexcept
701 {
702 assert(p != Node::NullPtr);
703 assert(COLOR(p) == RED);
704 assert(LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr);
705
706 if (root == Node::NullPtr)
707 {
708 root = p;
709 ++num_nodes;
710 return p;
711 }
712
714 }
715
721 Node* insert_dup(Node *p) noexcept
722 {
723 assert(p != Node::NullPtr);
724 assert(COLOR(p) == RED);
725 assert(LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr);
726
727 if (root == Node::NullPtr)
728 {
729 root = p;
730 ++num_nodes;
731 return p;
732 }
733
735 }
736
743 {
744 assert(p != Node::NullPtr);
745 assert(COLOR(p) == RED);
746 assert(LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr);
747
748 if (root == Node::NullPtr)
749 {
750 root = p;
751 ++num_nodes;
752 return p;
753 }
754
755 // Search first
756 Node *found = search(KEY(p));
757 if (found != nullptr)
758 return found; // Return existing node
759
760 // Not found, insert
762 }
763
769 Node* search(const Key& key) const noexcept
770 {
771 Node* p = root;
772 while (p != Node::NullPtr)
773 {
774 if (equals(key, KEY(p)))
775 return p;
776 p = less(key, KEY(p)) ? LLINK(p) : RLINK(p);
777 }
778 return nullptr;
779 }
780
786 Node* remove(const Key& key) noexcept
787 {
788 if (root == Node::NullPtr)
789 return nullptr;
790
791 Node *fp;
792 Node *p = searchAndColorRed(key, fp);
793
794 if (not equals(KEY(p), key))
795 return nullptr;
796
798 --num_nodes;
799
800 return p;
801 }
802
804 Node*& getRoot() noexcept { return root; }
805
808
809private:
811 static bool testBlackHeight(Node *p, int &max, int bh = 0) noexcept
812 {
813 if (p == Node::NullPtr)
814 return true;
815
816 if (COLOR(p) == BLACK)
817 ++bh;
818
819 if (LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr)
820 {
821 if (max == -1)
822 max = bh;
823 return bh == max;
824 }
825
826 return testBlackHeight(LLINK(p), max, bh)
828 }
829
831 static bool testNode(Node* p) noexcept
832 {
833 if (p == Node::NullPtr)
834 return true;
835
836 // Red nodes must have black children
837 if (COLOR(p) == RED and
838 not (COLOR(LLINK(p)) == BLACK and COLOR(RLINK(p)) == BLACK))
839 return false;
840
841 int max = -1;
842 int bh = 0;
843
844 return testBlackHeight(p, max, bh);
845 }
846
848 static bool verify(Node* p) noexcept
849 {
850 if (p == Node::NullPtr)
851 return true;
852 if (not testNode(p))
853 return false;
854 return verify(LLINK(p)) and verify(RLINK(p));
855 }
856
857public:
863 {
864 if (root == Node::NullPtr)
865 return true;
866 return verify(root);
867 }
868
870 bool verify() const noexcept { return verifyRedBlack(); }
871
883};
884
890template <typename Key, class Compare = std::less<Key>>
891class TdRbTree : public GenTdRbTree<RbNode, Key, Compare>
892{
894public:
895 using Base::Base;
896};
897
903template <typename Key, class Compare = std::less<Key>>
904class TdRbTreeVtl : public GenTdRbTree<RbNodeVtl, Key, Compare>
905{
907public:
908 using Base::Base;
909};
910
911} // namespace Aleph
912
913# endif /* TPL_TDRBTREE_H */
@ KEY
Definition btreepic.C:169
Inorder iterator on the nodes of a binary tree.
Top-down red-black binary search tree implementation.
void reset() noexcept
Reset tree to empty state (does not free nodes)
virtual ~GenTdRbTree()=default
void init() noexcept
Initialize header nodes.
Compare & get_compare() noexcept
Get reference to comparator.
GenTdRbTree(GenTdRbTree &&other) noexcept
Move constructor.
bool is_empty() const noexcept
Check if tree is empty.
Node * insert_dup(Node *p) noexcept
Insert a node, allowing duplicates.
const Compare & get_compare() const noexcept
Node * fHead
Pointer to header's parent.
size_t size() const noexcept
Get number of nodes in tree (O(1))
Node *& root
Reference to root (right child of head)
Node * searchAndColorRed(const Key &key, Node *&fp) noexcept
Search for key while coloring nodes red for deletion.
static void flipColors(Node *p) noexcept
Flip colors: black parent with two red children becomes red with two black children.
Node * searchFlipColorsAndInsert(Node *q) noexcept
Search for insertion point, flipping colors proactively to maintain balance.
static Node * gotoLeftAndColorRed(Node *fp, Node *&ffp) noexcept
Descend to left child, ensuring current node is red for deletion.
Node headNode
Sentinel header node (parent of root)
void colorRootAsRed() noexcept
Color root red if safe (both children black)
void restoreRedCondition(Node *p, Node *&fp, Node *ffp, Node *fffp) noexcept
Restore red-black property after color flip creates two consecutive reds.
size_t num_nodes
Number of nodes in tree.
GenTdRbTree & operator=(GenTdRbTree &&other) noexcept
Move assignment operator.
GenTdRbTree & operator=(const GenTdRbTree &)=delete
Deleted copy assignment.
Node * remove(const Key &key) noexcept
Remove and return node with given key.
Node * searchFlipColorsAndInsertDup(Node *q) noexcept
Search for insertion point allowing duplicates.
Node * search_or_insert(Node *p) noexcept
Search for key or insert if not found.
static void findSuccAndSwap(Node *p, Node *&fp) noexcept
Find successor and swap with node p for deletion.
Node * search(const Key &key) const noexcept
Search for a key in the tree.
static Node * gotoRightAndColorRed(Node *fp, Node *&ffp) noexcept
Descend to right child, ensuring current node is red for deletion.
Node headParent
Sentinel grandparent node.
GenTdRbTree() noexcept
Default constructor.
NodeType< Key > Node
bool verifyRedBlack() const noexcept
Verify that tree satisfies all red-black properties.
Node * head
Pointer to header.
static void removeAndRendLeafRed(Node *p, Node *fp) noexcept
Remove node p and ensure it becomes a red leaf.
static bool verify(Node *p) noexcept
Recursively verify red-black properties.
static bool testBlackHeight(Node *p, int &max, int bh=0) noexcept
Test black height property recursively.
Node *& getRoot() noexcept
Get reference to root pointer.
static Node * getSibling(Node *p, Node *fp) noexcept
Get sibling of node p whose parent is fp.
GenTdRbTree(const Compare &__cmp) noexcept
Constructor with comparator.
bool less(const Key &a, const Key &b) const noexcept
Returns true if a < b according to comparator.
Node * getRoot() const noexcept
Get const root pointer
GenTdRbTree(const GenTdRbTree &)=delete
Deleted copy constructor (use explicit copy if needed)
Compare cmp
Comparison functor.
bool equals(const Key &a, const Key &b) const noexcept
Returns true if a == b (neither a < b nor b < a)
void swap(GenTdRbTree &other) noexcept
Swap contents with another tree.
Node * insert(Node *p) noexcept
Insert a node into the tree.
static void findPredAndSwap(Node *p, Node *&fp) noexcept
Find predecessor and swap with node p for deletion.
static bool testNode(Node *p) noexcept
Test red-black properties for a single node.
bool verify() const noexcept
Alias for verify.
Top-down red-black tree with virtual destructor.
Top-down red-black tree without virtual destructor.
__gmp_expr< typename __gmp_resolve_expr< T, V >::value_type, __gmp_binary_expr< __gmp_expr< T, U >, __gmp_expr< V, W >, __gmp_max_function > > max(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Definition gmpfrxx.h:4110
Node * rotate_to_left(Node *p) noexcept
Rotate to the left the tree with root p
Node * rotate_to_right(Node *p) noexcept
Rotate to the right the tree with root p
constexpr Node *& RLINK(Node *p) noexcept
Return the right tree of p.
constexpr Node *& LLINK(Node *p) noexcept
Return a pointer to left subtree.
Freq_Node * pred
Predecessor node in level-order traversal.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
DynList< T > maps(const C &c, Op op)
Classic map operation.
unsigned char Color
Definition rbNodeRk.H:50
#define COLOR(p)
Definition quadnode.H:58
Red-Black tree node definition and validation utilities.
#define BLACK
Black color constant.
Definition rbNode.H:76
#define RED
Red color constant (newly inserted nodes are red)
Definition rbNode.H:73
Iterator over tree nodes in sorted order.
Iterator(const GenTdRbTree &t)
Stack implementations backed by dynamic or fixed arrays.
Utility functions for binary tree operations.
Basic binary tree node definitions.