RBTree(红黑树)
红色节点不容许连续,黑色节点容许连续。根一定是黑色的,哨兵节点一定是黑色的。从任意节点出发到达哨兵节点的黑色节点个数要一致。
红黑树近似于平衡。
红黑树的定义
typedef enum { RED = 0, BLACK = 1 } ColorType;
typedef int KeyType;
typedef struct rb_node
{
rb_node *leftchild;//左孩子
rb_node *parent;//双亲
rb_node *rightchild;//右孩子
ColorType color;//颜色结点,红,黑
KeyType key;//关键码
}rb_node;
typedef struct
{
struct rb_node* root;//根节点
struct rb_node* NIL; //空节点
int cursize;//个数
}RBTree;
理解红黑树
我们看左图,如果从最上面的黑色节点出发,路径上看黑色数目都是2个,看右图,从最顶点的红色出发,黑色数目都是2个,这两个图是一样的。不会发生变化。
当我们插入第一个数据12,颜色必须是红色,但是它作为根节点,它的颜色由红色变为黑色,还有一个黑色节点作为哨兵节点,12的左孩子和右孩子都指向哨兵节点,插入23,颜色都是红色,双亲是黑色,可以(不许红色连续),我们插入34,34也是红色,在右边插入,但是它的双亲是红色,不行,就找双亲的双亲的左边,但是是哨兵节点(黑色),无法通过着色的改变来确定黑色的数目。
我们就以23位基准,把12绕到23,进行左旋转。23替代12的位置,23变为黑,12变为红。
我们插入45,45是红色,45的双亲是红色,找双亲的双亲的左边也是红色,
我们插入56,56是红色,双亲是红色,双亲的双亲的左边是哨兵,不能调整,只能进行旋转,把34改为红色,左单旋转。
我们插入50,双亲是红色,在56的左边,在折线上,双亲的双亲的左边是红色
我们插入78,大于56,颜色是红色,双亲是黑色,不需要调整。
我们插入89,是红色,双亲是红色,双亲的双亲的左边是红色
购买节点
rb_node* Buynode(KeyType kx)//购买结点
{
rb_node* s = (rb_node*)malloc(sizeof(rb_node));
if (nullptr == s) exit(1);
memset(s, 0, sizeof(rb_node));
s->color = RED;
s->key = kx;
return s;
}
void Freenode(rb_node* p)//释放结点
{
free(p);
}
左旋转
void RotateLeft(RBTree& tree, rb_node* ptr)//左旋转
{
rb_node* newroot = ptr->rightchild;
newroot->parent = ptr->parent;// 1
ptr->rightchild = newroot->leftchild;
if (newroot->leftchild != nullptr)
{
newroot->leftchild->parent = ptr;// 2
}
newroot->leftchild = ptr;
if (ptr->parent == nullptr)
{
tree.root = newroot;
}
else
{
if (ptr->parent->leftchild == ptr)
{
ptr->parent->leftchild = newroot;
}
else
{
ptr->parent->rightchild = newroot;
}
}
ptr->parent = newroot; // 3
}
右旋转
void RotateRight(RBTree& tree, rb_node* ptr)//右旋转
{
rb_node* newroot = ptr->leftchild;
newroot->parent = ptr->parent;//1
ptr->leftchild = newroot->rightchild;
if (newroot->rightchild != nullptr)
{
newroot->rightchild->parent = ptr;
}
newroot->rightchild = ptr;
if (ptr->parent == nullptr)
{
tree.root = newroot;
}
else
{
if (ptr->parent->leftchild == ptr)
{
ptr->parent->leftchild = newroot;
}
else
{
ptr->parent->rightchild = newroot;
}
}
ptr->parent = newroot;
}
插入和调整
void Adjust_RBTree(RBTree& tree, rb_node *ptr)
{
rb_node* _X = nullptr;
while (ptr->parent != nullptr && ptr->parent->color != BLACK)
{
if (ptr->parent->parent->rightchild == ptr->parent)
{
_X = ptr->parent->parent->leftchild;
if (_X->color == RED)
{
ptr->parent->color = BLACK;
_X->color = BLACK;
ptr->parent->parent->color = RED;
ptr = ptr->parent->parent;
}
else
{
if (ptr->parent->leftchild == ptr)
{
ptr = ptr->parent;
RotateRight(tree, ptr);
}
ptr->parent->color = BLACK;
ptr->parent->parent->color = RED;
RotateLeft(tree, ptr->parent->parent);
}
}
else // left
{
_X = ptr->parent->parent->rightchild;
if (_X->color == RED)
{
ptr->parent->color = BLACK;
_X->color = BLACK;
ptr->parent->parent->color = RED;
ptr = ptr->parent->parent;
}
else
{
if (ptr->parent->rightchild == ptr)
{
ptr = ptr->parent;
RotateLeft(tree, ptr);
}
ptr->parent->color = BLACK;
ptr->parent->parent->color = RED;
RotateRight(tree, ptr->parent->parent);
}
}
}
tree.root->color = BLACK;
}
bool Insert(RBTree& tree, KeyType kx)
{
rb_node* p = Buynode(kx);
Adjust_RBTree(tree, p);
return true;
}