diff --git a/table/RedBlackTreeTable/include/RedBlackTreeTable.h b/table/RedBlackTreeTable/include/RedBlackTreeTable.h index fc7d393..2a3b013 100644 --- a/table/RedBlackTreeTable/include/RedBlackTreeTable.h +++ b/table/RedBlackTreeTable/include/RedBlackTreeTable.h @@ -24,10 +24,22 @@ class RedBlackTreeTable : public TreeTable { template struct SRBNode : TreeTable::template SNode { Color color; - SRBNode* pParent = nullptr; - SRBNode* pLeft = nullptr; - SRBNode* pRight = nullptr; + SRBNode* pRBParent = nullptr; + SRBNode* pRBLeft = nullptr; + SRBNode* pRBRight = nullptr; SRBNode(Key key, Value value) : TreeTable::template SNode(key, value) {} + void SetParent(SRBNode* pParent) { + pRBParent = pParent; + this->pParent = pParent; + } + void SetLeft(SRBNode* pLeft) { + pRBLeft= pLeft; + this->pLeft= pLeft; + } + void SetRight(SRBNode* pRight) { + pRBRight = pRight; + this->pRight= pRight; + } }; @@ -79,13 +91,13 @@ class RedBlackTreeTable : public TreeTable { /// Левый поворот вокруг узла. /// /// Узел, вокруг которого происходит поворот. - void LeftRotate(TreeTable::template SNode* node); + void LeftRotate(SRBNode* node); /// /// Правый поворот вокруг узла. /// /// Узел, вокруг которого происходит поворот. - void RightRotate(TreeTable::template SNode* node); + void RightRotate(SRBNode* node); #pragma endregion }; diff --git a/table/RedBlackTreeTable/src/RedBlackTreeTable.hpp b/table/RedBlackTreeTable/src/RedBlackTreeTable.hpp index 45fa769..4d08566 100644 --- a/table/RedBlackTreeTable/src/RedBlackTreeTable.hpp +++ b/table/RedBlackTreeTable/src/RedBlackTreeTable.hpp @@ -20,16 +20,18 @@ void RedBlackTreeTable::Insert(Key key, Value value) else { current = current->pRight; } } - new_Node->pParent = static_cast*>(parent); + new_Node->SetParent(static_cast*>(parent)); // новый узел или как левый, или правый потомок в зависимости от значения ключа + + auto rbParent = static_cast*>(parent); if (key < parent->key) { - parent->pLeft = new_Node; - parent->pLeft->pParent = parent; + rbParent->SetLeft(new_Node); + rbParent->pRBLeft->SetParent(rbParent); } else { - parent->pRight = new_Node; - parent->pRight->pParent = parent; + rbParent->SetRight(new_Node); + rbParent->pRBRight->SetParent(rbParent); } } BalanceInsertion(new_Node); @@ -59,47 +61,47 @@ void RedBlackTreeTable::Delete(Key key) template void RedBlackTreeTable::BalanceInsertion(SRBNode* node) { - while (node != this->pRoot && node->pParent->color == RED) { + while (node != this->pRoot && node->pRBParent->color == RED) { // Если новый вставленный узел является левым потомком - if (node->pParent == node->pParent->pParent->pLeft) { - SRBNode* uncle = node->pParent->pParent->pRight; + if (node->pRBParent == node->pRBParent->pRBParent->pRBLeft) { + SRBNode* uncle = node->pRBParent->pRBParent->pRBRight; // Случай 1: дядя узла красный if (uncle && uncle->color == RED) { - node->pParent->color = BLACK; + node->pRBParent->color = BLACK; uncle->color = BLACK; - node->pParent->pParent->color = RED; - node = node->pParent->pParent; + node->pRBParent->pRBParent->color = RED; + node = node->pRBParent->pRBParent; } else { // Случай 2: в этом случае дядя узла является черным, и узел находится справа от родителя, то есть он является правым потомком (и последним) - if (node == node->pParent->pRight) { - node = node->pParent; + if (node == node->pRBParent->pRBRight) { + node = node->pRBParent; LeftRotate(node); } // Случай 3: когда дядя черный, а узел является левым потомком, выполняется правило красно-черного дерева, что оба ребенка красного узла должны быть черными - node->pParent->color = BLACK; - node->pParent->pParent->color = RED; - RightRotate(node->pParent->pParent); + node->pRBParent->color = BLACK; + node->pRBParent->pRBParent->color = RED; + RightRotate(node->pRBParent->pRBParent); } } else { - SRBNode* uncle = node->pParent->pParent->pLeft; + SRBNode* uncle = node->pRBParent->pRBParent->pRBLeft; if (uncle && uncle->color == RED) { - node->pParent->color = BLACK; + node->pRBParent->color = BLACK; uncle->color = BLACK; - node->pParent->pParent->color = RED; - node = node->pParent->pParent; + node->pRBParent->pRBParent->color = RED; + node = node->pRBParent->pRBParent; } else { - if (node == node->pParent->pLeft) { - node = node->pParent; + if (node == node->pRBParent->pLeft) { + node = node->pRBParent; RightRotate(node); } - node->pParent->color = BLACK; - node->pParent->pParent->color = RED; - LeftRotate(node->pParent->pParent); + node->pRBParent->color = BLACK; + node->pRBParent->pRBParent->color = RED; + LeftRotate(node->pRBParent->pRBParent); } } } @@ -110,68 +112,68 @@ void RedBlackTreeTable::BalanceDeletion(SRBNode* node) { while (node != this->pRoot && (node == nullptr || node->color == BLACK)) { if (node == node->pParent->pLeft) { - SRBNode* brother = node->pParent->pRight; + SRBNode* brother = node->pRBParent->pRBRight; if (brother->color == RED) { // Случай 1: брат - узла красный brother->color = BLACK; - node->pParent->color = RED; - LeftRotate(node->pParent); - brother = node->pParent->pRight; + node->pRBParent->color = RED; + LeftRotate(node->pRBParent); + brother = node->pRBParent->pRBRight; } - if ((brother->pLeft == nullptr || brother->pLeft->color == BLACK) && - (brother->pRight == nullptr || brother->pRight->color == BLACK)) { + if ((brother->pRBLeft == nullptr || brother->pRBLeft->color == BLACK) && + (brother->pRBRight == nullptr || brother->pRBRight->color == BLACK)) { // Случай 2: оба ребенка брата черные brother->color = RED; - node = node->pParent; + node = node->pRBParent; } else { - if (brother->pRight == nullptr || brother->pRight->color == BLACK) { + if (brother->pRBRight == nullptr || brother->pRBRight->color == BLACK) { // Случай 3: правый ребенок брата черный - brother->pLeft->color = BLACK; + brother->pRBLeft->color = BLACK; brother->color = RED; RightRotate(brother); - brother = node->pParent->pRight; + brother = node->pRBParent->pRBRight; } // Случай 4: правый ребенок брата красный - brother->color = node->pParent->color; - node->pParent->color = BLACK; - brother->pRight->color = BLACK; - LeftRotate(node->pParent); + brother->color = node->pRBParent->color; + node->pRBParent->color = BLACK; + brother->pRBRight->color = BLACK; + LeftRotate(node->pRBParent); node = static_cast*>(this->pRoot); } } else { - SRBNode* brother = node->pParent->pLeft; + SRBNode* brother = node->pRBParent->pRBLeft; if (brother->color == RED) { brother->color = BLACK; - node->pParent->color = RED; - RightRotate(node->pParent); - brother = node->pParent->pLeft; + node->pRBParent->color = RED; + RightRotate(node->pRBParent); + brother = node->pRBParent->pRBLeft; } - if ((brother->pRight == nullptr || brother->pRight->color == BLACK) && - (brother->pLeft == nullptr || brother->pLeft->color == BLACK)) { + if ((brother->pRBRight == nullptr || brother->pRBRight->color == BLACK) && + (brother->pRBLeft == nullptr || brother->pRBLeft->color == BLACK)) { brother->color = RED; - node = node->pParent; + node = node->pRBParent; } else { - if (brother->pLeft == nullptr || brother->pLeft->color == BLACK) { + if (brother->pRBLeft == nullptr || brother->pRBLeft->color == BLACK) { // Случай 3: левый ребенок брата черный - brother->pRight->color = BLACK; + brother->pRBRight->color = BLACK; brother->color = RED; LeftRotate(brother); - brother = node->pParent->pLeft; + brother = node->pRBParent->pRBLeft; } // Случай 4: левый ребенок брата красный - brother->color = node->pParent->color; - node->pParent->color = BLACK; - brother->pLeft->color = BLACK; - RightRotate(node->pParent); + brother->color = node->pRBParent->color; + node->pRBParent->color = BLACK; + brother->pRBLeft->color = BLACK; + RightRotate(node->pRBParent); node = static_cast*>(this->pRoot); } } @@ -184,41 +186,41 @@ void RedBlackTreeTable::BalanceDeletion(SRBNode* node) } template -void RedBlackTreeTable::LeftRotate(TreeTable::template SNode* node) +void RedBlackTreeTable::LeftRotate(SRBNode* node) { // Левый поворот вокруг узла - auto rightChild = node->pRight; - node->pRight = rightChild->pLeft; + auto rightChild = node->pRBRight; + node->SetRight(rightChild->pRBLeft); - if (rightChild->pLeft != nullptr) { rightChild->pLeft->pParent = node; } + if (rightChild->pRBLeft != nullptr) { rightChild->pRBLeft->SetParent(node); } - rightChild->pParent = node->pParent; + rightChild->SetParent(node->pRBParent); - if (node->pParent == nullptr) { this->pRoot = rightChild; } - else if (node == node->pParent->pLeft) { node->pParent->pLeft = rightChild; } - else { node->pParent->pRight = rightChild; } + if (node->pRBParent == nullptr) { this->pRoot = rightChild; } + else if (node == node->pRBParent->pRBLeft) { node->pRBParent->SetLeft(rightChild); } + else { node->pRBParent->SetRight(rightChild); } - rightChild->pLeft = node; - node->pParent = rightChild; + rightChild->SetLeft(node); + node->SetParent(rightChild); } template -void RedBlackTreeTable::RightRotate(TreeTable::template SNode* node) +void RedBlackTreeTable::RightRotate(SRBNode* node) { // Правый поворот вокруг узла - auto leftChild = node->pLeft; - node->pLeft = leftChild->pRight; + auto leftChild = node->pRBLeft; + node->SetLeft(leftChild->pRBRight); - if (leftChild->pRight != nullptr) { leftChild->pRight->pParent = node; } + if (leftChild->pRBRight != nullptr) { leftChild->pRBRight->SetParent(node); } - leftChild->pParent = node->pParent; + leftChild->SetParent(node->pRBParent); - if (node->pParent == nullptr) { this->pRoot = leftChild; } - else if (node == node->pParent->pRight) { node->pParent->pRight = leftChild; } - else { node->pParent->pLeft = leftChild; } + if (node->pRBParent == nullptr) { this->pRoot = leftChild; } + else if (node == node->pRBParent->pRBRight) { node->pRBParent->SetRight(leftChild); } + else { node->pRBParent->SetLeft(leftChild); } - leftChild->pRight = node; - node->pParent = leftChild; + leftChild->pRBRight = node; + node->pRBParent = leftChild; } diff --git a/table/TreeTable/src/TreeTable.hpp b/table/TreeTable/src/TreeTable.hpp index b6090a1..08990b5 100644 --- a/table/TreeTable/src/TreeTable.hpp +++ b/table/TreeTable/src/TreeTable.hpp @@ -19,10 +19,10 @@ bool TreeTable::IsFull() const noexcept template size_t TreeTable::Reset(void) noexcept { - this->position = 0; this->pActiveNode = this->pRoot; while (this->pActiveNode && this->pActiveNode->pLeft != nullptr) { this->pActiveNode = this->pActiveNode->pLeft; } while (this->pActiveNode->key == Key()) this->GoNext(); + this->position = 0; return 0; } @@ -35,6 +35,7 @@ bool TreeTable::IsTabEnded(void) const noexcept template size_t TreeTable::GoNext(void) noexcept { + if (this->position == this->length - 1) { return ++this->position; } if (this->pActiveNode == nullptr) { return 0; } if (this->pActiveNode->pRight != nullptr) { @@ -86,7 +87,22 @@ typename TreeTable::template SNode* TreeTablepRight; } } - return nullptr; + + auto tmpActiveNode = this->pActiveNode; + auto tmpPosition = this->position; + + currentNode = nullptr; + for (this->Reset(); !this->IsTabEnded(); this->GoNext()) { + if (this->pActiveNode->key == key) { + currentNode = this->pActiveNode; + break; + } + } + + this->pActiveNode = tmpActiveNode; + this->position = tmpPosition; + + return currentNode; }