1.红黑树的概念
红黑树,是一种二叉搜索树,但在每个节点上增加一个存储位表示结点的颜色,可以是Red或Black,通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出两倍,因而是接近平衡的
2.红黑树的性质
- 每个节点不是红色就是黑色
- 根结点是黑色的
- 如果一个节点是红色的,则它的两个孩子都是黑色的
- 每条路径上的黑色结点数目相同
- 每个叶子结点都是黑色的(这里的叶子结点指的是空节点)
3.红黑树结点的定义
enum Color{RED,BLACK};
template<class T>
struct RBTreeNode {
RBTreeNode(const T&data=T(),Color color= RED)
:_pLeft(nullptr)
,_pRight(nullptr)
,_pParent(nullptr)
,_data(data)
,_color(color)
{}
RBTreeNode<T>* _pLeft;
RBTreeNode<T>* _pRight;
RBTreeNode<T>* _pParent;
Color _color;
T _data;
};
4.红黑树的插入操作
红黑树是在二叉搜索树的基础上加上其平衡限制条件,因此,红黑树的插入可分为两步
(1):按照二叉搜索树的规则插入新节点
bool Insert(const T& data) {
Node*& pRoot = GetRoot();
if (pRoot == nullptr) {
pRoot = new Node(data, BLACK);
pRoot->_pParent = _pHead;
return true;
}
else {
Node* pCur = pRoot;
Node* pParent = nullptr;
while (pCur) {
pParent = pCur;
if (data < pCur->_data) {
pCur = pCur->_pLeft;
}
else if (data > pCur->_data) {
pCur = pCur->_pRight;
}
else {
return false;
}
}
pCur = new Node(data);
if (data < pParent->_data) {
pParent->_pLeft = pCur;
}
else {
pParent->_pRight = pCur;
}
pCur->_pParent = pParent;
(2):检测新节点插入后,红黑树的心智是否遭到破坏
while (pParent != _pHead && pParent->_color == RED) {
Node* grandfather = pParent->_pParent;
if (pParent == grandfather->_pLeft) {
Node* uncle = grandfather->_pRight;
if (uncle && uncle->_color == RED) {
uncle->_color = BLACK;
pParent->_color = BLACK;
grandfather->_color = RED;
pCur = grandfather;
pParent = pCur->_pParent;
}
else {
if (pCur == pParent->_pRight) {
RotateL(pParent);
swap(pCur, pParent);
}
pParent->_color = BLACK;
grandfather->_color = RED;
RotateR(grandfather);
}
}
else {
Node* uncle = grandfather->_pLeft;
if (uncle && uncle->_color == RED) {
uncle->_color = BLACK;
pParent->_color = BLACK;
grandfather->_color = RED;
pCur = grandfather;
pParent = pCur->_pParent;
}
else {
if (pCur == pParent->_pLeft) {
RotateR(pParent);
swap(pParent, pCur);
}
pParent->_color = BLACK;
grandfather->_color = RED;
RotateL(grandfather);
}
}
}
}
5.红黑树的验证
- 检测其是否满足二叉搜索树(中序遍历是否为有序遍历)
Node* _InOrder(Node* pRoot) {
if (pRoot) {
_InOrder(pRoot->_pLeft);
cout << pRoot->_data << " ";
_InOrder(pRoot->_pRight);
}
return pRoot;
}
- 检测其是否满足红黑树的性质
bool IsvalidRBTree() {
Node* pRoot = GetRoot();
if (pRoot == nullptr) {
return true;
}
if (pRoot->_color != BLACK) {
cout << "违反了性质一" << endl;
return false;
}
int blackCount = 0;
Node* pCur = pRoot;
while (pCur) {
if (pCur->_color == BLACK) {
blackCount++;
}
pCur = pCur->_pLeft;
}
size_t pathblack = 0;
return _IsvalidRBTree(pRoot, blackCount, pathblack);
}
private:
bool _IsvalidRBTree(Node* pRoot, size_t blackCount, size_t pathblack) {
if (pRoot == nullptr) {
return true;
}
if (pRoot->_color == BLACK) {
pathblack++;
}
if (nullptr == pRoot->_pLeft && nullptr == pRoot->_pRight) {
if (pathblack != blackCount) {
cout << "违反性质四:每条路径上的黑色结点个数相同" << endl;
return false;
}
}
Node* pParent = pRoot->_pParent;
if (pParent != _pHead && pParent->_color == RED && pRoot->_color == RED) {
cout << "违反性质三:红色结点不能连在一起" << endl;
return false;
}
return _IsvalidRBTree(pRoot->_pLeft,blackCount,pathblack) && _IsvalidRBTree(pRoot->_pRight,blackCount,pathblack);
}
6.红黑树的完整代码
enum Color{RED,BLACK};
template<class T>
struct RBTreeNode {
RBTreeNode(const T&data=T(),Color color= RED)
:_pLeft(nullptr)
,_pRight(nullptr)
,_pParent(nullptr)
,_data(data)
,_color(color)
{}
RBTreeNode<T>* _pLeft;
RBTreeNode<T>* _pRight;
RBTreeNode<T>* _pParent;
Color _color;
T _data;
};
template<class T>
class RBTree {
typedef RBTreeNode<T>Node;
public:
RBTree() {
_pHead = new Node;
_pHead->_pLeft = _pHead;
_pHead->_pRight = _pHead;
}
bool Insert(const T& data) {
Node*& pRoot = GetRoot();
if (pRoot == nullptr) {
pRoot = new Node(data, BLACK);
pRoot->_pParent = _pHead;
return true;
}
else {
Node* pCur = pRoot;
Node* pParent = nullptr;
while (pCur) {
pParent = pCur;
if (data < pCur->_data) {
pCur = pCur->_pLeft;
}
else if (data > pCur->_data) {
pCur = pCur->_pRight;
}
else {
return false;
}
}
pCur = new Node(data);
if (data < pParent->_data) {
pParent->_pLeft = pCur;
}
else {
pParent->_pRight = pCur;
}
pCur->_pParent = pParent;
while (pParent != _pHead && pParent->_color == RED) {
Node* grandfather = pParent->_pParent;
if (pParent == grandfather->_pLeft) {
Node* uncle = grandfather->_pRight;
if (uncle && uncle->_color == RED) {
uncle->_color = BLACK;
pParent->_color = BLACK;
grandfather->_color = RED;
pCur = grandfather;
pParent = pCur->_pParent;
}
else {
if (pCur == pParent->_pRight) {
RotateL(pParent);
swap(pCur, pParent);
}
pParent->_color = BLACK;
grandfather->_color = RED;
RotateR(grandfather);
}
}
else {
Node* uncle = grandfather->_pLeft;
if (uncle && uncle->_color == RED) {
uncle->_color = BLACK;
pParent->_color = BLACK;
grandfather->_color = RED;
pCur = grandfather;
pParent = pCur->_pParent;
}
else {
if (pCur == pParent->_pLeft) {
RotateR(pParent);
swap(pParent, pCur);
}
pParent->_color = BLACK;
grandfather->_color = RED;
RotateL(grandfather);
}
}
}
}
pRoot->_color = BLACK;
_pHead->_pLeft = LeftMost();
_pHead->_pRight = RightMost();
return true;
}
void InOrder() {
_InOrder(GetRoot());
}
Node* LeftMost() {
Node* pRoot = GetRoot();
if (pRoot == nullptr) {
return NULL;
}
Node* pCur = pRoot;
while (pCur->_pLeft) {
pCur = pCur->_pLeft;
}
return pCur;
}
Node* RightMost() {
Node* pRoot = GetRoot();
if (pRoot == nullptr) {
return NULL;
}
Node* pCur = pRoot;
while (pCur->_pRight) {
pCur = pCur->_pRight;
}
return pCur;
}
bool IsvalidRBTree() {
Node* pRoot = GetRoot();
if (pRoot == nullptr) {
return true;
}
if (pRoot->_color != BLACK) {
cout << "违反了性质一" << endl;
return false;
}
int blackCount = 0;
Node* pCur = pRoot;
while (pCur) {
if (pCur->_color == BLACK) {
blackCount++;
}
pCur = pCur->_pLeft;
}
size_t pathblack = 0;
return _IsvalidRBTree(pRoot, blackCount, pathblack);
}
private:
bool _IsvalidRBTree(Node* pRoot, size_t blackCount, size_t pathblack) {
if (pRoot == nullptr) {
return true;
}
if (pRoot->_color == BLACK) {
pathblack++;
}
if (nullptr == pRoot->_pLeft && nullptr == pRoot->_pRight) {
if (pathblack != blackCount) {
cout << "违反性质四:每条路径上的黑色结点个数相同" << endl;
return false;
}
}
Node* pParent = pRoot->_pParent;
if (pParent != _pHead && pParent->_color == RED && pRoot->_color == RED) {
cout << "违反性质三:红色结点不能连在一起" << endl;
return false;
}
return _IsvalidRBTree(pRoot->_pLeft,blackCount,pathblack) && _IsvalidRBTree(pRoot->_pRight,blackCount,pathblack);
}
void RotateL(Node* pParent) {
Node* pSubR = pParent->_pRight;
Node* pSubRL = pSubR->_pLeft;
pParent->_pRight = pSubRL;
if (pSubRL) {
pSubRL->_pParent = pParent;
}
pSubR->_pLeft = pParent;
Node* pPParent = pParent->_pParent;
pParent->_pParent = pSubR;
pSubR->_pParent = pPParent;
if (pPParent == _pHead) {
_pHead->_pParent=pSubR;
}
else {
if (pPParent->_pLeft == pParent) {
pPParent->_pLeft = pSubR;
}
else {
pPParent->_pRight = pSubR;
}
}
}
void RotateR(Node* pParent) {
Node* pSubL = pParent->_pLeft;
Node*pSubLR = pSubL->_pRight;
pParent->_pLeft = pSubLR;
if (pSubLR) {
pSubLR->_pParent = pParent;
}
pSubL->_pRight = pParent;
Node* pPParent = pParent->_pParent;
pParent->_pParent = pSubL;
pSubL->_pParent = pPParent;
if (pPParent == _pHead) {
_pHead->_pParent = pSubL;
}
else {
if (pPParent->_pLeft == pParent) {
pPParent->_pLeft = pSubL;
}
else {
pPParent->_pRight = pSubL;
}
}
}
Node*& GetRoot() {
return _pHead->_pParent;
}
Node* _InOrder(Node* pRoot) {
if (pRoot) {
_InOrder(pRoot->_pLeft);
cout << pRoot->_data << " ";
_InOrder(pRoot->_pRight);
}
return pRoot;
}
private:
Node* _pHead;
};
void TestRBTree() {
int a[] = { 5, 3, 4 ,1, 7, 8, 2, 6, 0, 9 };
RBTree<int>t;
for (auto e : a) {
t.Insert(e);
}
t.InOrder();
cout << endl;
cout << t.LeftMost()->_data << endl;
cout << t.RightMost()->_data << endl;
if (t.IsvalidRBTree()) {
cout << "is RBTree" << endl;
}
else {
cout << "is not RBTree" << endl;
}
}