#include <iostream>
template <class T>
class RBTree{
public:
typedef enum { BLACK, RED } NodeColor;
// Определение сторожевого узла
// (фиктивного черного листа красно-черного дерева
#define NIL &sentinel
// Red Black TREE NODE
template <class DATA>
struct RBTreeNode{
RBTreeNode<DATA> *parent; // Указатель на родительский узел
RBTreeNode<DATA> *left; // Указатель на узел-корень
// левого поддерева
RBTreeNode<DATA> *right; // Указатель на узел-корень
// правого поддерева
NodeColor color; // Цвет узла
DATA data; // Объект данных, хранящихся в узле дерева
RBTreeNode( const DATA& _data,
RBTreeNode<DATA>* _parent = NULL,
RBTreeNode<DATA>* _left = NIL,
RBTreeNode<DATA>* _right = NIL,
NodeColor _color = RED ){
data = _data;
parent = _parent;
left = _left;
right = _right;
color = _color;
}
};
private:
RBTreeNode<T> sentinel; // Сторожевой узел
RBTreeNode<T> *root; // Корень дерева
public:
RBTree() : sentinel(0, NULL, NIL, NIL, BLACK){
root = NIL;
}
// Вставка узла
RBTreeNode<T> *InsertNode(const T& data) {
//Вспомогательные указатели:
RBTreeNode<T> *newItem; // на новый элемент
RBTreeNode<T> *current; // на обозреваемый элемент
RBTreeNode<T> *parent; // на родительский элемент для обозреваемого элемента
// Поиск места вставки
current = root;
parent = NULL;
while(current != NIL){
if(data == current->data) return current; // Такой узел уже есть
parent = current;
if(data < current->data)
current = current->left;
else сurrent = current->right;
}
// Создание нового узла
newItem = new RBTreeNode<T>(data, parent, NIL, NIL, RED);
// Привязка нового узла к дереву
if(parent == NULL){
root = newItem;
}else{
//Здесь: новый элемент не является корнем дерева
if(newItem->data < parent->data)
parent->left = newItem;
else parent->right = newItem;
}
// Восстановление баланса после вставки
InsertFixup(newItem);
return newItem;
}
// Поиск узла
RBTreeNode<T> *FindNode(const T& data){
RBTreeNode<T> *current = root;
while(true){
if(current == NIL) return NULL;
if(current->data == data) return current;
if(data < current->data)
сurrent = current->left;
else current = current->right;
}
}
// Удаление узла по значению данных
void DeleteNode(const T& data){
RBTreeNode<T> *toDelete = FindNode(data);
DeleteNode(toDelete);
}
// Удаление узла по адресу узла
void DeleteNode(RBTreeNode<T> *toDelete){
RBTreeNode<T> *x, *y; // Указатели на узлы в ходе спусков влево-вправо
if(toDelete == NULL || toDelete == NIL) return;
if(toDelete->left == NIL || toDelete->right == NIL){
// Хотя бы одно из поддеревьев отсутствует
y = toDelete;
}else{
// Есть оба поддерева
y = toDelete->right;
while(y->left != NIL) y = y->left;
}
// Обрабатываем случай, когда у узла "y"
// только один потомок
if(y->left != NIL) x = y->left;
else x = y->right;
// Исключаем узел "y" из "родительской" цепочки
x->parent = y->parent;
if(y->parent != NULL){
if(y == y->parent->left) y->parent->left = x;
else y->parent->right = x;
}else root = x;
if(y != toDelete){
toDelete->data =y->data;
}if(y->color == BLACK){
// Восстановление баланса после удаления
DeleteFixup(x);
}
delete y;
}
private:
// Поворот дерева с корнем root вправо относительно узла x
void RotateRight( RBTreeNode<T> *x ){
RBTreeNode<T> *y = x->left;
// Формируем левое поддерево для x
x->left = y->right;
if(y->right != NIL) y->right->parent = x;
if(y != NIL) y->parent = x->parent;
if(x->parent != NULL){
if(x == x->parent->right) x->parent->right = y;
else x->parent->left = y;
}else root = y;
// Связываем x и y
y->right = x;
if(x != NIL) x->parent = y;
}
// Поворот дерева с корнем root влево относительно узла x
void RotateLeft(RBTreeNode<T> *x){
RBTreeNode<T> *y = x->right;
// Формируем правое поддерево для x
x->right = y->left;
if(y->left != NIL) y->left->parent = x;
if(y != NIL) y->parent = x->parent;
if(x->parent != NULL){
if(x == x->parent->left) x->parent->left = y;
else x->parent->right = y;
}else root = y;
// Связываем x и y
y->left = x;
if(x != NIL) x->parent = y;
}
// Восстановление баланса после вставки узла x
void InsertFixup(RBTreeNode<T> *x){
// Двигаемся в направлении root пока не будет восстановлено свойство 3
while(x != root && x->parent->color == RED){
if(x->parent == x->parent->parent->left){
// Родитель в левом поддереве относительно деда
RBTreeNode<T> *uncle = x->parent->parent->right;
if( uncle->color == RED ){
// Перекрашиваем родителя и дядю в черный...
x->parent->color = uncle->color = BLACK;
// ... а деда – в красный
x->parent->parent->color = RED;
x = x->parent->parent; // Теперь дед – это x
}else{ // Дядя – черный
if(x == x->parent->right){
x = x->parent;
RotateLeft(x);
}
x->parent->color = BLACK;
x->parent->parent->color = RED;
RotateRight(x->parent->parent);
}
}else{
// Родитель в правом поддереве
// относительно деда
// (зеркальное отражение предыдущего блока)
RBTreeNode<T> *uncle = x->parent->parent->left;
if(uncle->color == RED){
x->parent->color = uncle->color = BLACK;
x->parent->parent->color = RED;
x = x->parent->parent;
}else{
if(x == x->parent->left){
x = x->parent;
RotateRight(x);
}
x->parent->color = BLACK;
x->parent->parent->color = RED;
RotateLeft(x->parent->parent);
}
}
}
root->color = BLACK;
}
// Восстановление баланса после удаления узла x
void DeleteFixup(RBTreeNode<T> *x){
while(x != root && x->color == BLACK){
if(x == x->parent->left){
// Удаляемый элемент – корень левого
// поддерева
RBTreeNode<T> *brother = x->parent->right;
if(brother->color == RED){
brother->color = BLACK;
x->parent->color = RED;
RotateLeft(x->parent);
brother = x->parent->right;
}
if(brother->left->color == BLACK && brother->right->color == BLACK){
brother->color = RED;
x = x->parent;
}else{
if(brother->right->color == BLACK){
brother->left->color = BLACK;
brother->color = RED;
RotateRight(brother);
brother = x->parent->right;
}
brother->color = x->parent->color;
x->parent->color = BLACK;
brother->right->color = BLACK;
RotateLeft(x->parent);
x = root;
}
}else{
// Удаляемый элемент – корень правого
// поддерева
RBTreeNode<T> *brother = x->parent->left;
if(brother->color == RED){
brother->color = BLACK;
x->parent->color = RED;
RotateRight(x->parent);
brother = x->parent->left;
}
if( brother->right->color == BLACK && brother->left->color == BLACK){
brother->color = RED;
x = x->parent;
}else{
if(brother->left->color == BLACK){
brother->right->color = BLACK;
brother->color = RED;
RotateLeft(brother);
brother = x->parent->left;
}
brother->color = x->parent->color;
x->parent->color = BLACK;
brother->left->color = BLACK;
RotateRight(x->parent);
x = root;
}
}
}
x->color = BLACK;
}
void DeleteNode(RBTreeNode<T> *&root, RBTreeNode<T> *toDelete){
RBTreeNode<T> *x, *y; // Указатели на узлы в ходе
// спусков влево-вправо
if(toDelete == NULL || toDelete == NIL) return;
if(toDelete->left == NIL || toDelete->right == NIL){
// Хотя бы одно из поддеревьев отсутствует
y = toDelete;
}else{
// Есть оба поддерева
y = toDelete->right;
while(y->left != NIL) y = y->left;
}
// Обрабатываем случай, когда у узла "y" только
// один потомок
if(y->left != NIL) x = y->left;
else x = y->right;
// Исключаем узел "y" из "родительской" цепочки
x->parent = y->parent;
if(y->parent != NULL){
if(y == y->parent->left) y->parent->left = x;
else y->parent->right = x;
}else root = x;
if(y != toDelete){
toDelete->data =y->data;
}
if(y->color == BLACK){
// Восстановление баланса после удаления
DeleteFixup( root, x );
}
delete y;
}
};
int main() {
RBTree<int> rb;
rb.InsertNode(3);
return 0;
}