一、红黑树的定义
红黑树:红黑树是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。
红黑树和AVL树的区别:
AVL树:严格平衡因子
红黑树:近似平衡因子
平衡因子的调节:
1.每个节点不是红色就是黑色
2.根节点是黑色的
3.如果一个节点是红色的,则它的两个孩子节点是黑色的
(不存在连续的红色节点)
4.对于每个结点,从该结点到其所有后代叶节点的简单路径上,均 包含相同数目的黑色节点
(每条路径都存在相同数量的黑色节点)
5.每个叶子结点都是黑色的(此处的叶子结点指的是空节点)
二、底层代码的实现
enum Colour
{
RED,
BLACK
};
template<class K,class V>
struct RBTreeNode
{
AVLTreeNode<K,V>* _left;
AVLTreeNode<K,V>* _right;
AVLTreeNode<K,V>* _parent;
pair<K,V> _kv;
Colour _col;
RBTreeNode(const pair<K,V>&_kv)
:_left(nullptr)
,_right(nullptr)
,_parent(nullptr)
,_kv(kv)
,_col(RED)
{}};
template<class K,class V>
class RBTree
{
typedef RBTreeNode<K,V>Node;
public:
bool Insert(const pair<K,V>&_kv)
{
if(_root == nullptr)
{
_root = new Node(kv);
_root->_col = BLACK;
return true;
}
Node* parent = nullptr;
Node* cur = _root;
while(cur)
{
if(cur->_kv.first < kv.first)
{
parent = cur;
cur = cur -> _right;
}
else i f(cur->_kv.first > kv.first)
{
parent = cur;
cur = cur -> _left;
}
else
{
return false;
}
}
cur = new Node(kv);
cur->_col = RED; //新增节点给红色if(parent->_kv.first < kv.first)
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
cur->_parent = parent;
//parent 的颜色是黑色,就结束了
while(parent->_col == RED && parent)
{
//关键看叔叔
Node* grandfather = parent->_parent;
if(parent == grandfather->_left)
{
Node* uncle = grandfather->_right;
//叔叔存在且为红,变色即可
if(uncle && uncle->_col == RED)
{
parent ->_col = uncle->_col = BLACK;
grandfather->_col = RED;//继续往上处理
cur = grandfather;
parent = cur->_parent;
}
else //叔叔不存在或者存在且为黑
{
//单旋
if(cur == parent->_left)
{
RotateR(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else
{
RotateL(parent);
RotateR(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
else
{
Node* uncle = grandfather->_left;
if(uncle && uncle->_col == RED)
{
parent ->_col = uncle->_col = BLACK;
grandfather->_col = RED;cur = grandfather;
parent = cur->_parent;}
else //叔叔不存在或者存在且为黑
{
//单旋
if(cur == parent->_right)
{
RotateR(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else
{
RotateR(parent);
RotateL(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
}_root ->_col = BLACK;
return true;
}void RotateR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;parent->_left = subLR;
if(subLR)
subLR->_parent = parent;
subL->_right = parent;Node* ppNode = parent->_parent;
parent->_parent = subL;
if(parent == _root)
{
_root = subL;
_root->_parent = nullptr;
}
else
{
if(ppNode->_left == parent)
{
ppNode->_left = subL;
}
else
{
ppNode->_right = subL;
}subL->_parent = ppNode;
}
}
void RotateL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;parent->_right = subRL;
if(subRL)
subRL->_parent = parent;
subR->_left = parent;
Node* ppNode = parent->_parent;
parent->_parent = subR;
if(parent == _root)
{
_root = subR;
_root->_parent = nullptr;
}
else
{
if(ppNode->_right == parent)
{
ppNode->_right = subR;
}
else
{
ppNode->_left = subR;
}subR->_parent = ppNode;
}
}bool IsBalance()
{
if(_root-> _col == RED)
{
return false;
}
int refnum = 0;
Node* cur = _root;
while(cur)
{
if(cur->_col == BLACK)
{
++refnum;
}
cur = cur->_left;
}return Check(_root , 0,refnum);
}private:
bool Check(Node* root ,int blacknum,const int refnum)
{
if(root == nullptr)
{
if(refnum != blacknum)
{
//存在不相等的黑色节点的数量
return false;
}
return true;
}
if(root->_col == RED && root->_parent->_col == RED)
{
//存在连续的红色节点
return false;
}if(root->_col == BLACK)
{
blacknum++;
}
return Check(root->_left,blacknum,refnum)
&& Check(root->_right,blacknum,refnum);
}Node* _root = nullptr;
size_t _size = 0;
};