红黑树的性质:
1.每个节点不是红就是黑
2.根节点为黑色
3.如果节点为红,其子节点必须为黑
4.任一节点至NULL(树尾端)的任何路径,所含之黑节点树必须相同
性质总结一句话:一头一脚黑,黑同红不连
规则1就不用说了,由规则2,root->color=NULL;由规则4,可知新增节点为红;由规则3可知,新增节点之父必为黑,
当新节点插入不符合上述规则时,进行调整
经整理后,插入分为3种:
1.插入节点为父节点的左子树,叔节点为黑或空节点
2.插入节点为父节点的右子树,叔节点为黑或空节点
3.叔节点为红
#pragma once
typedef enum { RED = 0, BLACK } COLOR;
template<class Type>
class RBTree;
template<class Type>
class RBNode
{
friend class RBTree<Type>;
public:
RBNode() : data(Type()), color(RED), leftChild(NULL), rightChild(NULL), parent(NULL)
{}
RBNode(Type d, RBNode<Type>*left = NULL, RBNode<Type>*right = NULL, RBNode<Type>*pr = NULL)
:data(d), color(RED), leftChild(left), rightChild(right), parent(pr)
{}
~RBNode()
{}
private:
Type data;
RBNode<Type> *leftChild;
RBNode<Type> *rightChild;
RBNode<Type> *parent;
COLOR color;
};
template<class Type>
class RBTree
{
public:
RBTree() :root(NULL)
{}
public:
bool Insert(const Type& x)
{
return Insert(root, x);
}
protected:
bool Insert(RBNode<Type> *&t, const Type &v)
{
RBNode<Type> *p = t;
RBNode<Type> *pr = NULL;
while (p != NULL)
{
if (v == p->data)
return false;
pr = p;
if (v < p->data)
p = p->leftChild;
else
p = p->rightChild;
}
RBNode<Type> *x = new RBNode<Type>(v);
x->parent = pr;
if (pr == NULL)
{
t = x;
t->color = BLACK;
return true;
}
if (pr->data > x->data)
pr->leftChild = x;
else
pr->rightChild = x;
_Insert_Fixup(t, x);
return true;
}
public:
void sort()
{
sort(root);
}
protected:
void sort(RBNode<Type>*t)const
{
if (t != NULL)
{
sort(t->leftChild);
cout << t->data <<":"<<t->color<<" ";
sort(t->rightChild);
}
}
protected:
void _Insert_Fixup(RBNode<Type>*&t, RBNode<Type>*x)
{
RBNode<Type>*s;
while (x->parent!=NULL&&x->parent->color == RED)//父节点为红色
{
if (x->parent == x->parent->parent->leftChild)//父亲为他父亲的父亲的左孩子
{
s = x->parent->parent->rightChild;//叔父为他父亲的父亲的右孩子
/*if ((x == x->parent->leftChild&&s == NULL) ||
(x == x->parent->leftChild&&s != NULL&&s->color == BLACK))//1.插入节点为他父亲的左孩子,且叔父节点为空或者叔父节点不为空但颜色为黑
{
x->parent->color = BLACK;
x->parent->parent->color = RED;
RotateR(x->parent->parent);
}
else if ((x == x->parent->rightChild&&s == NULL) ||
(x == x->parent->rightChild&&s != NULL&&s->color == BLACK))//2.插入节点为他父亲的右孩子,且叔父节点为空或者叔父节点不为空但颜色为黑
{
x->color = BLACK;
x->parent->parent->color = RED;
RotateL(x->parent);
RotateR(x->parent);
}*/
//将上面的2种情况进行改进(更精简化)
if((s != NULL&&s->color == BLACK)||s == NULL)
{
if (x == x->parent->rightChild)//2.
{
x = x->parent;
RotateL(x);
}
//1.
x->parent->color = BLACK;
x->parent->parent->color = RED;
RotateR(x->parent->parent);
}
#if 0
else if (x == x->parent->leftChild&&s != NULL&&s->color == RED)//3.插入节点为他父亲的左孩子,且叔父节点不为空但颜色为红
{
x->color = BLACK;
RotateR(x->parent->parent);
if (x->parent->parent != NULL &&x->parent->parent->color == RED)
{
x = x->parent;
continue;
}
}
else if (x == x->parent->rightChild&&s != NULL&&s->color == RED)//4.插入节点为他父亲的右孩子,且叔父节点不为空但颜色为红
{
x->parent->color = BLACK;
RotateL(x->parent);
RotateR(x->parent);
if (x->parent != NULL &&x->parent->color == RED)
{
continue;
}
}
#endif
//对上面3,4情况进行改进,即不管x为其父的左孩子还是右孩子,将其父和叔叔的颜色改为黑色,其父亲的父亲改为红色,然后让x指向其父亲的父亲,循环(最后树的形状与之前不同)
else if(s!=NULL&&s->color==RED)
{
x->parent->color = BLACK;
x->parent->parent->color = RED;
s->color = BLACK;
x = x->parent->parent;
continue;
}
break;
}
else//与上面相反
{
s = x->parent->parent->leftChild;
/*
if ((x == x->parent->rightChild&&s == NULL) ||
(x == x->parent->rightChild&&s != NULL&&s->color == BLACK))
{
x->parent->color = BLACK;
x->parent->parent->color = RED;
RotateL(x->parent->parent);
}
else if
((x == x->parent->leftChild&&s == NULL) ||
(x == x->parent->leftChild&&s != NULL&&s->color == BLACK))
{
x->color = BLACK;
x->parent->parent->color = RED;
RotateR(x->parent);
RotateL(x->parent);
}
*/
if ((s != NULL&&s->color == BLACK) || s == NULL)
{
if (x == x->parent->leftChild)
{
x = x->parent;
RotateR(x);
}
x->parent->color = BLACK;
x->parent->parent->color = RED;
RotateL(x->parent->parent);
}
#if 0
else if (x == x->parent->rightChild&&s != NULL&&s->color == RED)
{
x->color = BLACK;
RotateL(x->parent->parent);
if (x->parent->parent != NULL&&x->parent->parent->color == RED)
{
x = x->parent;
continue;
}
}
else if (x == x->parent->leftChild&&s != NULL&&s->color == RED)
{
x->parent->color= BLACK;
RotateR(x->parent);
RotateL(x->parent);
if (x->parent != NULL&&x->parent->color == RED)
{
continue;
}
}
#endif
else if (s != NULL&&s->color == RED)
{
x->parent->color = BLACK;
x->parent->parent->color = RED;
s->color = BLACK;
x = x->parent->parent;
continue;
}
break;
}
}
t->color = BLACK;
}
protected:
void RotateR(RBNode<Type>*ptr)
{
RBNode<Type>*subR = ptr;
ptr = subR->leftChild;
if (ptr->rightChild != NULL)
ptr->rightChild->parent = subR;
ptr->parent = subR->parent;
if (subR->parent == NULL)
root = ptr;
else
{
if (subR == subR->parent->leftChild)
subR->parent->leftChild = ptr;
else
subR->parent->rightChild = ptr;
}
subR->leftChild = ptr->rightChild;
ptr->rightChild = subR;
subR->parent = ptr;
}
void RotateL(RBNode<Type>*ptr)
{
RBNode<Type>*subL = ptr;
ptr = subL->rightChild;
if (ptr->leftChild != NULL)
ptr->leftChild->parent = subL;
ptr->parent = subL->parent;
if (subL->parent == NULL)
{
root = ptr;
}
else
{
if (subL == subL->parent->leftChild)
subL->parent->leftChild = ptr;
else
subL->parent->rightChild = ptr;
}
subL->rightChild = ptr->leftChild;
ptr->leftChild = subL;
subL->parent = ptr;
}
private:
RBNode<Type>*root;
};
void main()
{
//int ar[] = { 16,3,1,7,11,9,26,18,14,15 };
int ar[] = { 16,3,1,7,11,9,26,18,14,13 };
int n = sizeof(ar) / sizeof(int);
RBTree<int> rb;
for (int i = 0; i < n; ++i)
{
rb.Insert(ar[i]);
}
rb.sort();
}