红黑树满足五个特征:
1、每个结点或是黑色或是红色
2、根结点是黑色
3、叶子结点是黑色(此时所说的结点是空结点 )
4、红色结点的子结点必是黑结点
5、从一个结点出发到其子孙的所有叶子结点(空结点)经过的黑色结点个数全部相同。
先看一下红黑树结点的定义
enum COLOR {RED,BLACK}
struct TreeNode
{
int key;
COLOR color;
TreeNode *lChild;
TreeNode *rChild;
TreeNode *parent;
};
红黑树的旋转:
红黑树的旋转类似于平衡二叉树的旋转,只是每个节点增加了父指针。
void RBTree::LeftRotate(TreeNode *x)
{
if (NULL == x->rChild) return;
TreeNode *y = x->rChild;
x->rChild = y->lChild;
if (NULL != y->lChild)
y->lChild->parent = x;
y->parent = x->parent;
if (NULL == x->parent)
root = y;
else if (x == x->parent->lChild)
x->parent->lChild = y;
else
x->parent->rChild = y;
y->lChild = x;
x->parent = y;
}
void RBTree::RightRotate(TreeNode *y)
{
if (NULL == y->lChild) return;
TreeNode *x = y->lChild;
y->lChild = x->rChild;
if (NULL != x->rChild)
x->rChild->parent = y;
x->parent = y->parent;
if (NULL == y->parent)
root = x;
else if (y == y->parent->lChild)
y->parent->lChild = x;
else
y->parent->rChild = x;
x->rChild = y;
y->parent = x;
}
红黑树的插入:
先像二叉查找树一样,将一个数值插入,则插入后的结点必是叶子结点。
void RBTree::Insert(int _key)
{
TreeNode *z = new TreeNode;
z->key = _key;
z->color = RED;
z->lChild = z->rChild = NULL;
TreeNode *y = NULL;
TreeNode *x = root;
while (x)
{
y = x;
if (_key < x->key)
x = x->lChild;
else
x = x->rChild;
}
z->parent = y;
if (NULL == y)
root = z;
else if (z->key < y->key)
y->lChild = z;
else
y->rChild = z;
InsertFix(z);
}
红黑树的插入调整
上步插入后,可知其可能违背红黑树的第四条规则,其他规则都不违背。
此时分三种情况考虑(其实是六种,但是对称存在,在这里就简化为三种吧,假设插入节点的父结点是其祖父节点的左结点)
一、u为红
解决方案:将p,u改为黑,g改为红,然后把cur=g,继续向上调整
二、u为黑,cur为父节点的左结点
解决方案:p改为黑,g改为红,以g为根右旋转
三、u为黑,curr为父节点的右结点
解决方案:以偏p为根左旋转,转化为情况二
void RBTree::InsertFix(TreeNode *z)
{
while (z->parent->color == RED)
{
if (z->parent == z->parent->parent->lChild)
{
TreeNode *y = z->parent->parent->rChild;
if (y->color == RED)
{
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
}
else
{
if (z == z->parent->rChild)
{
z = z->parent;
LeftRotate(z);
}
z->parent->parent->color = RED;
z->parent->color = BLACK;
RightRotate(z->parent->parent);
}
}
else
{
TreeNode *y = z->parent->parent->lChild;
if (y->color == RED)
{
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
}
else
{
if (z == z->parent->lChild)
{
z = z->parent;
RightRotate(z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
LeftRotate(z->parent->parent);
}
}
}
root->color = BLACK;
}
关于红黑树的删除及完整实现,请看以后的文章。