Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_tdRbTreeRk.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
50# ifndef TPL_TDRBTREERK_H
51# define TPL_TDRBTREERK_H
52
53# include <functional>
54# include <limits>
55# include <tpl_binNode.H>
56# include <tpl_binNodeUtils.H>
57# include <tpl_binNodeXt.H>
58# include <tpl_binTreeOps.H>
59# include <rbNodeRk.H>
60# include <ah-concepts.H>
61
62namespace Aleph
63{
64
96template <template <class> class NodeType, typename Key,
97 class Compare = Aleph::less<Key>>
100{
101public:
103 using key_type = Key;
104 using compare_type = Compare;
105 static constexpr size_t PATH_STACK_CAPACITY = 128;
106 static_assert(PATH_STACK_CAPACITY >= 2 * std::numeric_limits<size_t>::digits,
107 "PATH_STACK_CAPACITY too small for red-black worst-case height");
108
109private:
115 Compare cmp;
116
118 bool less(const Key& a, const Key& b) const noexcept
119 {
120 return cmp(a, b);
121 }
122
124 bool equals(const Key& a, const Key& b) const noexcept
125 {
126 return not cmp(a, b) and not cmp(b, a);
127 }
128
130 static Node* rotate_to_right_rk(Node *p, Node *pp) noexcept
131 {
132 assert(p != Node::NullPtr);
133 assert(pp != Node::NullPtr);
134
135 Node *q = LLINK(p);
136 LLINK(p) = RLINK(q);
137 RLINK(q) = p;
138
139 // Update counters
140 COUNT(p) = COUNT(LLINK(p)) + COUNT(RLINK(p)) + 1;
141 COUNT(q) = COUNT(LLINK(q)) + COUNT(RLINK(q)) + 1;
142
143 if (LLINK(pp) == p)
144 LLINK(pp) = q;
145 else
146 RLINK(pp) = q;
147
148 return q;
149 }
150
152 static Node* rotate_to_left_rk(Node *p, Node *pp) noexcept
153 {
154 assert(p != Node::NullPtr);
155 assert(pp != Node::NullPtr);
156
157 Node *q = RLINK(p);
158 RLINK(p) = LLINK(q);
159 LLINK(q) = p;
160
161 // Update counters
162 COUNT(p) = COUNT(LLINK(p)) + COUNT(RLINK(p)) + 1;
163 COUNT(q) = COUNT(LLINK(q)) + COUNT(RLINK(q)) + 1;
164
165 if (LLINK(pp) == p)
166 LLINK(pp) = q;
167 else
168 RLINK(pp) = q;
169
170 return q;
171 }
172
174 void restoreRedCondition(Node *p, Node *&fp, Node *ffp, Node *fffp) noexcept
175 {
176 assert(LLINK(fp) == p or RLINK(fp) == p);
177 assert(COLOR(fp) == RED);
178 assert(COLOR(p) == RED);
179
180 if (fp == root)
181 {
182 COLOR(fp) = BLACK;
183 return;
184 }
185
186 assert(LLINK(ffp) == fp or RLINK(ffp) == fp);
187 assert(COLOR(ffp) == BLACK);
188 assert(LLINK(fffp) == ffp or RLINK(fffp) == ffp);
189
190 COLOR(ffp) = RED;
191
192 if (LLINK(fp) == p and LLINK(ffp) == fp)
193 {
194 COLOR(fp) = BLACK;
196 }
197 else if (RLINK(fp) == p and RLINK(ffp) == fp)
198 {
199 COLOR(fp) = BLACK;
201 }
202 else
203 {
204 COLOR(p) = BLACK;
205 if (RLINK(fp) == p)
206 {
209 }
210 else
211 {
214 }
215 fp = fffp;
216 }
217 }
218
220 static void flipColors(Node* p) noexcept
221 {
222 assert(p != Node::NullPtr);
223 assert(COLOR(p) == BLACK);
224 assert(COLOR(LLINK(p)) == RED and COLOR(RLINK(p)) == RED);
225
226 COLOR(p) = RED;
227 COLOR(LLINK(p)) = COLOR(RLINK(p)) = BLACK;
228 }
229
234 {
235 assert(q != Node::NullPtr);
236 assert(root != Node::NullPtr);
237 assert(COLOR(q) == RED);
238
239 // Stack to track visited nodes for count updates
241 size_t stack_len = 0;
242
243 Node *p = root;
244 Node *fp = head;
245 Node *ffp = fHead;
246 Node *fffp = Node::NullPtr;
247 Node *nextNode;
248
249 stack[stack_len++] = p;
250
251 while (true)
252 {
253 if (equals(KEY(q), KEY(p)))
254 return nullptr; // Duplicate key
255
256 if (COLOR(p) == BLACK and COLOR(LLINK(p)) == RED
257 and COLOR(RLINK(p)) == RED)
258 {
259 flipColors(p);
260 if (COLOR(fp) == RED)
261 {
262 assert(fffp != Node::NullPtr);
264 }
265 }
266
267 if (less(KEY(q), KEY(p)))
268 {
269 if (LLINK(p) == Node::NullPtr)
270 break;
271 nextNode = LLINK(p);
272 }
273 else
274 {
275 if (RLINK(p) == Node::NullPtr)
276 break;
277 nextNode = RLINK(p);
278 }
279
280 fffp = ffp;
281 ffp = fp;
282 fp = p;
283 p = nextNode;
284 stack[stack_len++] = p;
285 }
286
287 // Perform insertion
288 if (less(KEY(q), KEY(p)))
289 LLINK(p) = q;
290 else
291 RLINK(p) = q;
292
293 if (COLOR(p) == RED)
294 restoreRedCondition(q, p, fp, ffp);
295
296 // Update counts bottom-up - O(log n)
297 // Each node's count = left_count + right_count + 1
298 // Children are already correct (leaf has count=1, rotated nodes recalculated)
300
301 return q;
302 }
303
307 {
308 assert(q != Node::NullPtr);
309 assert(root != Node::NullPtr);
310 assert(COLOR(q) == RED);
311
313 size_t stack_len = 0;
314
315 Node *p = root;
316 Node *fp = head;
317 Node *ffp = fHead;
318 Node *fffp = Node::NullPtr;
319 Node *nextNode;
320
321 stack[stack_len++] = p;
322
323 while (true)
324 {
325 if (COLOR(p) == BLACK and COLOR(LLINK(p)) == RED
326 and COLOR(RLINK(p)) == RED)
327 {
328 flipColors(p);
329 if (COLOR(fp) == RED)
330 {
331 assert(fffp != Node::NullPtr);
333 }
334 }
335
336 if (less(KEY(q), KEY(p)))
337 {
338 if (LLINK(p) == Node::NullPtr)
339 break;
340 nextNode = LLINK(p);
341 }
342 else
343 {
344 if (RLINK(p) == Node::NullPtr)
345 break;
346 nextNode = RLINK(p);
347 }
348
349 fffp = ffp;
350 ffp = fp;
351 fp = p;
352 p = nextNode;
353 stack[stack_len++] = p;
354 }
355
356 if (less(KEY(q), KEY(p)))
357 LLINK(p) = q;
358 else
359 RLINK(p) = q;
360
361 if (COLOR(p) == RED)
362 restoreRedCondition(q, p, fp, ffp);
363
364 // Update counts bottom-up - O(log n)
366
367 return q;
368 }
369
371 static size_t updateCountRec(Node *p) noexcept
372 {
373 if (p == Node::NullPtr)
374 return 0;
375
376 size_t left_count = updateCountRec(LLINK(p));
377 size_t right_count = updateCountRec(RLINK(p));
378 COUNT(p) = left_count + right_count + 1;
379 return COUNT(p);
380 }
381
385 static void updateCountsFromStack(Node** stack, size_t len) noexcept
386 {
387 // Process bottom-up: children are already correct
388 while (len > 0)
389 {
390 Node* p = stack[--len];
391 COUNT(p) = COUNT(LLINK(p)) + COUNT(RLINK(p)) + 1;
392 }
393 }
394
395
397 static Node* gotoLeftAndColorRed(Node *fp, Node *&ffp) noexcept
398 {
399 assert(fp != Node::NullPtr);
400 assert(ffp != Node::NullPtr);
401 assert(LLINK(fp) != Node::NullPtr);
402
403 Node *p = LLINK(fp);
404
405 if (COLOR(p) == RED)
406 return p;
407
408 Node *sp = RLINK(fp);
409
410 if (COLOR(fp) == BLACK)
411 {
412 assert(COLOR(sp) == RED);
414 COLOR(fp) = RED;
415 COLOR(sp) = BLACK;
416 ffp = sp;
417 sp = RLINK(fp);
418 }
419
420 if (COLOR(LLINK(p)) == BLACK and COLOR(RLINK(p)) == BLACK)
421 {
422 assert(COLOR(fp) == RED);
423
424 COLOR(p) = RED;
425 COLOR(fp) = BLACK;
426
427 Node *np = RLINK(sp);
428 Node *snp = LLINK(sp);
429
430 if (COLOR(snp) == BLACK and COLOR(np) == BLACK)
431 {
432 COLOR(sp) = RED;
433 return p;
434 }
435
436 if (COLOR(np) == RED)
437 {
439 COLOR(sp) = RED;
440 COLOR(np) = BLACK;
441 return p;
442 }
443
444 assert(COLOR(snp) == RED);
445
448 }
449 return p;
450 }
451
453 static Node* gotoRightAndColorRed(Node *fp, Node *&ffp) noexcept
454 {
455 assert(fp != Node::NullPtr);
456 assert(ffp != Node::NullPtr);
457 assert(RLINK(fp) != Node::NullPtr);
458
459 Node *p = RLINK(fp);
460
461 if (COLOR(p) == RED)
462 return p;
463
464 Node *sp = LLINK(fp);
465
466 if (COLOR(fp) == BLACK)
467 {
468 assert(COLOR(sp) == RED);
470 COLOR(fp) = RED;
471 COLOR(sp) = BLACK;
472 ffp = sp;
473 sp = LLINK(fp);
474 }
475
476 if (COLOR(LLINK(p)) == BLACK and COLOR(RLINK(p)) == BLACK)
477 {
478 assert(COLOR(fp) == RED);
479
480 COLOR(p) = RED;
481 COLOR(fp) = BLACK;
482
483 Node *np = LLINK(sp);
484 Node *snp = RLINK(sp);
485
486 if (COLOR(snp) == BLACK and COLOR(np) == BLACK)
487 {
488 COLOR(sp) = RED;
489 return p;
490 }
491
492 if (COLOR(np) == RED)
493 {
495 COLOR(sp) = RED;
496 COLOR(np) = BLACK;
497 return p;
498 }
499
500 assert(COLOR(snp) == RED);
501
504 }
505 return p;
506 }
507
509 static void findSuccAndSwap(Node *p, Node *&fp) noexcept
510 {
511 assert(p != Node::NullPtr);
512 assert(RLINK(p) != Node::NullPtr);
513
514 size_t original_count = COUNT(p);
515
516 Node *fSucc = p;
517 Node *succ = gotoRightAndColorRed(p, fp);
518 Node *ffSucc = fp;
519
520 while (LLINK(succ) != Node::NullPtr)
521 {
522 ffSucc = fSucc;
523 fSucc = succ;
525 }
526
527 if (LLINK(fp) == p)
528 LLINK(fp) = succ;
529 else
530 RLINK(fp) = succ;
531
532 LLINK(succ) = LLINK(p);
533 LLINK(p) = Node::NullPtr;
534
535 if (RLINK(p) == succ)
536 {
537 RLINK(p) = RLINK(succ);
538 RLINK(succ) = p;
539 fSucc = fp;
540 fp = succ;
541 }
542 else
543 {
544 Node *tmp = fp;
545 Node *succr = RLINK(succ);
546
547 RLINK(succ) = RLINK(p);
548 LLINK(fSucc) = p;
549 RLINK(p) = succr;
550 fp = fSucc;
551 fSucc = tmp;
552 }
553
554 Color tmp = COLOR(succ);
555 COLOR(succ) = COLOR(p);
556 COLOR(p) = tmp;
557
558 // Preserve count at successor's new position
559 COUNT(succ) = original_count;
560 }
561
563 static void findPredAndSwap(Node *p, Node *&fp) noexcept
564 {
565 assert(p != Node::NullPtr);
566 assert(LLINK(p) != Node::NullPtr);
567
568 size_t original_count = COUNT(p);
569
570 Node *fPred = p;
571 Node *pred = gotoLeftAndColorRed(p, fp);
572 Node *ffPred = fp;
573
574 while (RLINK(pred) != Node::NullPtr)
575 {
576 ffPred = fPred;
577 fPred = pred;
579 }
580
581 if (LLINK(fp) == p)
582 LLINK(fp) = pred;
583 else
584 RLINK(fp) = pred;
585
586 RLINK(pred) = RLINK(p);
587 RLINK(p) = Node::NullPtr;
588
589 if (LLINK(p) == pred)
590 {
591 LLINK(p) = LLINK(pred);
592 LLINK(pred) = p;
593 fPred = fp;
594 fp = pred;
595 }
596 else
597 {
598 Node *tmp = fp;
599 Node *predl = LLINK(pred);
600
601 LLINK(pred) = LLINK(p);
602 RLINK(fPred) = p;
603 LLINK(p) = predl;
604 fp = fPred;
605 fPred = tmp;
606 }
607
608 Color tmp = COLOR(pred);
609 COLOR(pred) = COLOR(p);
610 COLOR(p) = tmp;
611
613 }
614
617 {
618 if (COLOR(root) == RED)
619 return;
620
621 if (COLOR(LLINK(root)) == BLACK and COLOR(RLINK(root)) == BLACK)
622 COLOR(root) = RED;
623 }
624
627 Node* searchAndColorRed(const Key& key, Node *&fp,
628 Node** stack, size_t& stack_len) noexcept
629 {
630 Node *p = root;
631 fp = head;
632 Node *ffp = fHead;
633
634 stack_len = 0;
635
637 stack[stack_len++] = p;
638
639 while (true)
640 {
641 if (equals(key, KEY(p)))
642 return p;
643
644 ffp = fp;
645 fp = p;
646
647 if (less(key, KEY(p)))
648 {
649 if (LLINK(p) == Node::NullPtr)
650 return p; // Key not found, return current
651 p = gotoLeftAndColorRed(fp, ffp);
652 }
653 else
654 {
655 if (RLINK(p) == Node::NullPtr)
656 return p; // Key not found, return current
657 p = gotoRightAndColorRed(fp, ffp);
658 }
659
660 stack[stack_len++] = p;
661 }
662 }
663
665 static void removeAndRendLeafRed(Node *p, Node *fp) noexcept
666 {
667 assert(p != Node::NullPtr);
668 assert(fp != Node::NullPtr);
669
670 while (LLINK(p) != Node::NullPtr or RLINK(p) != Node::NullPtr)
671 {
672 if (RLINK(p) != Node::NullPtr)
673 findSuccAndSwap(p, fp);
674 else if (LLINK(p) != Node::NullPtr)
675 findPredAndSwap(p, fp);
676 }
677
678 if (LLINK(fp) == p)
679 LLINK(fp) = Node::NullPtr;
680 else
681 RLINK(fp) = Node::NullPtr;
682 }
683
686 {
687 RLINK(fHead) = head;
688 COLOR(Node::NullPtr) = BLACK;
689 COUNT(Node::NullPtr) = 0;
690 COLOR(head) = BLACK;
691 COUNT(head) = 0;
692 }
693
694public:
697 : head(&headNode), fHead(&headParent), root(headNode.getR()), cmp()
698 {
699 init();
700 }
701
703 explicit GenTdRbTreeRk(const Compare & __cmp) noexcept
705 {
706 init();
707 }
708
711 : head(&headNode), fHead(&headParent), root(headNode.getR()),
712 cmp(std::move(other.cmp))
713 {
714 init();
715 root = other.root;
716 other.root = Node::NullPtr;
717 }
718
721 {
722 if (this != &other)
723 {
724 root = other.root;
725 cmp = std::move(other.cmp);
726 other.root = Node::NullPtr;
727 }
728 return *this;
729 }
730
731 GenTdRbTreeRk(const GenTdRbTreeRk &) = delete;
733
736 {
737 root = Node::NullPtr;
738 }
739
741 void swap(GenTdRbTreeRk & other) noexcept
742 {
743 std::swap(root, other.root);
744 std::swap(cmp, other.cmp);
745 }
746
747 virtual ~GenTdRbTreeRk() = default;
748
750 size_t size() const noexcept { return COUNT(root); }
751
753 bool is_empty() const noexcept { return root == Node::NullPtr; }
754
756 Compare & get_compare() noexcept { return cmp; }
757 const Compare & get_compare() const noexcept { return cmp; }
758
762 Node* insert(Node *p) noexcept
763 {
764 assert(p != Node::NullPtr);
765 assert(COLOR(p) == RED);
766 COUNT(p) = 1;
767
768 if (root == Node::NullPtr)
769 {
770 root = p;
771 return p;
772 }
773
775 }
776
780 Node* insert_dup(Node *p) noexcept
781 {
782 assert(p != Node::NullPtr);
783 assert(COLOR(p) == RED);
784 COUNT(p) = 1;
785
786 if (root == Node::NullPtr)
787 {
788 root = p;
789 return p;
790 }
791
793 }
794
799 {
800 assert(p != Node::NullPtr);
801 assert(COLOR(p) == RED);
802 COUNT(p) = 1;
803
804 if (root == Node::NullPtr)
805 {
806 root = p;
807 return p;
808 }
809
810 Node *found = search(KEY(p));
811 if (found != nullptr)
812 return found;
813
815 }
816
820 Node* search(const Key& key) const noexcept
821 {
822 Node* p = root;
823 while (p != Node::NullPtr)
824 {
825 if (equals(key, KEY(p)))
826 return p;
827 p = less(key, KEY(p)) ? LLINK(p) : RLINK(p);
828 }
829 return nullptr;
830 }
831
837 Node* remove(const Key& key) noexcept
838 {
839 if (root == Node::NullPtr)
840 return nullptr;
841
843 size_t stack_len = 0;
844
845 Node *fp;
846 Node *p = searchAndColorRed(key, fp, stack, stack_len);
847
848 if (not equals(KEY(p), key))
849 return nullptr;
850
852
853 // Recalculate counts for visited nodes - usually O(log n)
854 // For complex cases with many swaps, fall back to full recalc
855 if (root != Node::NullPtr)
856 {
857 // The stack contains nodes visited during search
858 // After swaps, some may have moved, so do full recalc for safety
860 }
861
862 return p;
863 }
864
866 Node*& getRoot() noexcept { return root; }
868
869 // ===================== RANK OPERATIONS =====================
870
876 Node* select(size_t i) const
877 {
878 return Aleph::select(root, i);
879 }
880
884 std::pair<long, Node*> position(const Key & key) const noexcept
885 {
886 std::pair<long, Node*> ret_val;
888 inorder_position(root, key, ret_val.second);
889 return ret_val;
890 }
891
895 std::pair<long, Node*> find_position(const Key & key) const noexcept
896 {
897 std::pair<long, Node*> r(-2, nullptr);
899 find_position(root, key, r.second);
900 return r;
901 }
902
907 Node* remove_pos(size_t i)
908 {
909 Node* p = select(i);
910 if (p == nullptr)
911 return nullptr;
912 return remove(KEY(p));
913 }
914
920 void split_pos(size_t pos, GenTdRbTreeRk & t1, GenTdRbTreeRk & t2) noexcept
921 {
922 if (root == Node::NullPtr)
923 return;
924
925 if (pos == 0)
926 {
927 t2.root = root;
928 root = Node::NullPtr;
929 return;
930 }
931
932 if (pos >= size())
933 {
934 t1.root = root;
935 root = Node::NullPtr;
936 return;
937 }
938
939 // Simple O(n) implementation
940 size_t count = 0;
942 root = Node::NullPtr;
943 }
944
945private:
946 void split_pos_inorder(Node *p, size_t pos,
948 size_t & count) noexcept
949 {
950 if (p == Node::NullPtr)
951 return;
952
953 Node *left = LLINK(p);
954 Node *right = RLINK(p);
955
956 split_pos_inorder(left, pos, t1, t2, count);
957
958 p->reset();
959 if (count < pos)
960 t1.insert(p);
961 else
962 t2.insert(p);
963 ++count;
964
965 split_pos_inorder(right, pos, t1, t2, count);
966 }
967
968public:
974
981};
982
987template <typename Key, class Compare = Aleph::less<Key>>
988class TdRbTreeRk : public GenTdRbTreeRk<RbNodeRk, Key, Compare>
989{
991public:
992 using Base::Base;
993};
994
999template <typename Key, class Compare = Aleph::less<Key>>
1000class TdRbTreeRkVtl : public GenTdRbTreeRk<RbNodeRkVtl, Key, Compare>
1001{
1003public:
1004 using Base::Base;
1005};
1006
1007} // namespace Aleph
1008
1009# endif /* TPL_TDRBTREERK_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 tree with rank support (select/position).
GenTdRbTreeRk(GenTdRbTreeRk &&other) noexcept
Move constructor.
GenTdRbTreeRk(const Compare &__cmp) noexcept
Constructor with comparator.
Node * select(size_t i) const
Select i-th node in order.
Node * searchAndColorRed(const Key &key, Node *&fp, Node **stack, size_t &stack_len) noexcept
Search for key while coloring nodes red for deletion.
static void findPredAndSwap(Node *p, Node *&fp) noexcept
Find predecessor and swap for deletion.
Node * search(const Key &key) const noexcept
Search for a key.
GenTdRbTreeRk(const GenTdRbTreeRk &)=delete
NodeType< Key > Node
Node * getRoot() const noexcept
std::pair< long, Node * > position(const Key &key) const noexcept
Find position of a key.
Node * remove_pos(size_t i)
Remove node at position i.
static Node * rotate_to_left_rk(Node *p, Node *pp) noexcept
Rotate to left with counter update.
const Compare & get_compare() const noexcept
static Node * gotoRightAndColorRed(Node *fp, Node *&ffp) noexcept
Descend to right child for deletion, ensuring red.
Node headParent
Sentinel grandparent node.
void restoreRedCondition(Node *p, Node *&fp, Node *ffp, Node *fffp) noexcept
Restore red-black property after color flip.
static void flipColors(Node *p) noexcept
Flip colors with counter preservation.
Node *& getRoot() noexcept
Get root pointer.
bool less(const Key &a, const Key &b) const noexcept
Returns true if a < b according to comparator.
static size_t updateCountRec(Node *p) noexcept
Recursively update counts in subtree - O(n)
static void updateCountsFromStack(Node **stack, size_t len) noexcept
Update counts for nodes in stack (bottom-up) - O(log n) After rotations, nodes may have moved but the...
static constexpr size_t PATH_STACK_CAPACITY
void colorRootAsRed() noexcept
Color root red if safe.
Node * insert(Node *p) noexcept
Insert a node.
Node headNode
Sentinel header node (parent of root)
static Node * rotate_to_right_rk(Node *p, Node *pp) noexcept
Rotate to right with counter update.
GenTdRbTreeRk & operator=(GenTdRbTreeRk &&other) noexcept
Move assignment.
GenTdRbTreeRk() noexcept
Default constructor.
size_t size() const noexcept
Get number of nodes O(1)
void split_pos(size_t pos, GenTdRbTreeRk &t1, GenTdRbTreeRk &t2) noexcept
Split tree by position.
void reset() noexcept
Reset tree (does not free nodes)
Compare & get_compare() noexcept
Get comparator.
Node * remove(const Key &key) noexcept
Remove node with given key.
Node * search_or_insert(Node *p) noexcept
Search or insert.
Compare cmp
Comparison functor.
static void findSuccAndSwap(Node *p, Node *&fp) noexcept
Find successor and swap for deletion.
Node *& root
Reference to root (right child of head)
Node * searchFlipColorsAndInsert(Node *q) noexcept
Search for insertion point, flipping colors proactively.
static Node * gotoLeftAndColorRed(Node *fp, Node *&ffp) noexcept
Descend to left child for deletion, ensuring red.
Node * head
Pointer to header.
bool equals(const Key &a, const Key &b) const noexcept
Returns true if a == b (neither a < b nor b < a)
void init() noexcept
Initialize header nodes.
GenTdRbTreeRk & operator=(const GenTdRbTreeRk &)=delete
Node * searchFlipColorsAndInsertDup(Node *q) noexcept
Search for insertion point allowing duplicates.
std::pair< long, Node * > find_position(const Key &key) const noexcept
Find position of a key (even if not in tree).
void swap(GenTdRbTreeRk &other) noexcept
Swap with another tree.
bool verify() const noexcept
Verify tree properties.
bool is_empty() const noexcept
Check if empty.
Node * fHead
Pointer to header's parent.
void split_pos_inorder(Node *p, size_t pos, GenTdRbTreeRk &t1, GenTdRbTreeRk &t2, size_t &count) noexcept
virtual ~GenTdRbTreeRk()=default
Node * insert_dup(Node *p) noexcept
Insert a node allowing duplicates.
static void removeAndRendLeafRed(Node *p, Node *fp) noexcept
Remove node, making it a red leaf.
Top-down red-black tree with rank (virtual destructor).
Top-down red-black tree with rank (no virtual destructor).
long inorder_position(Node *r, const typename Node::key_type &key, Node *&p, Compare &cmp) noexcept
Compute the inorder position of a key.
bool check_rank_tree(Node *root) noexcept
Return true if root is a valid extended binary tree.
auto & COUNT(Node *p) noexcept
Return the number of nodes of the tree fron p is root.
Node * select(Node *r, const size_t pos)
Iterative selection of a node according to inorder position.
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.
bool is_red_black_bst_rk(Node *node, Compare &cmp)
Verify that tree rooted at node is a valid red-black BST with counters.
Definition rbNodeRk.H:170
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.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
unsigned char Color
Definition rbNodeRk.H:50
#define COLOR(p)
Definition quadnode.H:58
Red-Black tree node with rank (subtree count).
#define BLACK
Black color constant.
Definition rbNode.H:76
#define RED
Red color constant (newly inserted nodes are red)
Definition rbNode.H:73
Iterator(const GenTdRbTreeRk &t)
#define RLINK(i, n)
#define LLINK(i, n)
gsl_rng * r
Utility functions for binary tree operations.
Extended binary node with subtree count.
Basic binary tree node definitions.
Binary tree operations (split, join, rotate).