#include <iostream>
#include <vector>
template<typename Comparable>
class RBTree
{
private:
struct RBNode
{
RBNode *parent;
RBNode *left;
RBNode *right;
Comparable key;
int color;
RBNode(RBNode *p = nullptr, RBNode *lt = nullptr, RBNode *rt = nullptr,
const Comparable ele = Comparable(), int c = BLACK)
:parent(p), left(lt), right(rt), key(ele), color(c)
{ }
};
RBNode *nilNode; //哨兵节点,代表叶节点和根节点的父节点
RBNode *root = new RBNode(nilNode, nullptr, nullptr, Comparable(), BLACK);
int currenSize = 0;
enum{ RED, BLACK };
void print(RBNode *t)
{
if (t !=nilNode)
{
print(t->left);
cout << t->key << " "<<((t->color==RED)? "RED":"BLACK")<<" "<<((t==root)?"is root":"not root")<<endl;
print(t->right);
}
}
public:
RBTree()
{
root->parent = nilNode;
}
void print()
{
print(root);
}
//左旋
void leftRotate(RBNode *t)
{
RBNode *y = t->right;
t->right = y->left;
if (y->left != nilNode)//如果y节点的左节点不为空,则应该父节点指向t
y->left->parent = t;
y->parent = t->parent;
if (t->parent == nilNode)
root = y;
else if (t == t->parent->left)
t->parent->left = y;
else
t->parent->right = y;
y->left = t;
t->parent = y;
}
//右旋
void rightRotate(RBNode *t)
{
RBNode *y = t->left;
t->left = y->right;
if (y->right != nilNode)
y->right->parent = t;
y->parent = t->parent;
if (t->parent == nilNode)
root = y;
else if (t == t->parent->left)
t->parent->left = y;
else
t->parent->right = y;
y->right = t;
t->parent = y;
}
//在红黑树中插入新的元素
void rbInsert(const Comparable z,int c=RED)
{
RBNode *y = nilNode;
RBNode *x = root;
//如果是插入的第一个节点,将根节点的值设定为z即可
if (currenSize == 0)
{
root->key=z;
currenSize++;
}
else
{
while (x != nilNode)
{
y = x;
if (z < x->key)
x = x->left;
else
x = x->right;
}
RBNode *t = new RBNode(y, nilNode, nilNode, z, c);
if (z<y->key)
y->left = t;
else
y->right = t;
currenSize++;
rbInsertFixup(t);//保持红黑树性质
}
}
void rbInsertFixup(RBNode *t)
{
while (t!=root&&t->parent->color == RED)
{
//如果父节点是祖父节点的左儿子
if (t->parent == t->parent->parent->left)
{
//y指向t的叔节点
RBNode *y = t->parent->parent->right;
//如果叔节点为红色,则将父节点和叔节点变为黑色
//同时把祖父节点变为红色,然后指针指向祖父节点以判断祖父节点是否符合性质
if (y->color == RED)
{
t->parent->color = BLACK;
y->color = BLACK;
if (t->parent->parent != root)
t->parent->parent->color = RED;
t = t->parent->parent;
}
//如果叔节点为黑色,则需要通过两次旋转
//如果当前节点为右子树
else if (t == t->parent->right)
{
t = t->parent;
leftRotate(t);
t->parent->color = BLACK;
t->parent->parent->color= RED;
rightRotate(t->parent->parent);
}
//如果当前节点为左子树
else
{
t = t->parent;
rightRotate(t);
t->parent->color = BLACK;
t->parent->parent->color = RED;
rightRotate(t->parent->parent);
}
}
//如果父节点是祖父节点的右儿子
else
{
RBNode *y = t->parent->parent->right;
//如果叔节点为红色,则将父节点和叔节点变为黑色
//同时把祖父节点变为红色,然后指针指向祖父节点以判断祖父节点是否符合性质
if (y->color == RED)
{
t->parent->color = BLACK;
y->color = BLACK;
if (t->parent->parent!=root)
t->parent->parent->color = RED;
t = t->parent->parent;
}
//如果叔节点为黑色,则需要通过两次旋转
//如果当前节点为左子树
else if (t == t->parent->left)
{
t = t->parent;
rightRotate(t);
t->parent->color = BLACK;
t->parent->parent->color = RED;
leftRotate(t->parent->parent);
}
//如果当前节点为右子树
else{
t = t->parent;
leftRotate(t);
t->parent->color = BLACK;
t->parent->parent->color = RED;
leftRotate(t->parent->parent);
}
}
}
}
};
算法导论—红黑树(还没写完,先备份一个)
最新推荐文章于 2021-08-16 20:04:48 发布