123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818 |
- #pragma once
- #include <util/generic/utility.h>
- #include <util/generic/yexception.h>
- using TRbTreeColorType = bool;
- #define RBTreeRed false
- #define RBTreeBlack true
- struct TRbTreeNodeBase {
- using TColorType = TRbTreeColorType;
- using TBasePtr = TRbTreeNodeBase*;
- TColorType Color_;
- TBasePtr Parent_;
- TBasePtr Left_;
- TBasePtr Right_;
- size_t Children_;
- inline TRbTreeNodeBase() noexcept {
- ReInitNode();
- }
- inline void ReInitNode() noexcept {
- Color_ = RBTreeBlack;
- Parent_ = nullptr;
- Left_ = nullptr;
- Right_ = nullptr;
- Children_ = 1;
- }
- static TBasePtr MinimumNode(TBasePtr x) {
- while (x->Left_ != nullptr)
- x = x->Left_;
- return x;
- }
- static TBasePtr MaximumNode(TBasePtr x) {
- while (x->Right_ != nullptr)
- x = x->Right_;
- return x;
- }
- static TBasePtr ByIndex(TBasePtr x, size_t index) {
- if (x->Left_ != nullptr) {
- if (index < x->Left_->Children_)
- return ByIndex(x->Left_, index);
- index -= x->Left_->Children_;
- }
- if (0 == index)
- return x;
- if (!x->Right_)
- ythrow yexception() << "index not found";
- return ByIndex(x->Right_, index - 1);
- }
- };
- struct TRbTreeBaseIterator;
- template <class TDummy>
- class TRbGlobal {
- public:
- using TBasePtr = TRbTreeNodeBase*;
- static void Rebalance(TBasePtr x, TBasePtr& root);
- static TBasePtr RebalanceForErase(TBasePtr z, TBasePtr& root, TBasePtr& leftmost, TBasePtr& rightmost);
- static void DecrementChildrenUntilRoot(TBasePtr x, TBasePtr root);
- static void RecalcChildren(TBasePtr x);
- static TBasePtr IncrementNode(TBasePtr);
- static TBasePtr DecrementNode(TBasePtr);
- static void RotateLeft(TBasePtr x, TBasePtr& root);
- static void RotateRight(TBasePtr x, TBasePtr& root);
- };
- using TRbGlobalInst = TRbGlobal<bool>;
- struct TRbTreeBaseIterator {
- using TBasePtr = TRbTreeNodeBase*;
- TBasePtr Node_;
- inline TRbTreeBaseIterator(TBasePtr x = nullptr) noexcept
- : Node_(x)
- {
- }
- };
- template <class TValue, class TTraits>
- struct TRbTreeIterator: public TRbTreeBaseIterator {
- using TReference = typename TTraits::TReference;
- using TPointer = typename TTraits::TPointer;
- using TSelf = TRbTreeIterator<TValue, TTraits>;
- using TBasePtr = TRbTreeNodeBase*;
- inline TRbTreeIterator() noexcept = default;
- template <class T1>
- inline TRbTreeIterator(const T1& x) noexcept
- : TRbTreeBaseIterator(x)
- {
- }
- inline TReference operator*() const noexcept {
- return *static_cast<TValue*>(Node_);
- }
- inline TPointer operator->() const noexcept {
- return static_cast<TValue*>(Node_);
- }
- inline TSelf& operator++() noexcept {
- Node_ = TRbGlobalInst::IncrementNode(Node_);
- return *this;
- }
- inline TSelf operator++(int) noexcept {
- TSelf tmp = *this;
- ++(*this);
- return tmp;
- }
- inline TSelf& operator--() noexcept {
- Node_ = TRbGlobalInst::DecrementNode(Node_);
- return *this;
- }
- inline TSelf operator--(int) noexcept {
- TSelf tmp = *this;
- --(*this);
- return tmp;
- }
- template <class T1>
- inline bool operator==(const T1& rhs) const noexcept {
- return Node_ == rhs.Node_;
- }
- template <class T1>
- inline bool operator!=(const T1& rhs) const noexcept {
- return Node_ != rhs.Node_;
- }
- };
- template <class TValue, class TCmp>
- class TRbTree {
- struct TCmpAdaptor: public TCmp {
- inline TCmpAdaptor() noexcept = default;
- inline TCmpAdaptor(const TCmp& cmp) noexcept
- : TCmp(cmp)
- {
- }
- template <class T1, class T2>
- inline bool operator()(const T1& l, const T2& r) const {
- return TCmp::Compare(l, r);
- }
- };
- struct TNonConstTraits {
- using TReference = TValue&;
- using TPointer = TValue*;
- };
- struct TConstTraits {
- using TReference = const TValue&;
- using TPointer = const TValue*;
- };
- using TNodeBase = TRbTreeNodeBase;
- using TBasePtr = TRbTreeNodeBase*;
- using TColorType = TRbTreeColorType;
- public:
- class TRealNode: public TNodeBase {
- public:
- inline TRealNode()
- : Tree_(nullptr)
- {
- }
- inline ~TRealNode() {
- UnLink();
- }
- inline void UnLink() noexcept {
- if (Tree_) {
- Tree_->EraseImpl(this);
- ReInitNode();
- Tree_ = nullptr;
- }
- }
- inline void SetRbTreeParent(TRbTree* parent) noexcept {
- Tree_ = parent;
- }
- inline TRbTree* ParentTree() const noexcept {
- return Tree_;
- }
- private:
- TRbTree* Tree_;
- };
- using TIterator = TRbTreeIterator<TValue, TNonConstTraits>;
- using TConstIterator = TRbTreeIterator<TValue, TConstTraits>;
- inline TRbTree() noexcept {
- Init();
- }
- inline TRbTree(const TCmp& cmp) noexcept
- : KeyCompare_(cmp)
- {
- Init();
- }
- inline void Init() noexcept {
- Data_.Color_ = RBTreeRed;
- Data_.Parent_ = nullptr;
- Data_.Left_ = &Data_;
- Data_.Right_ = &Data_;
- Data_.Children_ = 0;
- }
- struct TDestroy {
- inline void operator()(TValue& v) const noexcept {
- v.SetRbTreeParent(nullptr);
- v.ReInitNode();
- }
- };
- inline ~TRbTree() {
- ForEachNoOrder(TDestroy());
- }
- inline void Clear() noexcept {
- ForEachNoOrder(TDestroy());
- Init();
- }
- template <class F>
- inline void ForEachNoOrder(const F& f) {
- ForEachNoOrder(Root(), f);
- }
- template <class F>
- inline void ForEachNoOrder(TNodeBase* n, const F& f) {
- if (n && n != &Data_) {
- ForEachNoOrder(n->Left_, f);
- ForEachNoOrder(n->Right_, f);
- f(ValueNode(n));
- }
- }
- inline TIterator Begin() noexcept {
- return LeftMost();
- }
- inline TConstIterator Begin() const noexcept {
- return LeftMost();
- }
- inline TIterator End() noexcept {
- return &this->Data_;
- }
- inline TConstIterator End() const noexcept {
- return const_cast<TBasePtr>(&this->Data_);
- }
- inline bool Empty() const noexcept {
- return this->Begin() == this->End();
- }
- inline explicit operator bool() const noexcept {
- return !this->Empty();
- }
- inline TIterator Insert(TValue* val) {
- return Insert(*val);
- }
- inline TIterator Insert(TValue& val) {
- val.UnLink();
- TBasePtr y = &this->Data_;
- TBasePtr x = Root();
- while (x != nullptr) {
- ++(x->Children_);
- y = x;
- if (KeyCompare_(ValueNode(&val), ValueNode(x))) {
- x = LeftNode(x);
- } else {
- x = RightNode(x);
- }
- }
- return InsertImpl(y, &val, x);
- }
- template <class F>
- inline void ForEach(F& f) {
- TIterator it = Begin();
- while (it != End()) {
- f(*it++);
- }
- }
- inline void Erase(TValue& val) noexcept {
- val.UnLink();
- }
- inline void Erase(TValue* val) noexcept {
- Erase(*val);
- }
- inline void Erase(TIterator pos) noexcept {
- Erase(*pos);
- }
- inline void EraseImpl(TNodeBase* val) noexcept {
- TRbGlobalInst::RebalanceForErase(val, this->Data_.Parent_, this->Data_.Left_, this->Data_.Right_);
- }
- template <class T1>
- inline TValue* Find(const T1& k) const {
- TBasePtr y = nullptr;
- TBasePtr x = Root(); // Current node.
- while (x != nullptr)
- if (!KeyCompare_(ValueNode(x), k))
- y = x, x = LeftNode(x);
- else
- x = RightNode(x);
- if (y) {
- if (KeyCompare_(k, ValueNode(y))) {
- y = nullptr;
- }
- }
- return static_cast<TValue*>(y);
- }
- size_t GetIndex(TBasePtr x) const {
- size_t index = 0;
- if (x->Left_ != nullptr) {
- index += x->Left_->Children_;
- }
- while (x != nullptr && x->Parent_ != nullptr && x->Parent_ != const_cast<TBasePtr>(&this->Data_)) {
- if (x->Parent_->Right_ == x && x->Parent_->Left_ != nullptr) {
- index += x->Parent_->Left_->Children_;
- }
- if (x->Parent_->Right_ == x) {
- index += 1;
- }
- x = x->Parent_;
- }
- return index;
- }
- template <class T1>
- inline TBasePtr LowerBound(const T1& k) const {
- TBasePtr y = const_cast<TBasePtr>(&this->Data_); /* Last node which is not less than k. */
- TBasePtr x = Root(); /* Current node. */
- while (x != nullptr)
- if (!KeyCompare_(ValueNode(x), k))
- y = x, x = LeftNode(x);
- else
- x = RightNode(x);
- return y;
- }
- template <class T1>
- inline TBasePtr UpperBound(const T1& k) const {
- TBasePtr y = const_cast<TBasePtr>(&this->Data_); /* Last node which is greater than k. */
- TBasePtr x = Root(); /* Current node. */
- while (x != nullptr)
- if (KeyCompare_(k, ValueNode(x)))
- y = x, x = LeftNode(x);
- else
- x = RightNode(x);
- return y;
- }
- template <class T1>
- inline size_t LessCount(const T1& k) const {
- auto x = LowerBound(k);
- if (x == const_cast<TBasePtr>(&this->Data_)) {
- if (const auto root = Root()) {
- return root->Children_;
- } else {
- return 0;
- }
- } else {
- return GetIndex(x);
- }
- }
- template <class T1>
- inline size_t NotLessCount(const T1& k) const {
- return Root()->Children_ - LessCount<T1>(k);
- }
- template <class T1>
- inline size_t GreaterCount(const T1& k) const {
- auto x = UpperBound(k);
- if (x == const_cast<TBasePtr>(&this->Data_)) {
- return 0;
- } else {
- return Root()->Children_ - GetIndex(x);
- }
- }
- template <class T1>
- inline size_t NotGreaterCount(const T1& k) const {
- return Root()->Children_ - GreaterCount<T1>(k);
- }
- TValue* ByIndex(size_t index) {
- return static_cast<TValue*>(TRbTreeNodeBase::ByIndex(Root(), index));
- }
- private:
- // CRP 7/10/00 inserted argument on_right, which is another hint (meant to
- // act like on_left and ignore a portion of the if conditions -- specify
- // on_right != nullptr to bypass comparison as false or on_left != nullptr to bypass
- // comparison as true)
- TIterator InsertImpl(TRbTreeNodeBase* parent, TRbTreeNodeBase* val, TRbTreeNodeBase* on_left = nullptr, TRbTreeNodeBase* on_right = nullptr) {
- ValueNode(val).SetRbTreeParent(this);
- TBasePtr new_node = val;
- if (parent == &this->Data_) {
- LeftNode(parent) = new_node;
- // also makes LeftMost() = new_node
- Root() = new_node;
- RightMost() = new_node;
- } else if (on_right == nullptr &&
- // If on_right != nullptr, the remainder fails to false
- (on_left != nullptr ||
- // If on_left != nullptr, the remainder succeeds to true
- KeyCompare_(ValueNode(val), ValueNode(parent))))
- {
- LeftNode(parent) = new_node;
- if (parent == LeftMost())
- // maintain LeftMost() pointing to min node
- LeftMost() = new_node;
- } else {
- RightNode(parent) = new_node;
- if (parent == RightMost())
- // maintain RightMost() pointing to max node
- RightMost() = new_node;
- }
- ParentNode(new_node) = parent;
- TRbGlobalInst::Rebalance(new_node, this->Data_.Parent_);
- return new_node;
- }
- TBasePtr Root() const {
- return this->Data_.Parent_;
- }
- TBasePtr LeftMost() const {
- return this->Data_.Left_;
- }
- TBasePtr RightMost() const {
- return this->Data_.Right_;
- }
- TBasePtr& Root() {
- return this->Data_.Parent_;
- }
- TBasePtr& LeftMost() {
- return this->Data_.Left_;
- }
- TBasePtr& RightMost() {
- return this->Data_.Right_;
- }
- static TBasePtr& LeftNode(TBasePtr x) {
- return x->Left_;
- }
- static TBasePtr& RightNode(TBasePtr x) {
- return x->Right_;
- }
- static TBasePtr& ParentNode(TBasePtr x) {
- return x->Parent_;
- }
- static TValue& ValueNode(TBasePtr x) {
- return *static_cast<TValue*>(x);
- }
- static TBasePtr MinimumNode(TBasePtr x) {
- return TRbTreeNodeBase::MinimumNode(x);
- }
- static TBasePtr MaximumNode(TBasePtr x) {
- return TRbTreeNodeBase::MaximumNode(x);
- }
- private:
- TCmpAdaptor KeyCompare_;
- TNodeBase Data_;
- };
- template <class TValue, class TCmp>
- class TRbTreeItem: public TRbTree<TValue, TCmp>::TRealNode {
- };
- template <class TDummy>
- void TRbGlobal<TDummy>::RotateLeft(TRbTreeNodeBase* x, TRbTreeNodeBase*& root) {
- TRbTreeNodeBase* y = x->Right_;
- x->Right_ = y->Left_;
- if (y->Left_ != nullptr)
- y->Left_->Parent_ = x;
- y->Parent_ = x->Parent_;
- if (x == root)
- root = y;
- else if (x == x->Parent_->Left_)
- x->Parent_->Left_ = y;
- else
- x->Parent_->Right_ = y;
- y->Left_ = x;
- x->Parent_ = y;
- y->Children_ = x->Children_;
- x->Children_ = ((x->Left_) ? x->Left_->Children_ : 0) + ((x->Right_) ? x->Right_->Children_ : 0) + 1;
- }
- template <class TDummy>
- void TRbGlobal<TDummy>::RotateRight(TRbTreeNodeBase* x, TRbTreeNodeBase*& root) {
- TRbTreeNodeBase* y = x->Left_;
- x->Left_ = y->Right_;
- if (y->Right_ != nullptr)
- y->Right_->Parent_ = x;
- y->Parent_ = x->Parent_;
- if (x == root)
- root = y;
- else if (x == x->Parent_->Right_)
- x->Parent_->Right_ = y;
- else
- x->Parent_->Left_ = y;
- y->Right_ = x;
- x->Parent_ = y;
- y->Children_ = x->Children_;
- x->Children_ = ((x->Left_) ? x->Left_->Children_ : 0) + ((x->Right_) ? x->Right_->Children_ : 0) + 1;
- }
- template <class TDummy>
- void TRbGlobal<TDummy>::Rebalance(TRbTreeNodeBase* x, TRbTreeNodeBase*& root) {
- x->Color_ = RBTreeRed;
- while (x != root && x->Parent_->Color_ == RBTreeRed) {
- if (x->Parent_ == x->Parent_->Parent_->Left_) {
- TRbTreeNodeBase* y = x->Parent_->Parent_->Right_;
- if (y && y->Color_ == RBTreeRed) {
- x->Parent_->Color_ = RBTreeBlack;
- y->Color_ = RBTreeBlack;
- x->Parent_->Parent_->Color_ = RBTreeRed;
- x = x->Parent_->Parent_;
- } else {
- if (x == x->Parent_->Right_) {
- x = x->Parent_;
- RotateLeft(x, root);
- }
- x->Parent_->Color_ = RBTreeBlack;
- x->Parent_->Parent_->Color_ = RBTreeRed;
- RotateRight(x->Parent_->Parent_, root);
- }
- } else {
- TRbTreeNodeBase* y = x->Parent_->Parent_->Left_;
- if (y && y->Color_ == RBTreeRed) {
- x->Parent_->Color_ = RBTreeBlack;
- y->Color_ = RBTreeBlack;
- x->Parent_->Parent_->Color_ = RBTreeRed;
- x = x->Parent_->Parent_;
- } else {
- if (x == x->Parent_->Left_) {
- x = x->Parent_;
- RotateRight(x, root);
- }
- x->Parent_->Color_ = RBTreeBlack;
- x->Parent_->Parent_->Color_ = RBTreeRed;
- RotateLeft(x->Parent_->Parent_, root);
- }
- }
- }
- root->Color_ = RBTreeBlack;
- }
- template <class TDummy>
- void TRbGlobal<TDummy>::RecalcChildren(TRbTreeNodeBase* x) {
- x->Children_ = ((x->Left_) ? x->Left_->Children_ : 0) + ((x->Right_) ? x->Right_->Children_ : 0) + 1;
- }
- template <class TDummy>
- void TRbGlobal<TDummy>::DecrementChildrenUntilRoot(TRbTreeNodeBase* x, TRbTreeNodeBase* root) {
- auto* ptr = x;
- --ptr->Children_;
- while (ptr != root) {
- ptr = ptr->Parent_;
- --ptr->Children_;
- }
- }
- template <class TDummy>
- TRbTreeNodeBase* TRbGlobal<TDummy>::RebalanceForErase(TRbTreeNodeBase* z,
- TRbTreeNodeBase*& root,
- TRbTreeNodeBase*& leftmost,
- TRbTreeNodeBase*& rightmost) {
- TRbTreeNodeBase* y = z;
- TRbTreeNodeBase* x;
- TRbTreeNodeBase* x_parent;
- if (y->Left_ == nullptr) // z has at most one non-null child. y == z.
- x = y->Right_; // x might be null.
- else {
- if (y->Right_ == nullptr) // z has exactly one non-null child. y == z.
- x = y->Left_; // x is not null.
- else { // z has two non-null children. Set y to
- y = TRbTreeNodeBase::MinimumNode(y->Right_); // z's successor. x might be null.
- x = y->Right_;
- }
- }
- if (y != z) {
- // relink y in place of z. y is z's successor
- z->Left_->Parent_ = y;
- y->Left_ = z->Left_;
- if (y != z->Right_) {
- x_parent = y->Parent_;
- if (x)
- x->Parent_ = y->Parent_;
- y->Parent_->Left_ = x; // y must be a child of mLeft
- y->Right_ = z->Right_;
- z->Right_->Parent_ = y;
- } else
- x_parent = y;
- if (root == z)
- root = y;
- else if (z->Parent_->Left_ == z)
- z->Parent_->Left_ = y;
- else
- z->Parent_->Right_ = y;
- y->Parent_ = z->Parent_;
- DoSwap(y->Color_, z->Color_);
- RecalcChildren(y);
- if (x_parent != y) {
- --x_parent->Children_;
- }
- if (x_parent != root) {
- DecrementChildrenUntilRoot(x_parent->Parent_, root);
- }
- y = z;
- // y now points to node to be actually deleted
- } else {
- // y == z
- x_parent = y->Parent_;
- if (x)
- x->Parent_ = y->Parent_;
- if (root == z)
- root = x;
- else {
- if (z->Parent_->Left_ == z)
- z->Parent_->Left_ = x;
- else
- z->Parent_->Right_ = x;
- DecrementChildrenUntilRoot(z->Parent_, root); // we lost y
- }
- if (leftmost == z) {
- if (z->Right_ == nullptr) // z->mLeft must be null also
- leftmost = z->Parent_;
- // makes leftmost == _M_header if z == root
- else
- leftmost = TRbTreeNodeBase::MinimumNode(x);
- }
- if (rightmost == z) {
- if (z->Left_ == nullptr) // z->mRight must be null also
- rightmost = z->Parent_;
- // makes rightmost == _M_header if z == root
- else // x == z->mLeft
- rightmost = TRbTreeNodeBase::MaximumNode(x);
- }
- }
- if (y->Color_ != RBTreeRed) {
- while (x != root && (x == nullptr || x->Color_ == RBTreeBlack))
- if (x == x_parent->Left_) {
- TRbTreeNodeBase* w = x_parent->Right_;
- if (w->Color_ == RBTreeRed) {
- w->Color_ = RBTreeBlack;
- x_parent->Color_ = RBTreeRed;
- RotateLeft(x_parent, root);
- w = x_parent->Right_;
- }
- if ((w->Left_ == nullptr ||
- w->Left_->Color_ == RBTreeBlack) &&
- (w->Right_ == nullptr ||
- w->Right_->Color_ == RBTreeBlack))
- {
- w->Color_ = RBTreeRed;
- x = x_parent;
- x_parent = x_parent->Parent_;
- } else {
- if (w->Right_ == nullptr || w->Right_->Color_ == RBTreeBlack) {
- if (w->Left_)
- w->Left_->Color_ = RBTreeBlack;
- w->Color_ = RBTreeRed;
- RotateRight(w, root);
- w = x_parent->Right_;
- }
- w->Color_ = x_parent->Color_;
- x_parent->Color_ = RBTreeBlack;
- if (w->Right_)
- w->Right_->Color_ = RBTreeBlack;
- RotateLeft(x_parent, root);
- break;
- }
- } else {
- // same as above, with mRight <-> mLeft.
- TRbTreeNodeBase* w = x_parent->Left_;
- if (w->Color_ == RBTreeRed) {
- w->Color_ = RBTreeBlack;
- x_parent->Color_ = RBTreeRed;
- RotateRight(x_parent, root);
- w = x_parent->Left_;
- }
- if ((w->Right_ == nullptr ||
- w->Right_->Color_ == RBTreeBlack) &&
- (w->Left_ == nullptr ||
- w->Left_->Color_ == RBTreeBlack))
- {
- w->Color_ = RBTreeRed;
- x = x_parent;
- x_parent = x_parent->Parent_;
- } else {
- if (w->Left_ == nullptr || w->Left_->Color_ == RBTreeBlack) {
- if (w->Right_)
- w->Right_->Color_ = RBTreeBlack;
- w->Color_ = RBTreeRed;
- RotateLeft(w, root);
- w = x_parent->Left_;
- }
- w->Color_ = x_parent->Color_;
- x_parent->Color_ = RBTreeBlack;
- if (w->Left_)
- w->Left_->Color_ = RBTreeBlack;
- RotateRight(x_parent, root);
- break;
- }
- }
- if (x)
- x->Color_ = RBTreeBlack;
- }
- return y;
- }
- template <class TDummy>
- TRbTreeNodeBase* TRbGlobal<TDummy>::DecrementNode(TRbTreeNodeBase* Node_) {
- if (Node_->Color_ == RBTreeRed && Node_->Parent_->Parent_ == Node_)
- Node_ = Node_->Right_;
- else if (Node_->Left_ != nullptr) {
- Node_ = TRbTreeNodeBase::MaximumNode(Node_->Left_);
- } else {
- TBasePtr y = Node_->Parent_;
- while (Node_ == y->Left_) {
- Node_ = y;
- y = y->Parent_;
- }
- Node_ = y;
- }
- return Node_;
- }
- template <class TDummy>
- TRbTreeNodeBase* TRbGlobal<TDummy>::IncrementNode(TRbTreeNodeBase* Node_) {
- if (Node_->Right_ != nullptr) {
- Node_ = TRbTreeNodeBase::MinimumNode(Node_->Right_);
- } else {
- TBasePtr y = Node_->Parent_;
- while (Node_ == y->Right_) {
- Node_ = y;
- y = y->Parent_;
- }
- // check special case: This is necessary if mNode is the
- // _M_head and the tree contains only a single node y. In
- // that case parent, left and right all point to y!
- if (Node_->Right_ != y)
- Node_ = y;
- }
- return Node_;
- }
- #undef RBTreeRed
- #undef RBTreeBlack
|