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# include <ah-concepts.H>
61
62namespace Aleph
63{
64
95template <template <class> class NodeType, typename Key,
96 class Compare = Aleph::less<Key>>
99{
100public:
102 using key_type = Key;
103 using compare_type = Compare;
104
105private:
111 Compare cmp;
112 size_t num_nodes;
113
115 bool less(const Key& a, const Key& b) const noexcept
116 {
117 return cmp(a, b);
118 }
119
121 bool equals(const Key& a, const Key& b) const noexcept
122 {
123 return not cmp(a, b) and not cmp(b, a);
124 }
125
127 static Node* getSibling(Node *p, Node *fp) noexcept
128 {
129 assert(LLINK(fp) == p or RLINK(fp) == p);
130 return LLINK(fp) == p ? RLINK(fp) : LLINK(fp);
131 }
132
134 void restoreRedCondition(Node *p, Node *&fp, Node *ffp, Node *fffp) noexcept
135 {
136 assert(LLINK(fp) == p or RLINK(fp) == p);
137 assert(COLOR(fp) == RED);
138 assert(COLOR(p) == RED);
139
140 if (fp == root)
141 {
142 COLOR(fp) = BLACK;
143 return;
144 }
145
146 assert(LLINK(ffp) == fp or RLINK(ffp) == fp);
147 assert(COLOR(ffp) == BLACK);
148 assert(LLINK(fffp) == ffp or RLINK(fffp) == ffp);
149
150 COLOR(ffp) = RED;
151
152 if (LLINK(fp) == p and LLINK(ffp) == fp)
153 {
154 COLOR(fp) = BLACK;
156 }
157 else if (RLINK(fp) == p and RLINK(ffp) == fp)
158 {
159 COLOR(fp) = BLACK;
161 }
162 else
163 {
164 COLOR(p) = BLACK;
165 if (RLINK(fp) == p)
166 {
167 rotate_to_left(fp, ffp);
169 }
170 else
171 {
172 rotate_to_right(fp, ffp);
174 }
175 fp = fffp;
176 }
177 }
178
180 static void flipColors(Node* p) noexcept
181 {
182 assert(p != Node::NullPtr);
183 assert(COLOR(p) == BLACK);
184 assert(COLOR(LLINK(p)) == RED and COLOR(RLINK(p)) == RED);
185
186 COLOR(p) = RED;
187 COLOR(LLINK(p)) = COLOR(RLINK(p)) = BLACK;
188 }
189
192 {
193 assert(q != Node::NullPtr);
194 assert(root != Node::NullPtr);
195 assert(COLOR(q) == RED);
196 assert(LLINK(q) == Node::NullPtr and RLINK(q) == Node::NullPtr);
197
198 Node *p = root; // Current node
199 Node *fp = head; // p's parent
200 Node *ffp = fHead; // p's grandparent
201 Node *fffp = Node::NullPtr; // p's great-grandparent
202 Node *nextNode;
203
204 while (true)
205 {
206 if (equals(KEY(q), KEY(p)))
207 return nullptr; // Duplicated key, insertion not possible
208
209 // Proactive color flip: if p is black with two red children, flip
210 if (COLOR(p) == BLACK and COLOR(LLINK(p)) == RED
211 and COLOR(RLINK(p)) == RED)
212 {
213 flipColors(p);
214 if (COLOR(fp) == RED) // May violate red condition
215 {
216 assert(fffp != Node::NullPtr);
218 }
219 }
220
221 // Descend to appropriate child
222 if (less(KEY(q), KEY(p)))
223 {
224 if (LLINK(p) == Node::NullPtr)
225 break;
226 nextNode = LLINK(p);
227 }
228 else
229 {
230 if (RLINK(p) == Node::NullPtr)
231 break;
232 nextNode = RLINK(p);
233 }
234
235 // Update ancestor chain
236 fffp = ffp;
237 ffp = fp;
238 fp = p;
239 p = nextNode;
240 }
241
242 ++num_nodes;
243
244 // Perform insertion
245 if (less(KEY(q), KEY(p)))
246 LLINK(p) = q;
247 else
248 RLINK(p) = q;
249
250 if (COLOR(p) == RED) // May violate red condition
251 restoreRedCondition(q, p, fp, ffp);
252
253 return q;
254 }
255
258 {
259 assert(q != Node::NullPtr);
260 assert(root != Node::NullPtr);
261 assert(COLOR(q) == RED);
262 assert(LLINK(q) == Node::NullPtr and RLINK(q) == Node::NullPtr);
263
264 Node *p = root;
265 Node *fp = head;
266 Node *ffp = fHead;
267 Node *fffp = Node::NullPtr;
268 Node *nextNode;
269
270 while (true)
271 {
272 // Proactive color flip
273 if (COLOR(p) == BLACK and COLOR(LLINK(p)) == RED
274 and COLOR(RLINK(p)) == RED)
275 {
276 flipColors(p);
277 if (COLOR(fp) == RED)
278 {
279 assert(fffp != Node::NullPtr);
281 }
282 }
283
284 // Descend (duplicates go right)
285 if (less(KEY(q), KEY(p)))
286 {
287 if (LLINK(p) == Node::NullPtr)
288 break;
289 nextNode = LLINK(p);
290 }
291 else // >= goes right
292 {
293 if (RLINK(p) == Node::NullPtr)
294 break;
295 nextNode = RLINK(p);
296 }
297
298 fffp = ffp;
299 ffp = fp;
300 fp = p;
301 p = nextNode;
302 }
303
304 ++num_nodes;
305
306 if (less(KEY(q), KEY(p)))
307 LLINK(p) = q;
308 else
309 RLINK(p) = q;
310
311 if (COLOR(p) == RED)
312 restoreRedCondition(q, p, fp, ffp);
313
314 return q;
315 }
316
318 static Node* gotoLeftAndColorRed(Node *fp, Node *&ffp) noexcept
319 {
320 assert(fp != Node::NullPtr);
321 assert(ffp != Node::NullPtr);
322 assert(LLINK(ffp) == fp or RLINK(ffp) == fp);
323 assert(LLINK(fp) != Node::NullPtr);
324
325 Node *p = LLINK(fp);
326
327 if (COLOR(p) == RED)
328 return p;
329
330 Node *sp = RLINK(fp);
331
332 // fp black means we came from another black node
333 if (COLOR(fp) == BLACK)
334 {
335 assert(COLOR(sp) == RED);
336 rotate_to_left(fp, ffp);
337 COLOR(fp) = RED;
338 COLOR(sp) = BLACK;
339 ffp = sp;
340 sp = RLINK(fp);
341 }
342
343 if (COLOR(LLINK(p)) == BLACK and COLOR(RLINK(p)) == BLACK)
344 {
345 assert(COLOR(LLINK(fp)) == BLACK);
346 assert(COLOR(RLINK(fp)) == BLACK);
347 assert(COLOR(fp) == RED);
348
349 COLOR(p) = RED;
350 COLOR(fp) = BLACK;
351
352 Node *np = RLINK(sp); // Nephew of p
353 Node *snp = LLINK(sp); // Sibling-nephew of p
354
355 if (COLOR(snp) == BLACK and COLOR(np) == BLACK)
356 {
357 COLOR(sp) = RED;
358 return p;
359 }
360
361 if (COLOR(np) == RED)
362 {
363 ffp = rotate_to_left(fp, ffp);
364 COLOR(sp) = RED;
365 COLOR(np) = BLACK;
366 assert(ffp == sp);
367 return p;
368 }
369
370 assert(COLOR(snp) == RED);
371
372 rotate_to_right(sp, fp);
373 ffp = rotate_to_left(fp, ffp);
374 assert(ffp == snp);
375 }
376 return p;
377 }
378
380 static Node* gotoRightAndColorRed(Node *fp, Node *&ffp) noexcept
381 {
382 assert(fp != Node::NullPtr);
383 assert(ffp != Node::NullPtr);
384 assert(LLINK(ffp) == fp or RLINK(ffp) == fp);
385 assert(RLINK(fp) != Node::NullPtr);
386
387 Node *p = RLINK(fp);
388
389 if (COLOR(p) == RED)
390 return p;
391
392 Node *sp = LLINK(fp);
393
394 if (COLOR(fp) == BLACK)
395 {
396 assert(COLOR(sp) == RED);
397 rotate_to_right(fp, ffp);
398 COLOR(fp) = RED;
399 COLOR(sp) = BLACK;
400 ffp = sp;
401 sp = LLINK(fp);
402 }
403
404 if (COLOR(LLINK(p)) == BLACK and COLOR(RLINK(p)) == BLACK)
405 {
406 assert(COLOR(RLINK(fp)) == BLACK);
407 assert(COLOR(LLINK(fp)) == BLACK);
408 assert(COLOR(fp) == RED);
409
410 COLOR(p) = RED;
411 COLOR(fp) = BLACK;
412
413 Node *np = LLINK(sp); // Nephew of p
414 Node *snp = RLINK(sp); // Sibling-nephew of p
415
416 if (COLOR(snp) == BLACK and COLOR(np) == BLACK)
417 {
418 COLOR(sp) = RED;
419 return p;
420 }
421
422 if (COLOR(np) == RED)
423 {
424 ffp = rotate_to_right(fp, ffp);
425 COLOR(sp) = RED;
426 COLOR(np) = BLACK;
427 assert(ffp == sp);
428 return p;
429 }
430
431 assert(COLOR(snp) == RED);
432
433 rotate_to_left(sp, fp);
434 ffp = rotate_to_right(fp, ffp);
435 assert(ffp == snp);
436 }
437 return p;
438 }
439
441 static void findSuccAndSwap(Node *p, Node *&fp) noexcept
442 {
443 assert(p != Node::NullPtr);
444 assert(RLINK(p) != Node::NullPtr);
445 assert(fp != Node::NullPtr);
446 assert(LLINK(fp) == p or RLINK(fp) == p);
447
448 Node *fSucc = p;
449 Node *succ = gotoRightAndColorRed(p, fp);
450 Node *ffSucc = fp;
451
452 while (LLINK(succ) != Node::NullPtr)
453 {
454 ffSucc = fSucc;
455 fSucc = succ;
457 }
458
459 // Update parent of p to point to succ
460 if (LLINK(fp) == p)
461 LLINK(fp) = succ;
462 else
463 RLINK(fp) = succ;
464
465 // Swap left branches
466 LLINK(succ) = LLINK(p);
467 LLINK(p) = Node::NullPtr;
468
469 // Swap right branches (two cases)
470 if (RLINK(p) == succ)
471 {
472 RLINK(p) = RLINK(succ);
473 RLINK(succ) = p;
474 fSucc = fp;
475 fp = succ;
476 }
477 else
478 {
479 Node *tmp = fp;
480 Node *succr = RLINK(succ);
481
482 RLINK(succ) = RLINK(p);
483 LLINK(fSucc) = p;
484 RLINK(p) = succr;
485 fp = fSucc;
486 fSucc = tmp;
487 }
488
489 // Swap colors
490 Color tmp = COLOR(succ);
491 COLOR(succ) = COLOR(p);
492 COLOR(p) = tmp;
493 }
494
496 static void findPredAndSwap(Node *p, Node *&fp) noexcept
497 {
498 assert(p != Node::NullPtr);
499 assert(LLINK(p) != Node::NullPtr);
500 assert(fp != Node::NullPtr);
501 assert(LLINK(fp) == p or RLINK(fp) == p);
502
503 Node *fPred = p;
504 Node *pred = gotoLeftAndColorRed(p, fp);
505 Node *ffPred = fp;
506
507 while (RLINK(pred) != Node::NullPtr)
508 {
509 ffPred = fPred;
510 fPred = pred;
512 }
513
514 // Update parent of p to point to pred
515 if (LLINK(fp) == p)
516 LLINK(fp) = pred;
517 else
518 RLINK(fp) = pred;
519
520 // Swap right branches
521 RLINK(pred) = RLINK(p);
522 RLINK(p) = Node::NullPtr;
523
524 // Swap left branches (two cases)
525 if (LLINK(p) == pred)
526 {
527 LLINK(p) = LLINK(pred);
528 LLINK(pred) = p;
529 fPred = fp;
530 fp = pred;
531 }
532 else
533 {
534 Node *tmp = fp;
535 Node *predl = LLINK(pred);
536
537 LLINK(pred) = LLINK(p);
538 RLINK(fPred) = p;
539 LLINK(p) = predl;
540 fp = fPred;
541 fPred = tmp;
542 }
543
544 // Swap colors
545 Color tmp = COLOR(pred);
546 COLOR(pred) = COLOR(p);
547 COLOR(p) = tmp;
548 }
549
552 {
553 if (COLOR(root) == RED)
554 return;
555
556 if (COLOR(LLINK(root)) == BLACK and COLOR(RLINK(root)) == BLACK)
557 COLOR(root) = RED;
558 }
559
561 Node* searchAndColorRed(const Key& key, Node *&fp) noexcept
562 {
563 Node *p = root;
564 fp = head;
565 Node *ffp = fHead;
566
568
569 while (true)
570 {
571 if (equals(key, KEY(p)))
572 return p;
573
574 ffp = fp;
575 fp = p;
576
577 if (less(key, KEY(p)))
578 {
579 if (LLINK(p) == Node::NullPtr)
580 return p;
581 p = gotoLeftAndColorRed(fp, ffp);
582 }
583 else
584 {
585 if (RLINK(p) == Node::NullPtr)
586 return p;
587 p = gotoRightAndColorRed(fp, ffp);
588 }
589 }
590 }
591
593 static void removeAndRendLeafRed(Node *p, Node *fp) noexcept
594 {
595 assert(p != Node::NullPtr);
596 assert(fp != Node::NullPtr);
597 assert(LLINK(fp) == p or RLINK(fp) == p);
598
599 while (LLINK(p) != Node::NullPtr or RLINK(p) != Node::NullPtr)
600 {
601 if (RLINK(p) != Node::NullPtr)
602 findSuccAndSwap(p, fp);
603 else if (LLINK(p) != Node::NullPtr)
604 findPredAndSwap(p, fp);
605 }
606
607 if (LLINK(fp) == p)
608 LLINK(fp) = Node::NullPtr;
609 else
610 RLINK(fp) = Node::NullPtr;
611 }
612
615 {
616 RLINK(fHead) = head;
617 COLOR(Node::NullPtr) = BLACK;
618 COLOR(head) = BLACK;
619 num_nodes = 0;
620 }
621
622public:
625 : head(&headNode), fHead(&headParent), root(headNode.getR()), cmp()
626 {
627 init();
628 }
629
631 explicit GenTdRbTree(const Compare & __cmp) noexcept
633 {
634 init();
635 }
636
639 : head(&headNode), fHead(&headParent), root(headNode.getR()),
640 cmp(std::move(other.cmp)), num_nodes(other.num_nodes)
641 {
642 RLINK(fHead) = head;
643 COLOR(Node::NullPtr) = BLACK;
644 COLOR(head) = BLACK;
645 root = other.root;
646 other.root = Node::NullPtr;
647 other.num_nodes = 0;
648 }
649
652 {
653 if (this != &other)
654 {
655 root = other.root;
656 num_nodes = other.num_nodes;
657 cmp = std::move(other.cmp);
658 other.root = Node::NullPtr;
659 other.num_nodes = 0;
660 }
661 return *this;
662 }
663
665 GenTdRbTree(const GenTdRbTree &) = delete;
666
668 GenTdRbTree & operator=(const GenTdRbTree &) = delete;
669
672 {
673 root = Node::NullPtr;
674 num_nodes = 0;
675 }
676
678 void swap(GenTdRbTree & other) noexcept
679 {
680 std::swap(root, other.root);
681 std::swap(num_nodes, other.num_nodes);
682 std::swap(cmp, other.cmp);
683 }
684
685 virtual ~GenTdRbTree() = default;
686
688 size_t size() const noexcept { return num_nodes; }
689
691 bool is_empty() const noexcept { return root == Node::NullPtr; }
692
694 Compare & get_compare() noexcept { return cmp; }
695 const Compare & get_compare() const noexcept { return cmp; }
696
702 Node* insert(Node *p) noexcept
703 {
704 assert(p != Node::NullPtr);
705 assert(COLOR(p) == RED);
706 assert(LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr);
707
708 if (root == Node::NullPtr)
709 {
710 root = p;
711 ++num_nodes;
712 return p;
713 }
714
716 }
717
723 Node* insert_dup(Node *p) noexcept
724 {
725 assert(p != Node::NullPtr);
726 assert(COLOR(p) == RED);
727 assert(LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr);
728
729 if (root == Node::NullPtr)
730 {
731 root = p;
732 ++num_nodes;
733 return p;
734 }
735
737 }
738
745 {
746 assert(p != Node::NullPtr);
747 assert(COLOR(p) == RED);
748 assert(LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr);
749
750 if (root == Node::NullPtr)
751 {
752 root = p;
753 ++num_nodes;
754 return p;
755 }
756
757 // Search first
758 Node *found = search(KEY(p));
759 if (found != nullptr)
760 return found; // Return existing node
761
762 // Not found, insert
764 }
765
771 Node* search(const Key& key) const noexcept
772 {
773 Node* p = root;
774 while (p != Node::NullPtr)
775 {
776 if (equals(key, KEY(p)))
777 return p;
778 p = less(key, KEY(p)) ? LLINK(p) : RLINK(p);
779 }
780 return nullptr;
781 }
782
788 Node* remove(const Key& key) noexcept
789 {
790 if (root == Node::NullPtr)
791 return nullptr;
792
793 Node *fp;
794 Node *p = searchAndColorRed(key, fp);
795
796 if (not equals(KEY(p), key))
797 return nullptr;
798
800 --num_nodes;
801
802 return p;
803 }
804
806 Node*& getRoot() noexcept { return root; }
807
810
811private:
813 static bool testBlackHeight(Node *p, int &max, int bh = 0) noexcept
814 {
815 if (p == Node::NullPtr)
816 return true;
817
818 if (COLOR(p) == BLACK)
819 ++bh;
820
821 if (LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr)
822 {
823 if (max == -1)
824 max = bh;
825 return bh == max;
826 }
827
828 return testBlackHeight(LLINK(p), max, bh)
830 }
831
833 static bool testNode(Node* p) noexcept
834 {
835 if (p == Node::NullPtr)
836 return true;
837
838 // Red nodes must have black children
839 if (COLOR(p) == RED and
840 not (COLOR(LLINK(p)) == BLACK and COLOR(RLINK(p)) == BLACK))
841 return false;
842
843 int max = -1;
844 int bh = 0;
845
846 return testBlackHeight(p, max, bh);
847 }
848
850 static bool verify(Node* p) noexcept
851 {
852 if (p == Node::NullPtr)
853 return true;
854 if (not testNode(p))
855 return false;
856 return verify(LLINK(p)) and verify(RLINK(p));
857 }
858
859public:
865 {
866 if (root == Node::NullPtr)
867 return true;
868 return verify(root);
869 }
870
872 bool verify() const noexcept { return verifyRedBlack(); }
873
885};
886
892template <typename Key, class Compare = Aleph::less<Key>>
894class TdRbTree : public GenTdRbTree<RbNode, Key, Compare>
895{
897public:
898 using Base::Base;
899};
900
906template <typename Key, class Compare = Aleph::less<Key>>
908class TdRbTreeVtl : public GenTdRbTree<RbNodeVtl, Key, Compare>
909{
911public:
912 using Base::Base;
913};
914
915} // namespace Aleph
916
917# endif /* TPL_TDRBTREE_H */
C++20 concepts for constraining comparison functors.
@ 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.
Strict weak ordering constraint for BST comparators.
Definition ah-concepts.H:84
__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
Freq_Node * pred
Predecessor node in level-order traversal.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
and
Check uniqueness with explicit hash + equality functors.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
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)
#define RLINK(i, n)
#define LLINK(i, n)
Stack implementations backed by dynamic or fixed arrays.
Utility functions for binary tree operations.
Basic binary tree node definitions.