740 lines
22 KiB
C++
740 lines
22 KiB
C++
|
#pragma once
|
|||
|
|
|||
|
#include <iostream>
|
|||
|
|
|||
|
namespace Lenyiin
|
|||
|
{
|
|||
|
enum Colour
|
|||
|
{
|
|||
|
RED,
|
|||
|
BLACK
|
|||
|
};
|
|||
|
|
|||
|
template <class T>
|
|||
|
struct RBTreeNode
|
|||
|
{
|
|||
|
RBTreeNode<T>* _left; // <20><><EFBFBD>ӽڵ<D3BD>
|
|||
|
RBTreeNode<T>* _right; // <20><><EFBFBD>ӽڵ<D3BD>
|
|||
|
RBTreeNode<T>* _parent; // <20><><EFBFBD>ڵ<EFBFBD>
|
|||
|
|
|||
|
T _data; // <20>ڵ<EFBFBD><DAB5>洢<EFBFBD><E6B4A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Colour _colour; // <20>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB>
|
|||
|
|
|||
|
// <20>ڵ<EFBFBD><DAB5>Ĺ<EFBFBD><C4B9>캯<EFBFBD><ECBAAF><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC>Ϊ<EFBFBD><CEAA>ɫ<EFBFBD>ڵ<EFBFBD>
|
|||
|
RBTreeNode(const T& data)
|
|||
|
: _left(nullptr), _right(nullptr), _parent(nullptr), _data(data), _colour(RED)
|
|||
|
{
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
template <class T, class Ref, class Ptr>
|
|||
|
struct __TreeIterator
|
|||
|
{
|
|||
|
typedef RBTreeNode<T> Node;
|
|||
|
typedef __TreeIterator<T, Ref, Ptr> Self;
|
|||
|
Node* _node; // <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD>Ľڵ<C4BD>
|
|||
|
|
|||
|
// <20><><EFBFBD>캯<EFBFBD><ECBAAF>
|
|||
|
__TreeIterator(Node* node)
|
|||
|
: _node(node)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Ref operator*()
|
|||
|
{
|
|||
|
return _node->_data;
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD>ʳ<EFBFBD>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Ptr operator->()
|
|||
|
{
|
|||
|
return &_node->_data;
|
|||
|
}
|
|||
|
|
|||
|
// ǰ<>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Self& operator++()
|
|||
|
{
|
|||
|
// 1. <20><><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD>Ϊ<EFBFBD><CEAA>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
|||
|
if (_node->_right)
|
|||
|
{
|
|||
|
Node* subLeft = _node->_right;
|
|||
|
while (subLeft->_left)
|
|||
|
{
|
|||
|
subLeft = subLeft->_left;
|
|||
|
}
|
|||
|
_node = subLeft;
|
|||
|
}
|
|||
|
// 2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>, <20><>ʾ _node <20><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>, <20><>һ<EFBFBD><D2BB><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5>, <20><><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><D2BA><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǹ<EFBFBD><C7B8><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
else
|
|||
|
{
|
|||
|
Node* cur = _node;
|
|||
|
Node* parent = cur->_parent;
|
|||
|
while (parent && cur == parent->_right)
|
|||
|
{
|
|||
|
cur = parent;
|
|||
|
parent = cur->_parent;
|
|||
|
}
|
|||
|
_node = parent;
|
|||
|
}
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Self operator++(int)
|
|||
|
{
|
|||
|
Node* tmp = _node;
|
|||
|
++(*this);
|
|||
|
return Self(tmp);
|
|||
|
}
|
|||
|
|
|||
|
// ǰ<>õݼ<C3B5><DDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Self& operator--()
|
|||
|
{
|
|||
|
// 1. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҽڵ<D2BD>
|
|||
|
if (_node->_left)
|
|||
|
{
|
|||
|
Node* subRight = _node->left;
|
|||
|
while (subRight->_right)
|
|||
|
{
|
|||
|
subRight = subRight->_right;
|
|||
|
}
|
|||
|
_node = subRight;
|
|||
|
}
|
|||
|
// 2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>, <20><>ʾ _node <20><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>, <20><>һ<EFBFBD><D2BB><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5>, <20><><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><D2BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5>Ǹ<EFBFBD><C7B8><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
else
|
|||
|
{
|
|||
|
Node* cur = _node;
|
|||
|
Node* parent = cur->_parent;
|
|||
|
while (parent && cur == parent->_left)
|
|||
|
{
|
|||
|
cur = parent;
|
|||
|
parent = cur->_parent;
|
|||
|
}
|
|||
|
_node = parent;
|
|||
|
}
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD>õݼ<C3B5><DDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Self operator--(int)
|
|||
|
{
|
|||
|
Node* tmp = _node;
|
|||
|
--(*this);
|
|||
|
return Self(tmp);
|
|||
|
}
|
|||
|
|
|||
|
bool operator!=(const Self& n)
|
|||
|
{
|
|||
|
return _node != n._node;
|
|||
|
}
|
|||
|
|
|||
|
bool operator==(const Self& n)
|
|||
|
{
|
|||
|
return _node == n._node;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
template <class K, class T, class KOfT>
|
|||
|
class RBTree
|
|||
|
{
|
|||
|
private:
|
|||
|
typedef RBTreeNode<T> Node;
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
void RotateL(Node* parent)
|
|||
|
{
|
|||
|
Node* ppNode = parent->_parent;
|
|||
|
Node* subR = parent->_right;
|
|||
|
Node* subRL = subR->_left;
|
|||
|
|
|||
|
parent->_right = subRL;
|
|||
|
if (subRL)
|
|||
|
{
|
|||
|
subRL->_parent = parent;
|
|||
|
}
|
|||
|
subR->_left = parent;
|
|||
|
parent->_parent = subR;
|
|||
|
|
|||
|
// 1. ԭ<><D4AD> parent <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD>, <20><><EFBFBD><EFBFBD> subR <20>Ǹ<EFBFBD>
|
|||
|
if (_root == parent)
|
|||
|
{
|
|||
|
_root = subR;
|
|||
|
subR->_parent = nullptr;
|
|||
|
}
|
|||
|
// 2. parent Ϊ<><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>, <20>ı<EFBFBD><C4B1><EFBFBD><EFBFBD>ӹ<EFBFBD>ϵ, <20><>ô subR Ҫ<><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
|||
|
else
|
|||
|
{
|
|||
|
if (ppNode->_left == parent)
|
|||
|
{
|
|||
|
ppNode->_left = subR;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ppNode->_right = subR;
|
|||
|
}
|
|||
|
subR->_parent = ppNode;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// <20>ҵ<EFBFBD><D2B5><EFBFBD>
|
|||
|
void RotateR(Node* parent)
|
|||
|
{
|
|||
|
Node* ppNode = parent->_parent;
|
|||
|
Node* subL = parent->_left;
|
|||
|
Node* subLR = subL->_right;
|
|||
|
|
|||
|
parent->_left = subLR;
|
|||
|
if (subLR)
|
|||
|
{
|
|||
|
subLR->_parent = parent;
|
|||
|
}
|
|||
|
subL->_right = parent;
|
|||
|
parent->_parent = subL;
|
|||
|
|
|||
|
if (_root == parent)
|
|||
|
{
|
|||
|
_root = subL;
|
|||
|
subL->_parent = nullptr;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (ppNode->_left == parent)
|
|||
|
{
|
|||
|
ppNode->_left = subL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ppNode->_right = subL;
|
|||
|
}
|
|||
|
subL->_parent = ppNode;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
void DeleteTree(Node* root)
|
|||
|
{
|
|||
|
if (root == nullptr)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// <20>ݹ<EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
DeleteTree(root->_left);
|
|||
|
// <20>ݹ<EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
DeleteTree(root->_right);
|
|||
|
|
|||
|
// ɾ<><C9BE><EFBFBD><EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD>
|
|||
|
delete root;
|
|||
|
}
|
|||
|
|
|||
|
public:
|
|||
|
typedef __TreeIterator<T, T&, T*> iterator;
|
|||
|
typedef __TreeIterator<T, const T&, const T*> const_iterator;
|
|||
|
|
|||
|
iterator begin()
|
|||
|
{
|
|||
|
Node* cur = _root;
|
|||
|
while (cur && cur->_left)
|
|||
|
{
|
|||
|
cur = cur->_left;
|
|||
|
}
|
|||
|
return iterator(cur);
|
|||
|
}
|
|||
|
|
|||
|
iterator end()
|
|||
|
{
|
|||
|
return iterator(nullptr);
|
|||
|
}
|
|||
|
|
|||
|
const_iterator begin() const
|
|||
|
{
|
|||
|
Node* cur = _root;
|
|||
|
while (cur && cur->_left)
|
|||
|
{
|
|||
|
cur = cur->_left;
|
|||
|
}
|
|||
|
return const_iterator(cur);
|
|||
|
}
|
|||
|
|
|||
|
const_iterator end() const
|
|||
|
{
|
|||
|
return const_iterator(nullptr);
|
|||
|
}
|
|||
|
|
|||
|
RBTree(Node* root = nullptr)
|
|||
|
: _root(root)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
~RBTree()
|
|||
|
{
|
|||
|
DeleteTree(_root);
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD>
|
|||
|
// 1. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڡ<EFBFBD>
|
|||
|
// 2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD>ڵ㣬<DAB5><E3A3AC><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
// 3. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD>ڵ㣬<DAB5><E3A3AC><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>游<EFBFBD><E6B8B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>Ϊ<EFBFBD><CEAA>ɫ<EFBFBD><C9AB><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
// a. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>죬<EFBFBD>Ѹ<EFBFBD><D1B8><EFBFBD><D7BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3>游<EFBFBD><E6B8B8><EFBFBD>죬<EFBFBD><ECA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
// b. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD>߲<EFBFBD><DFB2><EFBFBD><EFBFBD>ڡ<EFBFBD><DAA1><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD> or ˫<><CBAB><EFBFBD><EFBFBD>+ <20><>ɫ
|
|||
|
std::pair<iterator, bool> Insert(const T& data)
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><D0B2><EFBFBD>
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>գ<EFBFBD><D5A3>½ڵ<C2BD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>ڵ<EFBFBD>
|
|||
|
if (_root == nullptr)
|
|||
|
{
|
|||
|
_root = new Node(data);
|
|||
|
_root->_colour = BLACK; // <20><><EFBFBD>ڵ<EFBFBD><DAB5>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>
|
|||
|
return std::make_pair(iterator(_root), true);
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD>ʱʹ<CAB1>ñȽ<C3B1><C8BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƚϼ<C8BD><CFBC>Ĵ<EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD>֧<EFBFBD>ֲ<EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
KOfT koft;
|
|||
|
Node* parent = nullptr;
|
|||
|
Node* cur = _root;
|
|||
|
while (cur)
|
|||
|
{
|
|||
|
if (koft(cur->_data) > koft(data))
|
|||
|
{
|
|||
|
parent = cur;
|
|||
|
cur = cur->_left;
|
|||
|
}
|
|||
|
else if (koft(cur->_data) < koft(data))
|
|||
|
{
|
|||
|
parent = cur;
|
|||
|
cur = cur->_right;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч, <20><><EFBFBD><EFBFBD> false, <20><><EFBFBD>ҷ<EFBFBD><D2B7>ظü<D8B8><C3BC>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
return std::make_pair(iterator(cur), false);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// <20>ҵ<EFBFBD>λ<EFBFBD><CEBB>, <20><><EFBFBD>ݸ<EFBFBD><DDB8>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½ڵ<C2BD>
|
|||
|
cur = new Node(data);
|
|||
|
Node* newnode = cur;
|
|||
|
if (koft(parent->_data) > koft(cur->_data))
|
|||
|
{
|
|||
|
parent->_left = cur;
|
|||
|
cur->_parent = parent;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
parent->_right = cur;
|
|||
|
cur->_parent = parent;
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><DEB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
InsertFixUp(parent, cur);
|
|||
|
|
|||
|
return std::make_pair(iterator(newnode), true);
|
|||
|
}
|
|||
|
|
|||
|
void InsertFixUp(Node* parent, Node* cur)
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ
|
|||
|
// <20>½<EFBFBD><C2BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB>Ǻڵ<C7BA>? <09><>ɫ
|
|||
|
// 1. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڡ<EFBFBD>
|
|||
|
// 2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD>ڵ<EFBFBD>, <20><><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
// 3. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD>ڵ<EFBFBD>, <20><><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>, <20><><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>游<EFBFBD><E6B8B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>Ϊ<EFBFBD><CEAA>ɫ<EFBFBD><C9AB><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
// a. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>, <20>Ѹ<EFBFBD><D1B8><EFBFBD><D7BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20>游<EFBFBD><E6B8B8><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
// b. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>, <20><><EFBFBD>߲<EFBFBD><DFB2><EFBFBD><EFBFBD>ڡ<EFBFBD><DAA1><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD> or ˫<><CBAB><EFBFBD><EFBFBD>+ <20><>ɫ
|
|||
|
while (parent && parent->_colour == RED)
|
|||
|
{
|
|||
|
// <20>ؼ<EFBFBD><D8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Node* grandfather = parent->_parent;
|
|||
|
// <20><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>游<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӽڵ<D3BD>
|
|||
|
if (grandfather->_left == parent)
|
|||
|
{
|
|||
|
Node* uncle = grandfather->_right;
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD>1: uncle <20><><EFBFBD><EFBFBD>, <20><>Ϊ<EFBFBD><CEAA>
|
|||
|
if (uncle && uncle->_colour == RED)
|
|||
|
{
|
|||
|
parent->_colour = uncle->_colour = BLACK;
|
|||
|
grandfather->_colour = RED;
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD>
|
|||
|
cur = grandfather;
|
|||
|
parent = cur->_parent;
|
|||
|
}
|
|||
|
// <20><><EFBFBD><EFBFBD> 2 or <20><><EFBFBD><EFBFBD> 3 : uncle <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> or uncle <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>
|
|||
|
else
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD> 3 : ˫<><CBAB> -> <20>䵥<EFBFBD><E4B5A5>
|
|||
|
if (cur == parent->_right)
|
|||
|
{
|
|||
|
RotateL(parent);
|
|||
|
std::swap(parent, cur);
|
|||
|
}
|
|||
|
|
|||
|
// <20>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (ps: <20>п<EFBFBD><D0BF><EFBFBD><EFBFBD>ǵ<EFBFBD><C7B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
|||
|
RotateR(grandfather);
|
|||
|
grandfather->_colour = RED;
|
|||
|
parent->_colour = BLACK;
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
// <20><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>游<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӽڵ<D3BD>
|
|||
|
else
|
|||
|
{
|
|||
|
Node* uncle = grandfather->_left;
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD>1: uncle <20><><EFBFBD><EFBFBD>, <20><>Ϊ<EFBFBD><CEAA>
|
|||
|
if (uncle && uncle->_colour == RED)
|
|||
|
{
|
|||
|
parent->_colour = uncle->_colour = BLACK;
|
|||
|
grandfather->_colour = RED;
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD>
|
|||
|
cur = grandfather;
|
|||
|
parent = cur->_parent;
|
|||
|
}
|
|||
|
// <20><><EFBFBD><EFBFBD> 2 or <20><><EFBFBD><EFBFBD> 3 : uncle <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> or uncle <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>
|
|||
|
else
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD> 3 : ˫<><CBAB> -> <20>䵥<EFBFBD><E4B5A5>
|
|||
|
if (cur == parent->_left)
|
|||
|
{
|
|||
|
RotateR(parent);
|
|||
|
std::swap(parent, cur);
|
|||
|
}
|
|||
|
|
|||
|
// <20>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (ps: <20>п<EFBFBD><D0BF><EFBFBD><EFBFBD>ǵ<EFBFBD><C7B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
|||
|
RotateL(grandfather);
|
|||
|
grandfather->_colour = RED;
|
|||
|
parent->_colour = BLACK;
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// <20><>֤<EFBFBD><D6A4><EFBFBD>ڵ<EFBFBD>Ϊ<EFBFBD><CEAA>
|
|||
|
_root->_colour = BLACK;
|
|||
|
}
|
|||
|
|
|||
|
// ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
bool Erase(const K& key)
|
|||
|
{
|
|||
|
Node* nodeToDelete = _root;
|
|||
|
KOfT koft;
|
|||
|
|
|||
|
// 1. Ѱ<><D1B0>Ҫɾ<D2AA><C9BE><EFBFBD>Ľڵ<C4BD>
|
|||
|
while (nodeToDelete)
|
|||
|
{
|
|||
|
if (koft(nodeToDelete->_data) > key)
|
|||
|
{
|
|||
|
nodeToDelete = nodeToDelete->_left;
|
|||
|
}
|
|||
|
else if (koft(nodeToDelete->_data) < key)
|
|||
|
{
|
|||
|
nodeToDelete = nodeToDelete->_right;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
break; // <20>ҵ<EFBFBD><D2B5><EFBFBD>Ҫɾ<D2AA><C9BE><EFBFBD>Ľڵ<C4BD>
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// <20>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ֱ<>ӷ<EFBFBD><D3B7><EFBFBD> false
|
|||
|
if (nodeToDelete == nullptr)
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// ִ<><D6B4>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Node* parent, * child;
|
|||
|
// <20><><EFBFBD><EFBFBD>ԭ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Colour originalColour = nodeToDelete->_colour;
|
|||
|
|
|||
|
// 2. <20><><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD>ڵ<EFBFBD><DAB5>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (nodeToDelete->_left == nullptr)
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD> 1<><31>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>ӽڵ<D3BD>
|
|||
|
child = nodeToDelete->_right;
|
|||
|
parent = nodeToDelete->_parent;
|
|||
|
Transplant(nodeToDelete, nodeToDelete->_right);
|
|||
|
}
|
|||
|
else if (nodeToDelete->_right == nullptr)
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD> 2<><32>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>ӽڵ<D3BD>
|
|||
|
child = nodeToDelete->_left;
|
|||
|
parent = nodeToDelete->_parent;
|
|||
|
Transplant(nodeToDelete, nodeToDelete->_left);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD> 3<><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӽڵ<D3BD>
|
|||
|
// <20>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD>С<EFBFBD>ڵ㣨<DAB5><E3A3A8><EFBFBD>̽ڵ㣩
|
|||
|
Node* successor = Minimum(nodeToDelete->_right);
|
|||
|
originalColour = successor->_colour;
|
|||
|
child = successor->_right;
|
|||
|
if (successor->_parent == nodeToDelete)
|
|||
|
{
|
|||
|
parent = successor;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// <20><><EFBFBD>̽ڵ<CCBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӽڵ㣬<DAB5><E3A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӽڵ<D3BD><DAB5>滻<EFBFBD><E6BBBB>
|
|||
|
Transplant(successor, successor->_right);
|
|||
|
successor->_right = nodeToDelete->_right;
|
|||
|
successor->_right->_parent = successor;
|
|||
|
parent = successor->_parent;
|
|||
|
}
|
|||
|
// <20>ú<EFBFBD><C3BA>̽ڵ<CCBD><DAB5>滻ɾ<E6BBBB><C9BE><EFBFBD>ڵ<EFBFBD>
|
|||
|
Transplant(nodeToDelete, successor);
|
|||
|
successor->_left = nodeToDelete->_left;
|
|||
|
successor->_left->_parent = successor;
|
|||
|
successor->_colour = nodeToDelete->_colour; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>
|
|||
|
}
|
|||
|
|
|||
|
// ɾ<><C9BE><EFBFBD>ڵ<EFBFBD>
|
|||
|
delete nodeToDelete;
|
|||
|
|
|||
|
// 3. <20><EFBFBD><DEB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
// <20><><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD>Ľڵ<C4BD><DAB5>Ǻ<EFBFBD>ɫ, <20><>Ҫ<EFBFBD><D2AA><EFBFBD>е<EFBFBD><D0B5><EFBFBD>
|
|||
|
if (originalColour == BLACK)
|
|||
|
{
|
|||
|
EraseFixUp(child, parent);
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
Node* Minimum(Node* node)
|
|||
|
{
|
|||
|
while (node->_left != nullptr)
|
|||
|
{
|
|||
|
node = node->_left; // һֱ<D2BB><D6B1><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
|||
|
}
|
|||
|
return node;
|
|||
|
}
|
|||
|
|
|||
|
void Transplant(Node* u, Node* v)
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD>u<EFBFBD>Ǹ<EFBFBD><C7B8>ڵ㣬v<E3A3AC><76>Ϊ<EFBFBD>µĸ<C2B5><C4B8>ڵ<EFBFBD>
|
|||
|
if (u->_parent == nullptr)
|
|||
|
{
|
|||
|
_root = v;
|
|||
|
}
|
|||
|
// u<><75><EFBFBD><EFBFBD><EFBFBD>ӽڵ㣬<DAB5><E3A3AC>v<EFBFBD>滻<EFBFBD><E6BBBB>
|
|||
|
else if (u == u->_parent->_left)
|
|||
|
{
|
|||
|
u->_parent->_left = v;
|
|||
|
}
|
|||
|
// u<><75><EFBFBD><EFBFBD><EFBFBD>ӽڵ㣬<DAB5><E3A3AC>v<EFBFBD>滻<EFBFBD><E6BBBB>
|
|||
|
else
|
|||
|
{
|
|||
|
u->_parent->_right = v;
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD>v<EFBFBD><76>u<EFBFBD>ĸ<EFBFBD><C4B8>ڵ<EFBFBD>
|
|||
|
if (v != nullptr)
|
|||
|
{
|
|||
|
v->_parent = u->_parent;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void EraseFixUp(Node* child, Node* parent)
|
|||
|
{
|
|||
|
while (child != _root && (child == nullptr || child->_colour == BLACK))
|
|||
|
{
|
|||
|
if (child == parent->_left)
|
|||
|
{
|
|||
|
Node* brother = parent->_right;
|
|||
|
// <20><><EFBFBD><EFBFBD>1: child <20><><EFBFBD>ֵܽڵ<DCBD> brother <20>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>
|
|||
|
if (brother->_colour == RED)
|
|||
|
{
|
|||
|
brother->_colour = BLACK;
|
|||
|
parent->_colour = RED;
|
|||
|
RotateL(parent);
|
|||
|
brother = parent->_right;
|
|||
|
}
|
|||
|
// <20><><EFBFBD><EFBFBD>2: child <20><><EFBFBD>ֵܽڵ<DCBD> brother <20>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>, <20><> brother <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ㶼<DAB5>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>
|
|||
|
if ((brother->_left == nullptr || brother->_left->_colour == BLACK) &&
|
|||
|
(brother->_right == nullptr || brother->_right->_colour == BLACK))
|
|||
|
{
|
|||
|
brother->_colour = RED;
|
|||
|
child = parent;
|
|||
|
parent = child->_parent;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD>3: brother <20>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>, <20><><EFBFBD><EFBFBD> brother <20><><EFBFBD><EFBFBD><EFBFBD>ӽڵ<D3BD><DAB5>Ǻ<EFBFBD>ɫ, <20><><EFBFBD>ӽڵ<D3BD><DAB5>Ǻ<EFBFBD>ɫ
|
|||
|
if (brother->_right == nullptr || brother->_right->_colour == BLACK)
|
|||
|
{
|
|||
|
if (brother->_left)
|
|||
|
{
|
|||
|
brother->_left->_colour = BLACK;
|
|||
|
}
|
|||
|
brother->_colour = RED;
|
|||
|
RotateR(brother);
|
|||
|
brother = parent->_right;
|
|||
|
}
|
|||
|
// <20><><EFBFBD><EFBFBD>4: brother <20>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>, <20><><EFBFBD><EFBFBD> brother <20><><EFBFBD><EFBFBD><EFBFBD>ӽڵ<D3BD><DAB5>Ǻ<EFBFBD>ɫ
|
|||
|
if (brother)
|
|||
|
{
|
|||
|
brother->_colour = parent->_colour;
|
|||
|
parent->_colour = BLACK;
|
|||
|
if (brother->_right)
|
|||
|
{
|
|||
|
brother->_right->_colour = BLACK;
|
|||
|
}
|
|||
|
RotateL(parent);
|
|||
|
}
|
|||
|
child = _root;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Node* brother = parent->_left;
|
|||
|
// <20><><EFBFBD><EFBFBD>1: child <20><><EFBFBD>ֵܽڵ<DCBD> brother <20>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>
|
|||
|
if (brother->_colour == RED)
|
|||
|
{
|
|||
|
brother->_colour = BLACK;
|
|||
|
parent->_colour = RED;
|
|||
|
RotateR(parent);
|
|||
|
brother = parent->_left;
|
|||
|
}
|
|||
|
// <20><><EFBFBD><EFBFBD>2: child <20><><EFBFBD>ֵܽڵ<DCBD> parent <20>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>, <20><> brother <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ㶼<DAB5>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>
|
|||
|
if ((brother->_left == nullptr || brother->_left->_colour == BLACK) &&
|
|||
|
(brother->_right == nullptr || brother->_right->_colour == BLACK))
|
|||
|
{
|
|||
|
brother->_colour = RED;
|
|||
|
child = parent;
|
|||
|
parent = child->_parent;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD>3: brother <20>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>, <20><><EFBFBD><EFBFBD> brother <20><><EFBFBD><EFBFBD><EFBFBD>ӽڵ<D3BD><DAB5>Ǻ<EFBFBD>ɫ, <20><><EFBFBD>ӽڵ<D3BD><DAB5>Ǻ<EFBFBD>ɫ
|
|||
|
if (brother->_left == nullptr || brother->_left->_colour == BLACK)
|
|||
|
{
|
|||
|
if (brother->_right)
|
|||
|
{
|
|||
|
brother->_right->_colour = BLACK;
|
|||
|
}
|
|||
|
brother->_colour = RED;
|
|||
|
RotateL(brother);
|
|||
|
brother = parent->_left;
|
|||
|
}
|
|||
|
// <20><><EFBFBD><EFBFBD>4: brother <20>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>, <20><><EFBFBD><EFBFBD> brother <20><><EFBFBD><EFBFBD><EFBFBD>ӽڵ<D3BD><DAB5>Ǻ<EFBFBD>ɫ
|
|||
|
if (brother)
|
|||
|
{
|
|||
|
brother->_colour = parent->_colour;
|
|||
|
parent->_colour = BLACK;
|
|||
|
if (brother->_left)
|
|||
|
{
|
|||
|
brother->_left->_colour = BLACK;
|
|||
|
}
|
|||
|
RotateR(parent);
|
|||
|
}
|
|||
|
child = _root;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (child)
|
|||
|
{
|
|||
|
child->_colour = BLACK;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD>ҽڵ<D2BD>
|
|||
|
iterator& Find(const K& key)
|
|||
|
{
|
|||
|
KOfT koft;
|
|||
|
Node* cur = _root;
|
|||
|
while (cur)
|
|||
|
{
|
|||
|
if (koft(cur->_data) > key)
|
|||
|
{
|
|||
|
cur = cur->_left;
|
|||
|
}
|
|||
|
else if (koft(cur->_data) < key)
|
|||
|
{
|
|||
|
cur = cur->_right;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return iterator(cur);
|
|||
|
}
|
|||
|
}
|
|||
|
return iterator(nullptr);
|
|||
|
}
|
|||
|
|
|||
|
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7>Ǻ<EFBFBD><C7BA><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
bool IsRBTree()
|
|||
|
{
|
|||
|
Node* root = _root;
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD>Ҳ<EFBFBD>Ǻ<EFBFBD><C7BA><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (root == nullptr)
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
// 1. <20>жϸ<D0B6><CFB8>Ƿ<EFBFBD><C7B7>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB>
|
|||
|
if (root->_colour != BLACK)
|
|||
|
{
|
|||
|
std::cout << "<EFBFBD><EFBFBD><EFBFBD>ڵ㲻<EFBFBD>Ǻ<EFBFBD>ɫ" << std::endl;
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>·<EFBFBD><C2B7><EFBFBD>Ϻ<EFBFBD>ɫ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
size_t blackCount = 0;
|
|||
|
Node* cur = _root;
|
|||
|
while (cur)
|
|||
|
{
|
|||
|
if (cur->_colour == BLACK)
|
|||
|
{
|
|||
|
blackCount++;
|
|||
|
}
|
|||
|
cur = cur->_left;
|
|||
|
}
|
|||
|
|
|||
|
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, k <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼·<C2BC><C2B7><EFBFBD>к<EFBFBD>ɫ<EFBFBD>ڵ<EFBFBD><DAB5>ĸ<EFBFBD><C4B8><EFBFBD>
|
|||
|
size_t k = 0;
|
|||
|
return _IsRBTree(_root, k, blackCount);
|
|||
|
}
|
|||
|
|
|||
|
bool _IsRBTree(Node* root, size_t k, size_t blackCount)
|
|||
|
{
|
|||
|
// <20>ߵ<EFBFBD> nullptr ֮<><D6AE>, <20>ж<EFBFBD> k <20><> blackCount <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (root == nullptr)
|
|||
|
{
|
|||
|
// <20><><EFBFBD>պ<EFBFBD>ɫ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (blackCount != k)
|
|||
|
{
|
|||
|
std::cout << "Υ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ÿ<><C3BF>·<EFBFBD><C2B7><EFBFBD>к<EFBFBD>ɫ<EFBFBD>ڵ<EFBFBD><DAB5>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" << std::endl;
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
// ͳ<>ƺ<EFBFBD>ɫ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (root->_colour == BLACK)
|
|||
|
{
|
|||
|
k++;
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD>ǰ<E2B5B1>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>丸<EFBFBD>ڵ<D7BD><DAB5>Ƿ<EFBFBD><C7B7><EFBFBD>Ϊ<EFBFBD><CEAA>ɫ
|
|||
|
Node* parent = root->_parent;
|
|||
|
if (parent && parent->_colour == RED && root->_colour == RED)
|
|||
|
{
|
|||
|
std::cout << "Υ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20><>ɫ<EFBFBD>ڵ<EFBFBD><DAB5>ĺ<EFBFBD><C4BA>ӱ<EFBFBD><D3B1><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ" << std::endl;
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
return _IsRBTree(root->_left, k, blackCount) && _IsRBTree(root->_right, k, blackCount);
|
|||
|
}
|
|||
|
|
|||
|
private:
|
|||
|
Node* _root;
|
|||
|
};
|
|||
|
}
|