#ifndef REDBLACKTREE_REDBLACKTREE_H
#define REDBLACKTREE_REDBLACKTREE_H
template<typename T>
class RedBlackTree
{
enum Color{
RED,BLACK
};
class Node{
public:
T key;
Color color;
Node* left;
Node* right;
Node* parent;
Node():key{},color(BLACK),left(nullptr),right(nullptr){}
Node(T key):key(key),color(BLACK),left(nullptr),right(nullptr){}
};
Node* NIL;
Node *root;
public:
RedBlackTree()
{
NIL = new Node();
root = NIL;
}
~RedBlackTree()
{
postorder_walk_delete(root);
if(NIL)
{
delete NIL;
NIL = nullptr;
}
}
void insert(T key)
{
Node* node = new Node();
node->key = key;
RB_insert(node);
}
bool remvoe(T key)
{
Node* node = search(key);
if(node == NIL)
return false;
RB_delete(node);
delete node;
node = nullptr;
return true;
}
void show(void(*f)(T))
{
if(root == NIL)
return;
inorder_walk(root,f);
}
private:
// x
// \
// y
void left_rotate(Node *x)
{
Node *y = x->right;
x->right = y->left;
if(y->left != NIL)
y->left->parent = x;
y->parent = x->parent;
if(x->parent == NIL)
root = y;
else if(x == x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->left = x;
x->parent = y;
}
// y -> x
// / \ -> / \
// x c -> a y
// / \ -> / \
// a b -> b c
void right_rotate(Node *y)
{
Node* x = y->left;
y->left = x->right;
if(x->right != NIL)
x->right->parent = y;
x->parent = y->parent;
if(y->parent == NIL)
root = x;
else if(y == y->parent->left)
y->parent->left = x;
else
y->parent->right = x;
x->right = y;
y->parent = x;
}
void RB_insert(Node *z)
{
Node* y = NIL;
Node* x = root;
while (x!= NIL)
{
y = x;
if(z->key<x->key)
x = x->left;
else
x = x->right;
}
z->parent = y;
if(y == NIL)
root = z;
else if(z->key<y->key)
y->left = z;
else
y->right = z;
z->left = NIL;
z->right = NIL;
z->color = RED;
RB_insert_fixup(z);
}
void RB_insert_fixup(Node* z)
{
Node *y = nullptr;
while (z->parent->color == RED)
{
if(z->parent == z->parent->parent->left)
{
y = z->parent->parent->right;
if(y->color == RED)
{
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
}
else {
if (z == z->parent->right) {
z = z->parent;
left_rotate(z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
right_rotate(z->parent->parent);
}
}
else
{
y = z->parent->parent->left;
if(y->color == RED)
{
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
}
else
{
if(z == z->parent->left)
{
z = z->parent;
right_rotate(z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
left_rotate(z->parent->parent);
}
}
}
root->color = BLACK;
}
void RB_transplant(Node *u,Node*v)
{
if(u->parent == NIL)
root = v;
else if(u == u->parent->left)
u->parent->left = v;
else
u->parent->right = v;
v->parent = u->parent;
}
void RB_delete(Node* z)
{
Node* y = z;
Node* x = NIL;
Color y_original_color = y->color;
if(z->left == NIL)
{
x = z->right;
RB_transplant(z,z->right);
}
else if(z->right == NIL)
{
x = z->left;
RB_transplant(z,z->left);
}
else
{
y = minimum(z->right);
y_original_color = y->color;
x = y->right;
if(y->parent == z)
{
x->parent = y;
}
else
{
RB_transplant(y,y->right);
y->right = z->right;
y->right->parent = y;
}
RB_transplant(z,y);
y->left = z->left;
y->left->parent = y;
y->color = z->color;
}
if(y_original_color == BLACK)
{
PB_delete_fixup(x);
}
}
void PB_delete_fixup(Node* x)
{
while (x != root && x->color == BLACK)
{
if(x == x->parent->left)
{
Node* w = x->parent->right;
if(w->color == RED)
{
w->color = BLACK;
x->parent->color = RED;
left_rotate(x->parent);
w = x->parent->right;
}
if(w->left->color == BLACK && w->right->color == BLACK)
{
w->color = RED;
x = x->parent;
}
else
{
if(w->right->color == BLACK)
{
w->left->color = BLACK;
w->color = RED;
right_rotate(w);
w = x->parent->right;
}
w->color = x->parent->color;
x->parent->color = BLACK;
w->right->color = BLACK;
left_rotate(x->parent);
x = root;
}
}
else
{
Node* w = x->parent->left;
if(w->color == RED)
{
w->color = BLACK;
x->parent->color = RED;
right_rotate(x->parent);
w = x->parent->left;
}
if(w->left->color == BLACK && w->right->color == BLACK)
{
w->color = RED;
x = x->parent;
}
else
{
if(w->left->color == BLACK)
{
w->right->color = BLACK;
left_rotate(w);
w = x->parent->left;
}
w->color = x->parent->color;
x->parent->color = BLACK;
w->left->color = BLACK;
right_rotate(x->parent);
x = root;
}
}
}
x->color = BLACK;
}
Node* minimum(Node * x)
{
while (x->left != NIL)
{
x = x->left;
}
return x;
}
Node* maximum(Node* x)
{
while (x->right != NIL)
{
x = x->right;
}
return x;
}
Node* search(T key)
{
Node* x = root;
while (x != NIL && key != x->key)
{
if(key<x->key)
x = x->left;
else
x = x->right;
}
return x;
}
void inorder_walk(Node* x,void(*f)(T))
{
if(x != NIL)
{
inorder_walk(x->left,f);
f(x->key);
inorder_walk(x->right,f);
}
}
void postorder_walk_delete(Node* x)
{
if(x!=NIL)
{
postorder_walk_delete(x->left);
postorder_walk_delete(x->right);
delete x;
}
}
};
#endif //REDBLACKTREE_REDBLACKTREE_H
07-18
320