ORIGINAL
Loading...
Searching...
No Matches
RBTree.h
Go to the documentation of this file.
1#ifndef RBTREE_H
2#define RBTREE_H
3
4#include "allocator.h"
5#include "comparator.h"
6#include "couple.h"
7#include "queue.h"
8
18
19
20namespace original {
21
36 template<typename K_TYPE,
37 typename V_TYPE,
38 typename ALLOC = allocator<K_TYPE>,
40 class RBTree {
41 protected:
42
51 class RBNode {
52 public:
53
55 enum class color { BLACK, RED };
56
57 private:
59 color color_;
60 RBNode* parent_;
61 RBNode* left_;
62 RBNode* right_;
63 public:
64
74 explicit RBNode(const K_TYPE& key = K_TYPE{}, const V_TYPE& value = V_TYPE{},
75 color color = color::RED, RBNode* parent = nullptr, RBNode* left = nullptr, RBNode* right = nullptr);
76
78 RBNode(const RBNode& other);
79
81 RBNode& operator=(const RBNode& other);
82
84 RBNode(RBNode&& other) noexcept;
85
90 void swapData(RBNode& other) noexcept;
91
96 void swapColor(RBNode& other) noexcept;
97
103
109
114 const K_TYPE& getKey() const;
115
120 const V_TYPE& getValue() const;
121
126 V_TYPE& getValue();
127
132 void setValue(const V_TYPE& value);
133
139
145
150 RBNode* getPLeft() const;
151
157
163
169
174 void setColor(color new_color);
175
180 void setPParent(RBNode* new_parent);
181
186 void setPLeft(RBNode* new_left);
187
192 void setPRight(RBNode* new_right);
193
200 static void connect(RBNode* parent, RBNode* child, bool is_left);
201 };
202
203 using color = typename RBNode::color;
204 static constexpr color BLACK = color::BLACK;
205 static constexpr color RED = color::RED;
206 using rebind_alloc_node = typename ALLOC::template rebind_alloc<RBNode>;
207
208 RBNode* root_;
212
219 {
220 protected:
221 mutable RBTree* tree_;
222 mutable RBNode* cur_;
223
229 explicit Iterator(RBTree* tree = nullptr, RBNode* cur = nullptr);
230
232 Iterator(const Iterator& other);
233
236
237 public:
242 [[nodiscard]] bool hasNext() const;
243
248 [[nodiscard]] bool hasPrev() const;
249
253 void next() const;
254
258 void prev() const;
259
264 void operator+=(integer steps) const;
265
270 void operator-=(integer steps) const;
271
277
283
288 [[nodiscard]] bool isValid() const;
289 };
290
291 friend Iterator;
292
297 RBNode* treeCopy() const;
298
304 RBNode* getPrecursorNode(RBNode* cur) const;
305
311 RBNode* getSuccessorNode(RBNode* cur) const;
312
318 RBNode* getMinNode() const;
319
325 RBNode* getMaxNode() const;
326
334 RBNode* replaceNode(RBNode* src, RBNode* tar);
335
347 RBNode* createNode(const K_TYPE& key = K_TYPE{}, const V_TYPE& value = V_TYPE{},
348 color color = RED, RBNode* parent = nullptr,
349 RBNode* left = nullptr, RBNode* right = nullptr) const;
350
357 RBNode* createNode(RBNode&& other_node) const;
358
364 void destroyNode(RBNode* node) noexcept;
365
373 bool highPriority(RBNode* cur, RBNode* other) const;
374
382 bool highPriority(const K_TYPE& key, RBNode* other) const;
383
390 RBNode* rotateLeft(RBNode* cur);
391
398 RBNode* rotateRight(RBNode* cur);
399
405 void adjustInsert(RBNode* cur);
406
412 void adjustErase(RBNode* cur);
413
418 void destroyTree() noexcept;
419
424 explicit RBTree(Compare compare = Compare{});
425
432 RBNode* find(const K_TYPE& key) const;
433
440 bool modify(const K_TYPE& key, const V_TYPE& value);
441
449 bool insert(const K_TYPE& key, const V_TYPE& value);
450
457 bool erase(const K_TYPE& key);
458
464 };
465
466}
467
468template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
470 const color color, RBNode *parent, RBNode *left, RBNode *right)
471 : data_({key, value}), color_(color), parent_(parent), left_(left), right_(right) {}
472
473template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
477
478template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
481 if (this == &other)
482 return *this;
483
484 this->data_ = other.data_;
485 this->color_ = other.color_;
486 this->parent_ = other.parent_;
487 this->left_ = other.left_;
488 this->right_ = other.right_;
489 return *this;
490}
491
492template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
494 : data_(std::move(other.data_)), color_(other.color_), parent_(nullptr), left_(nullptr), right_(nullptr) {}
495
496
497template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
499 std::swap(this->data_, other.data_);
500}
501
502template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
504 std::swap(this->color_, other.color_);
505}
506
507template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
513
514template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
520
521template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
523 return this->data_.first();
524}
525
526template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
528 return this->data_.second();
529}
530
531template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
533 return this->data_.second();
534}
535
536template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
538 this->data_.template set<1>(value);
539}
540
541template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
546
547template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
552
553template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
558
559template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
564
565template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
571
572template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
578
579template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
581 this->color_ = new_color;
582}
583
584template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
586 this->parent_ = new_parent;
587}
588
589template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
591 this->left_ = new_left;
592}
593
594template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
596 this->right_ = new_right;
597}
598
599template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
601 RBNode* child, bool is_left) {
602 if (parent){
603 is_left ? parent->left_ = child : parent->right_ = child;
604 }
605 if (child){
606 child->parent_ = parent;
607 }
608}
609
610template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
613
614template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
618
619template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
622{
623 if (this == &other)
624 return *this;
625
626 this->tree_ = other.tree_;
627 this->cur_ = other.cur_;
628 return *this;
629}
630
631template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
633{
634 return this->cur_ && this->tree_->getSuccessorNode(this->cur_);
635}
636
637template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
639{
640 return this->cur_ && this->tree_->getPrecursorNode(this->cur_);
641}
642
643template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
645{
646 this->cur_ = this->tree_->getSuccessorNode(this->cur_);
647}
648
649template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
651{
652 this->cur_ = this->tree_->getPrecursorNode(this->cur_);
653}
654
655template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
657{
658 for (integer i = 0; i < steps; ++i) {
659 this->next();
660 }
661}
662
663template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
665{
666 for (integer i = 0; i < steps; ++i) {
667 this->prev();
668 }
669}
670
671template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
673{
674 if (!this->isValid()) {
675 throw outOfBoundError();
676 }
677
678 return this->cur_->getVal();
679}
680
681template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
683{
684 if (!this->isValid()) {
685 throw outOfBoundError();
686 }
687
688 return this->cur_->getVal();
689}
690
691template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
696
697
698template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
701 if (!this->root_) {
702 return nullptr;
703 }
704
705 RBNode* copied_root =
706 this->createNode(this->root_->getKey(), this->root_->getValue(), this->root_->getColor());
707 queue<RBNode*> src = {this->root_};
708 queue<RBNode*> tar = {copied_root};
709 while (!src.empty()){
710 RBNode* src_cur = src.head();
711 RBNode* tar_cur = tar.head();
712 RBNode* src_child;
713 RBNode* tar_child;
714 if (src_cur->getPLeft()){
715 src_child = src_cur->getPLeft();
716 tar_child = this->createNode(src_child->getKey(), src_child->getValue(), src_child->getColor());
717 RBNode::connect(tar_cur, tar_child, true);
718 src.push(src_child);
719 tar.push(tar_child);
720 }
721 if (src_cur->getPRight()){
722 src_child = src_cur->getPRight();
723 tar_child = this->createNode(src_child->getKey(), src_child->getValue(), src_child->getColor());
724 RBNode::connect(tar_cur, tar_child, false);
725 src.push(src_child);
726 tar.push(tar_child);
727 }
728 src.pop();
729 tar.pop();
730 }
731 return copied_root;
732}
733
734template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
737 if (!cur)
738 return nullptr;
739
740 if (cur->getPLeft()) {
741 cur = cur->getPLeft();
742 while (cur->getPRight()) {
743 cur = cur->getPRight();
744 }
745 return cur;
746 }
747
748 RBNode* parent = cur->getPParent();
749 while (parent && cur == parent->getPLeft()) {
750 cur = parent;
751 parent = parent->getPParent();
752 }
753 return parent;
754}
755
756template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
759 if (!cur)
760 return nullptr;
761
762 if (cur->getPRight()) {
763 cur = cur->getPRight();
764 while (cur->getPLeft()) {
765 cur = cur->getPLeft();
766 }
767 return cur;
768 }
769
770 RBNode* parent = cur->getPParent();
771 while (parent && cur == parent->getPRight()) {
772 cur = parent;
773 parent = parent->getPParent();
774 }
775 return parent;
776}
777
778template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
781{
782 if (!root_) return nullptr;
783
784 RBNode* node = root_;
785 while (node->getPLeft()) {
786 node = node->getPLeft();
787 }
788 return node;
789}
790
791template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
794{
795 if (!this->root_) {
796 return nullptr;
797 }
798
799 RBNode* cur = this->root_;
800 while (cur->getPRight()) {
801 cur = cur->getPRight();
802 }
803 return cur;
804}
805
806template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
809{
810 auto moved_src = this->createNode(std::move(*src));
811 moved_src->setColor(tar->getColor());
812 if (RBNode* tar_parent = tar->getPParent()) {
813 RBNode::connect(tar_parent, moved_src, tar_parent->getPLeft() == tar);
814 } else {
815 this->root_ = moved_src;
816 }
817 RBNode::connect(moved_src, tar->getPLeft(), true);
818 RBNode::connect(moved_src, tar->getPRight(), false);
819 this->destroyNode(tar);
820 return src;
821}
822
823template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
826 color color, RBNode* parent,
827 RBNode* left, RBNode* right) const {
828 auto node = this->rebind_alloc.allocate(1);
829 this->rebind_alloc.construct(node, key, value, color, parent, left, right);
830 return node;
831}
832
833template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
836{
837 auto node = this->rebind_alloc.allocate(1);
838 this->rebind_alloc.construct(node, std::move(other_node));
839 return node;
840}
841
842template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
844 this->rebind_alloc.destroy(node);
845 this->rebind_alloc.deallocate(node, 1);
846}
847
848template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
850 if (!cur){
851 return false;
852 }
853 return this->highPriority(cur->getKey(), other);
854}
855
856template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
858 if (!other){
859 return true;
860 }
861 return this->compare_(key, other->getKey());
862}
863
864template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
867 RBNode* child_left = cur;
868 RBNode* child_root = child_left->getPRight();
869 RBNode* child_left_child = child_root->getPLeft();
870 RBNode* child_right = child_root->getPRight();
871 RBNode::connect(nullptr, child_root, true);
872 RBNode::connect(child_root, child_left, true);
873 RBNode::connect(child_left, child_left_child, false);
874 RBNode::connect(child_root, child_right, false);
875 return child_root;
876}
877
878template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
881 RBNode* child_right = cur;
882 RBNode* child_root = cur->getPLeft();
883 RBNode* child_right_child = child_root->getPRight();
884 RBNode* child_left = child_root->getPLeft();
885 RBNode::connect(nullptr, child_root, true);
886 RBNode::connect(child_root, child_left, true);
887 RBNode::connect(child_right, child_right_child, true);
888 RBNode::connect(child_root, child_right, false);
889 return child_root;
890}
891
892template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
894 while (cur != this->root_ && cur->getPParent()->getColor() == RED) {
895 RBNode* parent = cur->getPParent();
896 RBNode* grand_parent = parent->getPParent();
897 RBNode* uncle = grand_parent->getPLeft() == parent ? grand_parent->getPRight() : grand_parent->getPLeft();
898 if (!uncle || uncle->getColor() == BLACK) {
899
900 RBNode* rotated_root;
901 if (grand_parent->getPLeft() == uncle) {
902
903 if (parent->getPLeft() == cur) {
904 RBNode::connect(grand_parent, this->rotateRight(parent), false);
905 }
906
907 if (grand_parent == this->root_) {
908 rotated_root = this->rotateLeft(grand_parent);
909 this->root_ = rotated_root;
910 RBNode::connect(nullptr, this->root_, true);
911 }else {
912 RBNode* grand_grand = grand_parent->getPParent();
913 bool is_left = grand_grand->getPLeft() == grand_parent;
914 rotated_root = this->rotateLeft(grand_parent);
915 RBNode::connect(grand_grand, rotated_root, is_left);
916 }
917 rotated_root->setColor(BLACK);
918 rotated_root->getPLeft()->setColor(RED);
919 } else {
920
921 if (parent->getPRight() == cur) {
922 RBNode::connect(grand_parent, this->rotateLeft(parent), true);
923 }
924
925 if (grand_parent == this->root_) {
926 rotated_root = this->rotateRight(grand_parent);
927 this->root_ = rotated_root;
928 RBNode::connect(nullptr, this->root_, true);
929 }else {
930 RBNode* grand_grand = grand_parent->getPParent();
931 bool is_left = grand_grand->getPLeft() == grand_parent;
932 rotated_root = this->rotateRight(grand_parent);
933 RBNode::connect(grand_grand, rotated_root, is_left);
934 }
935 rotated_root->setColor(BLACK);
936 rotated_root->getPRight()->setColor(RED);
937 }
938
939 break;
940 }
941 parent->setColor(BLACK);
942 uncle->setColor(BLACK);
943 grand_parent->setColor(RED);
944
945 cur = grand_parent;
946 }
947
948 this->root_->setColor(BLACK);
949}
950
951template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
953 while (cur != this->root_ && cur->getColor() == BLACK) {
954 RBNode* parent = cur->getPParent();
955 RBNode* brother;
956 RBNode* grand_parent;
957
958 if (parent->getPLeft() == cur) {
959 brother = parent->getPRight(); // R
960
961 if (brother->getColor() == RED) {
962 brother->swapColor(*parent);
963 grand_parent = parent->getPParent();
964 if (grand_parent) {
965 bool is_left = grand_parent->getPLeft() == parent;
966 RBNode::connect(grand_parent, this->rotateLeft(parent), is_left);
967 } else {
968 this->root_ = this->rotateLeft(parent);
969 RBNode::connect(nullptr, this->root_, true);
970 }
971 } else {
972 RBNode* nephew;
973 if (brother->getPRight() && brother->getPRight()->getColor() == RED) { // RR
974 nephew = brother->getPRight();
975 nephew->setColor(brother->getColor());
976 brother->setColor(parent->getColor());
977 parent->setColor(BLACK);
978 grand_parent = parent->getPParent();
979 if (grand_parent) {
980 bool is_left = grand_parent->getPLeft() == parent;
981 RBNode::connect(grand_parent, this->rotateLeft(parent), is_left);
982 } else {
983 this->root_ = this->rotateLeft(parent);
984 RBNode::connect(nullptr, this->root_, true);
985 }
986 break;
987 }
988
989 if (brother->getPLeft() && brother->getPLeft()->getColor() == RED) { // RL
990 nephew = brother->getPLeft();
991 nephew->setColor(parent->getColor());
992 parent->setColor(BLACK);
993 RBNode::connect(parent, this->rotateRight(brother), true);
994 grand_parent = parent->getPParent();
995 if (grand_parent) {
996 bool is_left = grand_parent->getPLeft() == parent;
997 RBNode::connect(grand_parent, this->rotateLeft(parent), is_left);
998 } else {
999 this->root_ = this->rotateLeft(parent);
1000 RBNode::connect(nullptr, this->root_, true);
1001 }
1002 break;
1003 }
1004
1005 if ((!brother->getPLeft() && !brother->getPRight()) ||
1006 (brother->getPLeft()->getColor() == BLACK && brother->getPRight()->getColor() == BLACK))
1007 {
1008 if (cur->getColor() == BLACK)
1009 {
1010 brother->setColor(RED);
1011 cur = cur->getPParent();
1012 } else
1013 {
1014 cur->setColor(BLACK);
1015 break;
1016 }
1017 }
1018 }
1019 }else {
1020 brother = parent->getPLeft(); // L
1021
1022 if (brother->getColor() == RED) {
1023 brother->swapColor(*parent);
1024 grand_parent = parent->getPParent();
1025 if (grand_parent) {
1026 bool is_left = grand_parent->getPLeft() == parent;
1027 RBNode::connect(grand_parent, this->rotateRight(parent), is_left);
1028 } else {
1029 this->root_ = this->rotateRight(parent);
1030 RBNode::connect(nullptr, this->root_, true);
1031 }
1032 } else {
1033 RBNode* nephew;
1034 if (brother->getPLeft() && brother->getPLeft()->getColor() == RED) { // LL
1035 nephew = brother->getPLeft();
1036 nephew->setColor(brother->getColor());
1037 brother->setColor(parent->getColor());
1038 parent->setColor(BLACK);
1039 grand_parent = parent->getPParent();
1040 if (grand_parent) {
1041 bool is_left = grand_parent->getPLeft() == parent;
1042 RBNode::connect(grand_parent, this->rotateRight(parent), is_left);
1043 } else {
1044 this->root_ = this->rotateRight(parent);
1045 RBNode::connect(nullptr, this->root_, true);
1046 }
1047 break;
1048 }
1049
1050 if (brother->getPRight() && brother->getPRight()->getColor() == RED) { // LR
1051 nephew = brother->getPRight();
1052 nephew->setColor(parent->getColor());
1053 parent->setColor(BLACK);
1054 RBNode::connect(parent, this->rotateLeft(brother), true);
1055 grand_parent = parent->getPParent();
1056 if (grand_parent) {
1057 bool is_left = grand_parent->getPLeft() == parent;
1058 RBNode::connect(grand_parent, this->rotateRight(parent), is_left);
1059 } else {
1060 this->root_ = this->rotateRight(parent);
1061 RBNode::connect(nullptr, this->root_, true);
1062 }
1063 break;
1064 }
1065
1066 if ((!brother->getPLeft() && !brother->getPRight()) ||
1067 (brother->getPLeft()->getColor() == BLACK && brother->getPRight()->getColor() == BLACK))
1068 {
1069 if (cur->getColor() == BLACK)
1070 {
1071 brother->setColor(RED);
1072 cur = cur->getPParent();
1073 } else
1074 {
1075 cur->setColor(BLACK);
1076 break;
1077 }
1078 }
1079
1080 }
1081 }
1082 }
1083
1084 cur->setColor(BLACK);
1085}
1086
1087template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
1089 if (!this->root_) {
1090 return;
1091 }
1092
1093 queue<RBNode*> queue = {this->root_};
1094 while (!queue.empty()) {
1095 RBNode* node = queue.head();
1096 if (node->getPLeft()) {
1097 queue.push(node->getPLeft());
1098 }
1099 if (node->getPRight()) {
1100 queue.push(node->getPRight());
1101 }
1102 this->destroyNode(queue.pop());
1103 }
1104 this->root_ = nullptr;
1105}
1106
1107template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
1109 : root_(nullptr), size_(0), compare_(std::move(compare)) {}
1110
1111template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
1114 auto cur = this->root_;
1115 while (cur){
1116 if (cur->getKey() == key){
1117 return cur;
1118 }
1119 cur = this->highPriority(key, cur) ? cur->getPLeft() : cur->getPRight();
1120 }
1121 return cur;
1122}
1123
1124template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
1125bool original::RBTree<K_TYPE, V_TYPE, ALLOC, Compare>::modify(const K_TYPE &key, const V_TYPE &value) {
1126 if (auto cur = this->find(key)){
1127 cur->setValue(value);
1128 return true;
1129 }
1130 return false;
1131}
1132
1133template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
1134bool original::RBTree<K_TYPE, V_TYPE, ALLOC, Compare>::insert(const K_TYPE &key, const V_TYPE &value) {
1135 auto** cur = &this->root_;
1136 RBNode* parent = nullptr;
1137 bool is_left = false;
1138
1139 while (*cur) {
1140 if ((*cur)->getKey() == key) {
1141 return false;
1142 }
1143 parent = *cur;
1144 is_left = this->highPriority(key, *cur);
1145 cur = is_left ? &(*cur)->getPLeftRef() : &(*cur)->getPRightRef();
1146 }
1147
1148 RBNode* child = this->createNode(key, value, parent ? RED : BLACK);
1149 if (!parent) {
1150 this->root_ = child;
1151 } else {
1152 RBNode::connect(parent, child, is_left);
1153 }
1154
1155 this->size_ += 1;
1156 this->adjustInsert(child);
1157 return true;
1158}
1159
1160template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
1162 if (!this->root_) {
1163 return false;
1164 }
1165
1166 auto cur = this->find(key);
1167 if (!cur) {
1168 return false;
1169 }
1170
1171 if (cur->getPLeft() && cur->getPRight()) {
1172 RBNode* replace = this->getPrecursorNode(cur) ?
1173 this->getPrecursorNode(cur) : this->getSuccessorNode(cur);
1174 cur = this->replaceNode(replace, cur);
1175 }
1176
1177 RBNode* parent = cur->getPParent();
1178 if (cur->getPLeft() && !cur->getPRight()) {
1179 if (!parent) {
1180 this->root_ = cur->getPLeft();
1181 RBNode::connect(nullptr, this->root_, true);
1182 this->root_->setColor(BLACK);
1183 } else {
1184 bool is_left = parent->getPLeft() == cur;
1185 RBNode::connect(parent, cur->getPLeft(), is_left);
1186 RBNode::connect(nullptr, cur, true);
1187 cur->getPLeft()->setColor(BLACK);
1188 }
1189 } else if (!cur->getPLeft() && cur->getPRight()) {
1190 if (!parent) {
1191 this->root_ = cur->getPRight();
1192 RBNode::connect(nullptr, this->root_, true);
1193 this->root_->setColor(BLACK);
1194 } else {
1195 bool is_left = parent->getPLeft() == cur;
1196 RBNode::connect(parent, cur->getPRight(), is_left);
1197 RBNode::connect(nullptr, cur, true);
1198 cur->getPRight()->setColor(BLACK);
1199 }
1200 } else {
1201 if (!parent) {
1202 this->root_ = nullptr;
1203 } else if (cur->getColor() == BLACK) {
1204 this->adjustErase(cur);
1205 } else {
1206 RBNode::connect(nullptr, cur, true);
1207 }
1208 }
1209
1210 if (cur->getPParent()) {
1211 RBNode::connect(cur->getPParent(), nullptr, cur->getPParent()->getPLeft() == cur);
1212 }
1213 this->destroyNode(cur);
1214 this->size_ -= 1;
1215 return true;
1216}
1217
1218template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
1222
1223#endif //RBTREE_H
Memory allocation interface and implementations.
Bidirectional iterator for RBTree.
Definition RBTree.h:219
Iterator & operator=(const Iterator &other)
Copy assignment operator.
Definition RBTree.h:621
Iterator(RBTree *tree=nullptr, RBNode *cur=nullptr)
Constructs iterator.
Definition RBTree.h:611
bool hasPrev() const
Checks if more elements exist backward.
Definition RBTree.h:638
void operator-=(integer steps) const
Moves iterator backward by steps.
Definition RBTree.h:664
bool hasNext() const
Checks if more elements exist forward.
Definition RBTree.h:632
bool isValid() const
Checks if iterator is valid.
Definition RBTree.h:692
couple< const K_TYPE, V_TYPE > & get()
Gets current element (non-const)
Definition RBTree.h:672
RBNode * cur_
Current node.
Definition RBTree.h:222
void operator+=(integer steps) const
Advances iterator by steps.
Definition RBTree.h:656
void prev() const
Moves to previous element.
Definition RBTree.h:650
void next() const
Moves to next element.
Definition RBTree.h:644
RBTree * tree_
Owning tree.
Definition RBTree.h:221
Internal node class for Red-Black Tree.
Definition RBTree.h:51
const V_TYPE & getValue() const
Gets value (const)
Definition RBTree.h:527
color
Node color enumeration.
Definition RBTree.h:55
RBNode *& getPRightRef()
Gets right child reference.
Definition RBTree.h:574
RBNode * getPLeft() const
Gets left child.
Definition RBTree.h:555
void setPLeft(RBNode *new_left)
Sets left child.
Definition RBTree.h:590
RBNode & operator=(const RBNode &other)
Copy assignment operator.
Definition RBTree.h:480
void setValue(const V_TYPE &value)
Sets new value.
Definition RBTree.h:537
color getColor() const
Gets node color.
Definition RBTree.h:543
const K_TYPE & getKey() const
Gets key.
Definition RBTree.h:522
void setPRight(RBNode *new_right)
Sets right child.
Definition RBTree.h:595
void swapColor(RBNode &other) noexcept
Swaps color with another node.
Definition RBTree.h:503
void setPParent(RBNode *new_parent)
Sets parent node.
Definition RBTree.h:585
void swapData(RBNode &other) noexcept
Swaps data with another node.
Definition RBTree.h:498
RBNode *& getPLeftRef()
Gets left child reference.
Definition RBTree.h:567
couple< const K_TYPE, V_TYPE > & getVal()
Gets key-value pair (non-const)
Definition RBTree.h:509
RBNode * getPRight() const
Gets right child.
Definition RBTree.h:561
void setColor(color new_color)
Sets node color.
Definition RBTree.h:580
RBNode * getPParent() const
Gets parent node.
Definition RBTree.h:549
static void connect(RBNode *parent, RBNode *child, bool is_left)
Connects parent and child nodes.
Definition RBTree.h:600
RBNode(const K_TYPE &key=K_TYPE{}, const V_TYPE &value=V_TYPE{}, color color=color::RED, RBNode *parent=nullptr, RBNode *left=nullptr, RBNode *right=nullptr)
Constructs a new RBNode.
Definition RBTree.h:469
~RBTree()
Destructor.
Definition RBTree.h:1219
bool insert(const K_TYPE &key, const V_TYPE &value)
Inserts new key-value pair.
Definition RBTree.h:1134
typename RBNode::color color
Color type alias.
Definition RBTree.h:203
RBNode * rotateRight(RBNode *cur)
Performs right rotation around a node.
Definition RBTree.h:880
RBTree(Compare compare=Compare{})
Constructs RBTree with given comparison function.
Definition RBTree.h:1108
RBNode * getMaxNode() const
Gets the maximum node in the tree.
Definition RBTree.h:793
bool highPriority(RBNode *cur, RBNode *other) const
Compares priority between two nodes.
Definition RBTree.h:849
static constexpr color BLACK
Definition RBTree.h:204
void destroyTree() noexcept
Destroys entire tree and deallocates all nodes.
Definition RBTree.h:1088
rebind_alloc_node rebind_alloc
Definition RBTree.h:211
RBNode * getSuccessorNode(RBNode *cur) const
Gets successor node (in-order successor)
Definition RBTree.h:758
void adjustErase(RBNode *cur)
Adjusts tree after deletion to maintain RB properties.
Definition RBTree.h:952
bool highPriority(const K_TYPE &key, RBNode *other) const
Compares priority between a key and a node.
Definition RBTree.h:857
RBNode * rotateLeft(RBNode *cur)
Performs left rotation around a node.
Definition RBTree.h:866
RBNode * replaceNode(RBNode *src, RBNode *tar)
Replaces one node with another while maintaining tree structure.
Definition RBTree.h:808
u_integer size_
Definition RBTree.h:209
RBNode * createNode(const K_TYPE &key=K_TYPE{}, const V_TYPE &value=V_TYPE{}, color color=RED, RBNode *parent=nullptr, RBNode *left=nullptr, RBNode *right=nullptr) const
Creates a new node with given parameters.
Definition RBTree.h:825
bool erase(const K_TYPE &key)
Erases node with given key.
Definition RBTree.h:1161
RBNode * treeCopy() const
Creates a deep copy of the tree.
Definition RBTree.h:700
RBNode * createNode(RBNode &&other_node) const
Creates a new node by moving from another node.
Definition RBTree.h:835
RBNode * getPrecursorNode(RBNode *cur) const
Gets precursor node (in-order predecessor)
Definition RBTree.h:736
typename ALLOC::template rebind_alloc< RBNode > rebind_alloc_node
Definition RBTree.h:206
void destroyNode(RBNode *node) noexcept
Destroys a node and deallocates memory.
Definition RBTree.h:843
RBNode * find(const K_TYPE &key) const
Finds node with given key.
Definition RBTree.h:1113
RBNode * getMinNode() const
Gets the minimum node in the tree.
Definition RBTree.h:780
void adjustInsert(RBNode *cur)
Adjusts tree after insertion to maintain RB properties.
Definition RBTree.h:893
static constexpr color RED
Definition RBTree.h:205
bool modify(const K_TYPE &key, const V_TYPE &value)
Modifies value for existing key.
Definition RBTree.h:1125
Default memory allocator using allocators utilities.
Definition allocator.h:154
bool empty() const
Checks if the container is empty.
Definition container.h:155
Container for two heterogeneous elements.
Definition couple.h:37
F_TYPE & first()
Access first element.
Definition couple.h:323
Comparator for increasing comparison (less than).
Definition comparator.h:63
Exception for container index out-of-range errors.
Definition error.h:84
First-In-First-Out (FIFO) container adapter.
Definition queue.h:35
TYPE head() const
Accesses front element of the queue.
Definition queue.h:195
void push(const TYPE &e)
Inserts element at the back of the queue.
Definition queue.h:181
TYPE pop()
Removes and returns front element from the queue.
Definition queue.h:188
Abstract base class for unique element containers.
Definition set.h:44
Comparator base class and concrete comparator classes.
Combines Comparable and CallbackOf for comparison callbacks.
Definition types.h:92
Generic pair container implementation.
Main namespace for the project Original.
Definition algorithms.h:21
std::uint32_t u_integer
32-bit unsigned integer type for sizes and indexes
Definition config.h:43
std::int64_t integer
64-bit signed integer type for arithmetic operations
Definition config.h:35
Queue container adapter implementation.