红黑树
- 是一棵二叉排序树;
- 节点要么是红色要么是黑色,根节点是黑色,叶子节点也是黑色;
- 红色节点的子节点必须是黑色;
- 从根节点任意路径向下到叶子节点途经的黑色节点个数相同(适用子树);
#include <iostream>
enum class RbColor {RB_RED, RB_BLACK};
template <typename T>
class RbNode {
public:
RbNode<T>* parent;
RbNode<T>* left;
RbNode<T>* right;
T data;
RbColor color;
RbNode() : parent(nullptr), left(nullptr), right(nullptr), color(RbColor::RB_BLACK) {}
RbNode(RbNode<T>* p, RbNode<T>* l, RbNode<T>* r, T d, RbColor c) : parent(p), left(l), right(r), data(d), color(c) {}
};
template<typename T>
class RbTree {
public:
RbTree() {
root = NIL;
}
void Insert(T data);
private:
RbNode<T>* L(RbNode<T>* node);
RbNode<T>* R(RbNode<T>* node);
RbNode<T>* root;
static RbNode<T>* NIL;
static RbNode<T> nullobj;
};
template<typename T>
RbNode<T> RbTree<T>::nullobj = RbNode<T>();
template<typename T>
RbNode<T>* RbTree<T>::NIL = &RbTree<T>::nullobj;
template<typename T>
void RbTree<T>::Insert(T data) {
RbNode<T>* cur = root;
RbNode<T>* pcur = nullptr;
RbNode<T>* uncle = nullptr;
RbNode<T>* gp = nullptr;
if(root == NIL) {
root = new RbNode<T>(nullptr, NIL, NIL, data, RbColor::RB_BLACK);
return;
}
while(cur->left != NIL || cur->right != NIL) {
if(data < cur->data) {
cur = cur->left;
}
else if(data > cur->data) {
cur = cur->right;
}
else {
return;
}
}
if(data < cur->data) {
cur->left = new RbNode<T>(cur, NIL, NIL, data, RbColor::RB_RED);
pcur = cur;
cur = cur->left;
}
else {
cur->right = new RbNode<T>(cur, NIL, NIL, data, RbColor::RB_RED);
pcur = cur;
cur = cur->right;
}
while(pcur != nullptr && pcur->color == RbColor::RB_RED) {
gp = pcur->parent;
uncle = gp->left == pcur ? gp->right : gp->left;
if(uncle->color == RbColor::RB_RED) {
pcur->color = RbColor::RB_BLACK;
uncle->color = RbColor::RB_BLACK;
gp->color = RbColor::RB_RED;
cur = gp;
pcur = cur->parent;
}
else {
if(gp->left == pcur && pcur->left == cur) {
pcur->color = RbColor::RB_BLACK;
gp->color = RbColor::RB_RED;
gp = R(gp);
}
else if(gp->right == pcur && pcur->right == cur) {
pcur->color = RbColor::RB_BLACK;
gp->color = RbColor::RB_RED;
gp = L(gp);
}
else if(gp->left == pcur && pcur->right == cur) {
pcur = L(pcur);
pcur->color = RbColor::RB_BLACK;
gp->color = RbColor::RB_RED;
gp = R(gp);
}
else {
pcur = R(pcur);
pcur->color = RbColor::RB_BLACK;
gp->color = RbColor::RB_RED;
gp = L(gp);
}
}
}
root->color = RbColor::RB_BLACK;
}
template<typename T>
RbNode<T>* RbTree<T>::L(RbNode<T>* node) {
RbNode<T>* t1 = node->left;
RbNode<T>* t2 = node->right;
node->right->left = node;
node->parent = t2;
node->right = t1;
t1->parent = node;
return t2;
}
template<typename T>
RbNode<T>* RbTree<T>::R(RbNode<T>* node) {
RbNode<T>* t1 = node->right;
RbNode<T>* t2 = node->left;
node->left->right = node;
node->parent = t2;
node->left = t1;
t1->parent = node;
return t2;
}