为什么会有红黑树呢,其实红黑树就是在AVL树上的优化,由于AVL树使一颗平衡树,为了保持平衡需要多次进行选择。而红黑树减少了旋转的次数,进行了优化,保证最长路径不超过最短路径的2倍。
红黑树的性质
1. 每个结点不是红色就是黑色
2. 根节点是黑色的
3. 如果一个节点是红色的,则它的两个孩子结点是黑色的
4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均 包含相同数目的黑色结点
5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)
开始考虑插入情况
先定义插入节点(cur)的父节点定义为p(parent),p的父节点定义为g (grandpa) ,g的另外一个孩子定义为u(uncle)。
将所有插入的树初始化为红。
几种情况
在这里,只讨论p在g的左边情况,p在g的右边同样的思路。
根据上面分析,只需要对u进行讨论
cur分为新插入的与向上调节赋值的两类
cur也可以在p的右边
什么是上调
当出现情况二和2图的时候,就要上调。
拿情况二举例,2图与之无异。
在调节的过程中,cur可能在p的左边,也可能在p的右边,p可能在g的左边,p也可能在g的右边,这些情况交替出现,需要我们用if调节去判断。
当出现情况一和1图,情况二和2图,通过旋转就可以维持红黑树的性质。下面会讲如何旋转
当我们向上调节,会出现这种情况(这里只讲p在g的左边的情况)
第一幅图的旋转
第二幅图旋转
对于左边的情况总结一下
边界的处理
调节的代码
while (cur!=_node&&parent!=_node)
{
if (parent->_color == BLACK)
{
return true;
}
else // paretn->_color==RED
{
if (parent == parent->_parent->_left) // cur 和 parent位于 g左边的情况
{
RBTreeNode* uncle = parent->_parent->_right;
if (uncle == nullptr && cur == parent->_left) // 开始即结束 直接变形
{
RBTreeNode* Grandp = parent->_parent;
RotateR(parent->_parent);
parent->_color = BLACK;
Grandp->_color = RED;
return true;
}
else if (uncle == nullptr && cur == parent->_right)
{
RBTreeNode* Grandp = parent->_parent;
RotateL(parent);
RotateR(Grandp);
Grandp->_color = RED;
cur->_color = BLACK;
return true;
}
else if (uncle->_color == RED) //向上调 // cur 位于 parent的左边 右边都行
{
parent->_color = BLACK;
uncle->_color = BLACK;
if (parent->_parent != _node)
{
parent->_parent->_color = RED;
}
cur = parent->_parent;
parent = cur->_parent;
}
else if (uncle->_color == BLACK&&cur==parent->_left) // 开始旋转
{
RBTreeNode* Grandp = parent->_parent;
RotateR(parent->_parent);
parent->_color = BLACK;
Grandp->_color = RED;
return true;
}
else if (uncle->_color == BLACK && cur == parent->_right)
{
RBTreeNode* Grandp = parent->_parent;
RotateL(parent);
RotateR(Grandp);
Grandp->_color = RED;
cur->_color = BLACK;
return true;
}
}
else // parent==paretn->_parent->_right
{
RBTreeNode* uncle = parent->_parent->_left;
if (uncle == nullptr && cur == parent->_right)
{
RBTreeNode* Grandp = parent->_parent;
RotateL(parent->_parent);
Grandp->_color = RED;
parent->_color = BLACK;
return true;
}
else if (uncle == nullptr && cur == parent->_left)
{
RBTreeNode* Grandp = parent->_parent;
RotateR(parent);
RotateL(Grandp);
cur->_color = BLACK;
Grandp->_color = RED;
return true;
}
else if (uncle->_color == RED)
{
parent->_color = BLACK;
uncle->_color = BLACK;
if (parent->_parent != _node)
{
parent->_parent->_color = RED;
}
cur = parent->_parent;
parent = cur->_parent;
}
else if (uncle->_color == BLACK && cur == parent->_left)
{
RBTreeNode* Grandp = parent->_parent;
RotateL(parent->_parent);
parent->_color = BLACK;
Grandp->_color = RED;
return true;
}
else if (uncle->_color == BLACK && cur == parent->_right)
{
RBTreeNode* Grandp = parent->_parent;
RotateR(parent);
RotateL(Grandp);
Grandp->_color = RED;
cur->_color = BLACK;
return true;
}
}
}
}
}
完整代码
enum Color
{
RED,
BLACK
};
template<class K, class V>
struct RBTreeNode
{
RBTreeNode* _left;
RBTreeNode* _right;
RBTreeNode* _parent;
K _key;
V _value;
Color _color;
RBTreeNode(const K& key, const V& value)
:_left(nullptr)
, _right(nullptr)
, _parent(nullptr)
, _color(RED)
, _key(key)
, _value(value)
{
}
};
template<class K, class V>
class RBTree
{
typedef RBTreeNode<K, V> RBTreeNode;
public:
RBTree()
:_node(nullptr)
{
}
bool Insert(const pair<K, V>& KV)
{
if (_node == nullptr)
{
_node = new RBTreeNode(KV.first, KV.second);
_node->_color = BLACK;
return true;
}
const K& key = KV.first;
const V& value = KV.second;
RBTreeNode* cur = _node;
RBTreeNode* parent = _node;
while (cur)
{
if (key < cur->_key)
{
parent = cur;
cur = cur->_left;
}
else if (key > cur->_key)
{
parent = cur;
cur = cur->_right;
}
else
{
return false;
}
}
if (key < parent->_key)
{
parent->_left = new RBTreeNode(key, value);
parent->_left->_parent = parent;
parent->_left->_color = RED;
cur = parent->_left;
}
if (key > parent->_key)
{
parent->_right = new RBTreeNode(key, value);
parent->_right->_parent = parent;
parent->_right->_color = RED;
cur = parent->_right;
}
while (cur!=_node&&parent!=_node)
{
if (parent->_color == BLACK)
{
return true;
}
else // paretn->_color==RED
{
if (parent == parent->_parent->_left) // cur 和 parent位于 g左边的情况
{
RBTreeNode* uncle = parent->_parent->_right;
if (uncle == nullptr && cur == parent->_left) // 开始即结束 直接变形
{
RBTreeNode* Grandp = parent->_parent;
RotateR(parent->_parent);
parent->_color = BLACK;
Grandp->_color = RED;
return true;
}
else if (uncle == nullptr && cur == parent->_right)
{
RBTreeNode* Grandp = parent->_parent;
RotateL(parent);
RotateR(Grandp);
Grandp->_color = RED;
cur->_color = BLACK;
return true;
}
else if (uncle->_color == RED) //向上调 // cur 位于 parent的左边 右边都行
{
parent->_color = BLACK;
uncle->_color = BLACK;
if (parent->_parent != _node)
{
parent->_parent->_color = RED;
}
cur = parent->_parent;
parent = cur->_parent;
}
else if (uncle->_color == BLACK&&cur==parent->_left) // 开始旋转
{
RBTreeNode* Grandp = parent->_parent;
RotateR(parent->_parent);
parent->_color = BLACK;
Grandp->_color = RED;
return true;
}
else if (uncle->_color == BLACK && cur == parent->_right)
{
RBTreeNode* Grandp = parent->_parent;
RotateL(parent);
RotateR(Grandp);
Grandp->_color = RED;
cur->_color = BLACK;
return true;
}
}
else // parent==paretn->_parent->_right
{
RBTreeNode* uncle = parent->_parent->_left;
if (uncle == nullptr && cur == parent->_right)
{
RBTreeNode* Grandp = parent->_parent;
RotateL(parent->_parent);
Grandp->_color = RED;
parent->_color = BLACK;
return true;
}
else if (uncle == nullptr && cur == parent->_left)
{
RBTreeNode* Grandp = parent->_parent;
RotateR(parent);
RotateL(Grandp);
cur->_color = BLACK;
Grandp->_color = RED;
return true;
}
else if (uncle->_color == RED)
{
parent->_color = BLACK;
uncle->_color = BLACK;
if (parent->_parent != _node)
{
parent->_parent->_color = RED;
}
cur = parent->_parent;
parent = cur->_parent;
}
else if (uncle->_color == BLACK && cur == parent->_left)
{
RBTreeNode* Grandp = parent->_parent;
RotateL(parent->_parent);
parent->_color = BLACK;
Grandp->_color = RED;
return true;
}
else if (uncle->_color == BLACK && cur == parent->_right)
{
RBTreeNode* Grandp = parent->_parent;
RotateR(parent);
RotateL(Grandp);
Grandp->_color = RED;
cur->_color = BLACK;
return true;
}
}
}
}
}
void RotateL(RBTreeNode* root)
{
if (root == nullptr)
{
return;
}
RBTreeNode* rootR = root->_right;
root->_right = rootR->_left;
if (rootR->_left)
{
rootR->_left->_parent = root;
}
rootR->_left = root;
RBTreeNode* g = root->_parent;
root->_parent = rootR;
if (root == _node)
{
_node = rootR;
rootR->_parent = nullptr;
}
else
{
rootR->_parent = g;
if (root == g->_left)
{
g->_left = rootR;
}
else
{
g->_right = rootR;
}
}
}
void RotateR(RBTreeNode* root)
{
if (root == nullptr)
{
return;
}
RBTreeNode* rootL = root->_left;
root->_left = rootL->_right;
if (rootL->_right)
{
rootL->_right->_parent = root;
}
rootL->_right = root;
RBTreeNode* g = root->_parent;
root->_parent = rootL;
if (root == _node)
{
_node = rootL;
rootL->_parent = nullptr;
}
else
{
rootL->_parent = g;
if (root == g->_left)
{
g->_left = rootL;
}
else
{
g->_right = rootL;
}
}
}
void _InOrder(RBTreeNode* root)
{
if (root == nullptr)
{
return;
}
_InOrder(root->_left);
cout << root->_key << " " << root->_value << endl;
_InOrder(root->_right);
}
void InOrder()
{
_InOrder(_node);
}
private:
RBTreeNode* _node;
};