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 if (steps < 0){
659 this->operator-=(-steps);
660 } else {
661 for (integer i = 0; i < steps; ++i) {
662 this->next();
663 }
664 }
665}
666
667template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
669{
670 if (steps < 0){
671 this->operator+=(-steps);
672 } else {
673 for (integer i = 0; i < steps; ++i) {
674 this->prev();
675 }
676 }
677}
678
679template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
681{
682 if (!this->isValid()) {
683 throw outOfBoundError();
684 }
685
686 return this->cur_->getVal();
687}
688
689template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
691{
692 if (!this->isValid()) {
693 throw outOfBoundError();
694 }
695
696 return this->cur_->getVal();
697}
698
699template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
704
705
706template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
709 if (!this->root_) {
710 return nullptr;
711 }
712
713 RBNode* copied_root =
714 this->createNode(this->root_->getKey(), this->root_->getValue(), this->root_->getColor());
715 queue<RBNode*> src = {this->root_};
716 queue<RBNode*> tar = {copied_root};
717 while (!src.empty()){
718 RBNode* src_cur = src.head();
719 RBNode* tar_cur = tar.head();
720 RBNode* src_child;
721 RBNode* tar_child;
722 if (src_cur->getPLeft()){
723 src_child = src_cur->getPLeft();
724 tar_child = this->createNode(src_child->getKey(), src_child->getValue(), src_child->getColor());
725 RBNode::connect(tar_cur, tar_child, true);
726 src.push(src_child);
727 tar.push(tar_child);
728 }
729 if (src_cur->getPRight()){
730 src_child = src_cur->getPRight();
731 tar_child = this->createNode(src_child->getKey(), src_child->getValue(), src_child->getColor());
732 RBNode::connect(tar_cur, tar_child, false);
733 src.push(src_child);
734 tar.push(tar_child);
735 }
736 src.pop();
737 tar.pop();
738 }
739 return copied_root;
740}
741
742template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
745 if (!cur)
746 return nullptr;
747
748 if (cur->getPLeft()) {
749 cur = cur->getPLeft();
750 while (cur->getPRight()) {
751 cur = cur->getPRight();
752 }
753 return cur;
754 }
755
756 RBNode* parent = cur->getPParent();
757 while (parent && cur == parent->getPLeft()) {
758 cur = parent;
759 parent = parent->getPParent();
760 }
761 return parent;
762}
763
764template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
767 if (!cur)
768 return nullptr;
769
770 if (cur->getPRight()) {
771 cur = cur->getPRight();
772 while (cur->getPLeft()) {
773 cur = cur->getPLeft();
774 }
775 return cur;
776 }
777
778 RBNode* parent = cur->getPParent();
779 while (parent && cur == parent->getPRight()) {
780 cur = parent;
781 parent = parent->getPParent();
782 }
783 return parent;
784}
785
786template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
789{
790 if (!root_) return nullptr;
791
792 RBNode* node = root_;
793 while (node->getPLeft()) {
794 node = node->getPLeft();
795 }
796 return node;
797}
798
799template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
802{
803 if (!this->root_) {
804 return nullptr;
805 }
806
807 RBNode* cur = this->root_;
808 while (cur->getPRight()) {
809 cur = cur->getPRight();
810 }
811 return cur;
812}
813
814template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
817{
818 auto moved_src = this->createNode(std::move(*src));
819 moved_src->setColor(tar->getColor());
820 if (RBNode* tar_parent = tar->getPParent()) {
821 RBNode::connect(tar_parent, moved_src, tar_parent->getPLeft() == tar);
822 } else {
823 this->root_ = moved_src;
824 }
825 RBNode::connect(moved_src, tar->getPLeft(), true);
826 RBNode::connect(moved_src, tar->getPRight(), false);
827 this->destroyNode(tar);
828 return src;
829}
830
831template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
834 color color, RBNode* parent,
835 RBNode* left, RBNode* right) const {
836 auto node = this->rebind_alloc.allocate(1);
837 this->rebind_alloc.construct(node, key, value, color, parent, left, right);
838 return node;
839}
840
841template <typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
844{
845 auto node = this->rebind_alloc.allocate(1);
846 this->rebind_alloc.construct(node, std::move(other_node));
847 return node;
848}
849
850template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
852 this->rebind_alloc.destroy(node);
853 this->rebind_alloc.deallocate(node, 1);
854}
855
856template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
858 if (!cur){
859 return false;
860 }
861 return this->highPriority(cur->getKey(), other);
862}
863
864template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
866 if (!other){
867 return true;
868 }
869 return this->compare_(key, other->getKey());
870}
871
872template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
875 RBNode* child_left = cur;
876 RBNode* child_root = child_left->getPRight();
877 RBNode* child_left_child = child_root->getPLeft();
878 RBNode* child_right = child_root->getPRight();
879 RBNode::connect(nullptr, child_root, true);
880 RBNode::connect(child_root, child_left, true);
881 RBNode::connect(child_left, child_left_child, false);
882 RBNode::connect(child_root, child_right, false);
883 return child_root;
884}
885
886template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
889 RBNode* child_right = cur;
890 RBNode* child_root = cur->getPLeft();
891 RBNode* child_right_child = child_root->getPRight();
892 RBNode* child_left = child_root->getPLeft();
893 RBNode::connect(nullptr, child_root, true);
894 RBNode::connect(child_root, child_left, true);
895 RBNode::connect(child_right, child_right_child, true);
896 RBNode::connect(child_root, child_right, false);
897 return child_root;
898}
899
900template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
902 while (cur != this->root_ && cur->getPParent()->getColor() == RED) {
903 RBNode* parent = cur->getPParent();
904 RBNode* grand_parent = parent->getPParent();
905 RBNode* uncle = grand_parent->getPLeft() == parent ? grand_parent->getPRight() : grand_parent->getPLeft();
906 if (!uncle || uncle->getColor() == BLACK) {
907
908 RBNode* rotated_root;
909 if (grand_parent->getPLeft() == uncle) {
910
911 if (parent->getPLeft() == cur) {
912 RBNode::connect(grand_parent, this->rotateRight(parent), false);
913 }
914
915 if (grand_parent == this->root_) {
916 rotated_root = this->rotateLeft(grand_parent);
917 this->root_ = rotated_root;
918 RBNode::connect(nullptr, this->root_, true);
919 }else {
920 RBNode* grand_grand = grand_parent->getPParent();
921 bool is_left = grand_grand->getPLeft() == grand_parent;
922 rotated_root = this->rotateLeft(grand_parent);
923 RBNode::connect(grand_grand, rotated_root, is_left);
924 }
925 rotated_root->setColor(BLACK);
926 rotated_root->getPLeft()->setColor(RED);
927 } else {
928
929 if (parent->getPRight() == cur) {
930 RBNode::connect(grand_parent, this->rotateLeft(parent), true);
931 }
932
933 if (grand_parent == this->root_) {
934 rotated_root = this->rotateRight(grand_parent);
935 this->root_ = rotated_root;
936 RBNode::connect(nullptr, this->root_, true);
937 }else {
938 RBNode* grand_grand = grand_parent->getPParent();
939 bool is_left = grand_grand->getPLeft() == grand_parent;
940 rotated_root = this->rotateRight(grand_parent);
941 RBNode::connect(grand_grand, rotated_root, is_left);
942 }
943 rotated_root->setColor(BLACK);
944 rotated_root->getPRight()->setColor(RED);
945 }
946
947 break;
948 }
949 parent->setColor(BLACK);
950 uncle->setColor(BLACK);
951 grand_parent->setColor(RED);
952
953 cur = grand_parent;
954 }
955
956 this->root_->setColor(BLACK);
957}
958
959template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
961 while (cur != this->root_ && cur->getColor() == BLACK) {
962 RBNode* parent = cur->getPParent();
963 RBNode* brother;
964 RBNode* grand_parent;
965
966 if (parent->getPLeft() == cur) {
967 brother = parent->getPRight(); // R
968
969 if (brother->getColor() == RED) {
970 brother->swapColor(*parent);
971 grand_parent = parent->getPParent();
972 if (grand_parent) {
973 bool is_left = grand_parent->getPLeft() == parent;
974 RBNode::connect(grand_parent, this->rotateLeft(parent), is_left);
975 } else {
976 this->root_ = this->rotateLeft(parent);
977 RBNode::connect(nullptr, this->root_, true);
978 }
979 } else {
980 RBNode* nephew;
981 if (brother->getPRight() && brother->getPRight()->getColor() == RED) { // RR
982 nephew = brother->getPRight();
983 nephew->setColor(brother->getColor());
984 brother->setColor(parent->getColor());
985 parent->setColor(BLACK);
986 grand_parent = parent->getPParent();
987 if (grand_parent) {
988 bool is_left = grand_parent->getPLeft() == parent;
989 RBNode::connect(grand_parent, this->rotateLeft(parent), is_left);
990 } else {
991 this->root_ = this->rotateLeft(parent);
992 RBNode::connect(nullptr, this->root_, true);
993 }
994 break;
995 }
996
997 if (brother->getPLeft() && brother->getPLeft()->getColor() == RED) { // RL
998 nephew = brother->getPLeft();
999 nephew->setColor(parent->getColor());
1000 parent->setColor(BLACK);
1001 RBNode::connect(parent, this->rotateRight(brother), true);
1002 grand_parent = parent->getPParent();
1003 if (grand_parent) {
1004 bool is_left = grand_parent->getPLeft() == parent;
1005 RBNode::connect(grand_parent, this->rotateLeft(parent), is_left);
1006 } else {
1007 this->root_ = this->rotateLeft(parent);
1008 RBNode::connect(nullptr, this->root_, true);
1009 }
1010 break;
1011 }
1012
1013 if ((!brother->getPLeft() && !brother->getPRight()) ||
1014 (brother->getPLeft()->getColor() == BLACK && brother->getPRight()->getColor() == BLACK))
1015 {
1016 if (cur->getColor() == BLACK)
1017 {
1018 brother->setColor(RED);
1019 cur = cur->getPParent();
1020 } else
1021 {
1022 cur->setColor(BLACK);
1023 break;
1024 }
1025 }
1026 }
1027 }else {
1028 brother = parent->getPLeft(); // L
1029
1030 if (brother->getColor() == RED) {
1031 brother->swapColor(*parent);
1032 grand_parent = parent->getPParent();
1033 if (grand_parent) {
1034 bool is_left = grand_parent->getPLeft() == parent;
1035 RBNode::connect(grand_parent, this->rotateRight(parent), is_left);
1036 } else {
1037 this->root_ = this->rotateRight(parent);
1038 RBNode::connect(nullptr, this->root_, true);
1039 }
1040 } else {
1041 RBNode* nephew;
1042 if (brother->getPLeft() && brother->getPLeft()->getColor() == RED) { // LL
1043 nephew = brother->getPLeft();
1044 nephew->setColor(brother->getColor());
1045 brother->setColor(parent->getColor());
1046 parent->setColor(BLACK);
1047 grand_parent = parent->getPParent();
1048 if (grand_parent) {
1049 bool is_left = grand_parent->getPLeft() == parent;
1050 RBNode::connect(grand_parent, this->rotateRight(parent), is_left);
1051 } else {
1052 this->root_ = this->rotateRight(parent);
1053 RBNode::connect(nullptr, this->root_, true);
1054 }
1055 break;
1056 }
1057
1058 if (brother->getPRight() && brother->getPRight()->getColor() == RED) { // LR
1059 nephew = brother->getPRight();
1060 nephew->setColor(parent->getColor());
1061 parent->setColor(BLACK);
1062 RBNode::connect(parent, this->rotateLeft(brother), true);
1063 grand_parent = parent->getPParent();
1064 if (grand_parent) {
1065 bool is_left = grand_parent->getPLeft() == parent;
1066 RBNode::connect(grand_parent, this->rotateRight(parent), is_left);
1067 } else {
1068 this->root_ = this->rotateRight(parent);
1069 RBNode::connect(nullptr, this->root_, true);
1070 }
1071 break;
1072 }
1073
1074 if ((!brother->getPLeft() && !brother->getPRight()) ||
1075 (brother->getPLeft()->getColor() == BLACK && brother->getPRight()->getColor() == BLACK))
1076 {
1077 if (cur->getColor() == BLACK)
1078 {
1079 brother->setColor(RED);
1080 cur = cur->getPParent();
1081 } else
1082 {
1083 cur->setColor(BLACK);
1084 break;
1085 }
1086 }
1087
1088 }
1089 }
1090 }
1091
1092 cur->setColor(BLACK);
1093}
1094
1095template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
1097 if (!this->root_) {
1098 return;
1099 }
1100
1101 queue<RBNode*> queue = {this->root_};
1102 while (!queue.empty()) {
1103 RBNode* node = queue.head();
1104 if (node->getPLeft()) {
1105 queue.push(node->getPLeft());
1106 }
1107 if (node->getPRight()) {
1108 queue.push(node->getPRight());
1109 }
1110 this->destroyNode(queue.pop());
1111 }
1112 this->root_ = nullptr;
1113}
1114
1115template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
1117 : root_(nullptr), size_(0), compare_(std::move(compare)) {}
1118
1119template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
1122 auto cur = this->root_;
1123 while (cur){
1124 if (cur->getKey() == key){
1125 return cur;
1126 }
1127 cur = this->highPriority(key, cur) ? cur->getPLeft() : cur->getPRight();
1128 }
1129 return cur;
1130}
1131
1132template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
1133bool original::RBTree<K_TYPE, V_TYPE, ALLOC, Compare>::modify(const K_TYPE &key, const V_TYPE &value) {
1134 if (auto cur = this->find(key)){
1135 cur->setValue(value);
1136 return true;
1137 }
1138 return false;
1139}
1140
1141template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
1142bool original::RBTree<K_TYPE, V_TYPE, ALLOC, Compare>::insert(const K_TYPE &key, const V_TYPE &value) {
1143 auto** cur = &this->root_;
1144 RBNode* parent = nullptr;
1145 bool is_left = false;
1146
1147 while (*cur) {
1148 if ((*cur)->getKey() == key) {
1149 return false;
1150 }
1151 parent = *cur;
1152 is_left = this->highPriority(key, *cur);
1153 cur = is_left ? &(*cur)->getPLeftRef() : &(*cur)->getPRightRef();
1154 }
1155
1156 RBNode* child = this->createNode(key, value, parent ? RED : BLACK);
1157 if (!parent) {
1158 this->root_ = child;
1159 } else {
1160 RBNode::connect(parent, child, is_left);
1161 }
1162
1163 this->size_ += 1;
1164 this->adjustInsert(child);
1165 return true;
1166}
1167
1168template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
1170 if (!this->root_) {
1171 return false;
1172 }
1173
1174 auto cur = this->find(key);
1175 if (!cur) {
1176 return false;
1177 }
1178
1179 if (cur->getPLeft() && cur->getPRight()) {
1180 RBNode* replace = this->getPrecursorNode(cur) ?
1181 this->getPrecursorNode(cur) : this->getSuccessorNode(cur);
1182 cur = this->replaceNode(replace, cur);
1183 }
1184
1185 RBNode* parent = cur->getPParent();
1186 if (cur->getPLeft() && !cur->getPRight()) {
1187 if (!parent) {
1188 this->root_ = cur->getPLeft();
1189 RBNode::connect(nullptr, this->root_, true);
1190 this->root_->setColor(BLACK);
1191 } else {
1192 bool is_left = parent->getPLeft() == cur;
1193 RBNode::connect(parent, cur->getPLeft(), is_left);
1194 RBNode::connect(nullptr, cur, true);
1195 cur->getPLeft()->setColor(BLACK);
1196 }
1197 } else if (!cur->getPLeft() && cur->getPRight()) {
1198 if (!parent) {
1199 this->root_ = cur->getPRight();
1200 RBNode::connect(nullptr, this->root_, true);
1201 this->root_->setColor(BLACK);
1202 } else {
1203 bool is_left = parent->getPLeft() == cur;
1204 RBNode::connect(parent, cur->getPRight(), is_left);
1205 RBNode::connect(nullptr, cur, true);
1206 cur->getPRight()->setColor(BLACK);
1207 }
1208 } else {
1209 if (!parent) {
1210 this->root_ = nullptr;
1211 } else if (cur->getColor() == BLACK) {
1212 this->adjustErase(cur);
1213 } else {
1214 RBNode::connect(nullptr, cur, true);
1215 }
1216 }
1217
1218 if (cur->getPParent()) {
1219 RBNode::connect(cur->getPParent(), nullptr, cur->getPParent()->getPLeft() == cur);
1220 }
1221 this->destroyNode(cur);
1222 this->size_ -= 1;
1223 return true;
1224}
1225
1226template<typename K_TYPE, typename V_TYPE, typename ALLOC, typename Compare>
1230
1231#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:668
bool hasNext() const
Checks if more elements exist forward.
Definition RBTree.h:632
bool isValid() const
Checks if iterator is valid.
Definition RBTree.h:700
couple< const K_TYPE, V_TYPE > & get()
Gets current element (non-const)
Definition RBTree.h:680
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:1227
bool insert(const K_TYPE &key, const V_TYPE &value)
Inserts new key-value pair.
Definition RBTree.h:1142
typename RBNode::color color
Color type alias.
Definition RBTree.h:203
RBNode * rotateRight(RBNode *cur)
Performs right rotation around a node.
Definition RBTree.h:888
RBTree(Compare compare=Compare{})
Constructs RBTree with given comparison function.
Definition RBTree.h:1116
RBNode * getMaxNode() const
Gets the maximum node in the tree.
Definition RBTree.h:801
bool highPriority(RBNode *cur, RBNode *other) const
Compares priority between two nodes.
Definition RBTree.h:857
static constexpr color BLACK
Definition RBTree.h:204
void destroyTree() noexcept
Destroys entire tree and deallocates all nodes.
Definition RBTree.h:1096
rebind_alloc_node rebind_alloc
Definition RBTree.h:211
RBNode * getSuccessorNode(RBNode *cur) const
Gets successor node (in-order successor)
Definition RBTree.h:766
void adjustErase(RBNode *cur)
Adjusts tree after deletion to maintain RB properties.
Definition RBTree.h:960
bool highPriority(const K_TYPE &key, RBNode *other) const
Compares priority between a key and a node.
Definition RBTree.h:865
RBNode * rotateLeft(RBNode *cur)
Performs left rotation around a node.
Definition RBTree.h:874
RBNode * replaceNode(RBNode *src, RBNode *tar)
Replaces one node with another while maintaining tree structure.
Definition RBTree.h:816
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:833
bool erase(const K_TYPE &key)
Erases node with given key.
Definition RBTree.h:1169
RBNode * treeCopy() const
Creates a deep copy of the tree.
Definition RBTree.h:708
RBNode * createNode(RBNode &&other_node) const
Creates a new node by moving from another node.
Definition RBTree.h:843
RBNode * getPrecursorNode(RBNode *cur) const
Gets precursor node (in-order predecessor)
Definition RBTree.h:744
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:851
RBNode * find(const K_TYPE &key) const
Finds node with given key.
Definition RBTree.h:1121
RBNode * getMinNode() const
Gets the minimum node in the tree.
Definition RBTree.h:788
void adjustInsert(RBNode *cur)
Adjusts tree after insertion to maintain RB properties.
Definition RBTree.h:901
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:1133
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.