红黑树概念
红黑树,是一种二叉搜索树,与一般二叉搜索树不同的是在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。
性质
它不仅仅具有二叉搜索树的特性,还必须满足以下特点:
- 根结点必须是黑色
- 每个结点不是黑的就是红的
- 如果一个节点是红色的,则它的两个孩子结点是黑色的
- 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均 包含相同数目的黑色结点
- 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)
- 新插入的结点必须以红色结点插入
操作
红黑树树的插入操作
typedef enum { BLACK = 0, RED = 1 }Color_Type;
template<class Type>
class RBTree;
template<class Type>
class RBNode
{
friend class RBTree<Type>;
public:
RBNode(const Type& d = Type())
:data(d), leftChild(nullptr), rightChild(nullptr), parent(nullptr), color(RED)
{}
~RBNode()
{}
private:
Type data;
RBNode* leftChild;
RBNode* rightChild;
RBNode* parent;
Color_Type color;
};
template<class Type>
class RBTree
{
public:
RBTree() :Nil(_Buynode()), root(Nil)
{
Nil->parent = Nil->leftChild = Nil->rightChild = nullptr;
Nil->color = BLACK;
}
public:
void Insert(const Type& v)
{
Insert(root, v);
}
void Remove(const Type& key)
{
Remove(root, key);
}
protected:
void Insert_Fixup(RBNode<Type>*& t, RBNode<Type>* x);
void Insert(RBNode<Type>*& t, const Type& v);
protected:
void RightRotate(RBNode<Type>*& t, RBNode<Type>* p);
void LeftRotate(RBNode<Type>*& t, RBNode<Type>* p);
protected:
RBNode<Type>* _Buynode(const Type& v = Type())
{
RBNode<Type>* s = new RBNode<Type>(v);
s->leftChild = s->rightChild = Nil;
return s;
}
private:
RBNode<Type>* Nil;
RBNode<Type>* root;
};
template<class Type>
void RBTree<Type>::LeftRotate(RBNode<Type>*& t, RBNode<Type>* p)
{
RBNode<Type>* s = p->rightChild;
p->rightChild = s->leftChild;
if (s->leftChild != Nil)
s->leftChild->parent = p;
s->parent = p->parent;
if (p->parent == Nil)
t = s;
else if (p == p->parent->leftChild)
p->parent->leftChild = s;
else
p->parent->rightChild = s;
s->leftChild = p;
p->parent = s;
}
template<class Type>
void RBTree<Type>::RightRotate(RBNode<Type>*& t, RBNode<Type>* p)
{
RBNode<Type>* s = p->leftChild;
p->leftChild = s->rightChild;
if (s->rightChild != Nil)
s->rightChild->parent = p;
s->parent = p->parent;
if (p->parent == Nil)
t = s;
else if (p == p->parent->leftChild)
p->parent->leftChild = s;
else
p->parent->rightChild = s;
s->rightChild = p;
p->parent = s;
}
/
template<class Type>
void RBTree<Type>::Insert(RBNode<Type>*& t, const Type& v)
{
//1 按照BST规则插入节点
RBNode<Type>* x = t, * pr = Nil;
while (x != Nil)
{
if (v == x->data)
return;
pr = x;
if (v < x->data)
x = x->leftChild;
else
x = x->rightChild;
}
x = _Buynode(v);
if (pr == Nil) //说明插入的节点为第一个根节点
{
t = x;
t->parent = Nil;
}
else if (v < pr->data)
pr->leftChild = x;
else
pr->rightChild = x;
x->parent = pr;
//2 调整平衡
Insert_Fixup(t, x);
}
template<class Type>
void RBTree<Type>::Insert_Fixup(RBNode<Type>*& t, RBNode<Type>* x)
{
while (x->parent->color == RED)
{
//不平衡
RBNode<Type>* s;
if (x->parent == x->parent->parent->leftChild)
{
//左分支
s = x->parent->parent->rightChild;
//状况三
if (s->color == RED)
{
x->parent->color = BLACK;
x->parent->parent->color = RED;
s->color = BLACK;
x = x->parent->parent;
}
else
{
//状况二
if (x == x->parent->rightChild)
{
x = x->parent;
LeftRotate(t, x);
}
//状况一
x->parent->color = BLACK;
x->parent->parent->color = RED;
RightRotate(t, x->parent->parent);
}
}
else
{
//右分支
s = x->parent->parent->leftChild;
//状况三
if (s->color == RED)
{
x->parent->color = BLACK;
x->parent->parent->color = RED;
s->color = BLACK;
x = x->parent->parent;
}
else
{
//状况二
if (x == x->parent->leftChild)
{
x = x->parent;
RightRotate(t, x);
}
//状况一
x->parent->color = BLACK;
x->parent->parent->color = RED;
LeftRotate(t, x->parent->parent);
}
}
}
t->color = BLACK;
}
红黑树删除
template<class Type>
void RBTree<Type>::Remove(RBNode<Type>*& t, const Type& key)
{
//1 按照BST规则删除节点
RBNode<Type>* p = t, * q;
while (p != Nil && p->data != key)
{
if (key < p->data)
p = p->leftChild;
else
p = p->rightChild;
}
if (p == Nil) //要删除的节点不存在
return;
if (p->leftChild != Nil && p->rightChild != Nil)
{
q = p->leftChild;
while (q->rightChild != Nil)
q = q->rightChild;
p->data = q->data;
p = q;
}
if (p->leftChild != Nil)
q = p->leftChild;
else
q = p->rightChild; //要么p真实指向p的右树,要么p指向空
q->parent = p->parent;
if (q->parent == Nil)
t = q;
else if (p == p->parent->leftChild)
p->parent->leftChild = q;
else
p->parent->rightChild = q;
//2 调整平衡
if (p->color == BLACK)
{
if (q != Nil)
q->color = BLACK;//组合4
else
Remove_Fixup(t, q); //组合2
}
delete p;
}
template<class Type>
void RBTree<Type>::Remove_Fixup(RBNode<Type>*& t, RBNode<Type>* x)
{
while (x != t && x->color == BLACK)
{
RBNode<Type>* w; // 兄弟节点
if (x == x->parent->leftChild)
{
//左分支
w = x->parent->rightChild;
//情形四
if (w->color == RED)
{
w->color = BLACK;
x->parent->color = RED;
LeftRotate(t, x->parent);
w = x->parent->rightChild;
}
//情形三
if (w->leftChild->color != RED && w->rightChild->color != RED)
{
w->color = RED;
if (x->parent->color == RED)
{
x->parent->color = BLACK;
x = t;
}
else
x = x->parent;
}
else
{
//情形二
if (w->leftChild != Nil)
{
w->color = RED;
w->leftChild->color = BLACK;
w = w->leftChild;
RightRotate(t, w->parent);
}
//情形一
w = x->parent->rightChild;
w->color = x->parent->color;
x->parent->color = BLACK;
w->rightChild->color = BLACK;
LeftRotate(t, x->parent);
x = t;
}
}
else
{
//右分支
w = x->parent->leftChild;
//情形4
if (w->color == RED)
{
w->color = BLACK;
w->parent->color = RED;
RightRotate(t, x->parent);
w = x->parent->leftChild;
}
//情形3
if (w->leftChild->color != RED && w->rightChild->color != RED)
{
w->color = RED;
if (x->parent->color == RED)
{
x->parent->color = BLACK;
x = t;
}
else
{
x = x->parent;
}
}
else
{
//情形2
if (w->rightChild != Nil)
{
w->color = RED;
w->rightChild->color = BLACK;
w = w->rightChild;
LeftRotate(t, w->parent);
}
//情形1
w = x->parent->leftChild;
w->color = x->parent->color;
x->parent->color = BLACK;
w->rightChild->color = BLACK;
RightRotate(t, x->parent);
x = t;
}
}
}
t->color = BLACK;
}
本文详细介绍了红黑树的概念,这是一种自平衡的二叉搜索树,通过颜色属性确保路径平衡。文章列举了红黑树的五个性质,并展示了插入和删除节点的关键代码实现,包括旋转操作和平衡调整策略,旨在帮助读者理解红黑树的内部工作机制。
的结构与操作#&spm=1001.2101.3001.5002&articleId=123030902&d=1&t=3&u=b553821881984fafa20a9cea61e80b81)

被折叠的 条评论
为什么被折叠?



