#pragma once
#include <cstdio>
#include <cmath>
#include <cstdlib>
template <class KeyType, class T>
class RBTree
{
private:
int _size;
class Node
{
public:
KeyType key;
T value;
Node *Left, *Right, *Parent;
bool color; // black = false
};
void rotateLeft (Node* x)
{
if (x->Right == NULL)
{
return;
}
Node* y = x->Right;
x->Right = y->Left;
if (x->Right != NULL)
{
x->Right->Parent = x;
}
y->Parent = x->Parent;
if (x->Parent == NULL)
{
Root = y;
}
else
{
if (x == x->Parent->Left)
{
x->Parent->Left = y;
}
else
{
x->Parent->Right = y;
}
}
y->Left = x;
x->Parent = y;
}
void rotateRight (Node* x)
{
if (x->Left == NULL) {
return;
}
Node* y = x->Left;
x->Left = y->Right;
if (x->Left != NULL) {
x->Left->Parent = x;
}
y->Parent = x->Parent;
if (x->Parent == NULL) {
Root = y;
}
else {
if (x == x->Parent->Left) {
x->Parent->Left = y;
}
else {
x->Parent->Right = y;
}
}
y->Right = x;
x->Parent = y;
}
void insertFixup(Node *x)
{
while (x != Root && x->Parent->color == true)
{
if (x->Parent == x->Parent->Parent->Left)
{
Node *y = NULL;
if (x->Parent->Parent->Right!=NULL)
y = x->Parent->Parent->Right;
if ((y!=NULL) && (y->color == true))
{
x->Parent->color = false;
y->color = false;
x->Parent->Parent->color = true;
x = x->Parent->Parent;
}
else
{
if (x == x->Parent->Right)
{
x = x->Parent;
rotateLeft(x);
}
x->Parent->color = false;
x->Parent->Parent->color = true;
rotateRight(x->Parent->Parent);
}
}
else
{
Node *y = NULL;
if (x->Parent->Parent->Left!=NULL)
y = x->Parent->Parent->Left;
//Node *y = x->Parent->Parent->Left;
if ((y!=NULL) && (y->color == true))
{
x->Parent->color = false;
y->color = false;
x->Parent->Parent->color = true;
x = x->Parent->Parent;
}
else
{
if (x == x->Parent->Left)
{
x = x->Parent;
rotateRight(x);
}
x->Parent->color = false;
x->Parent->Parent->color = true;
rotateLeft(x->Parent->Parent);
}
}
}
Root->color = false;
}
void deleteFixup(Node *x)
{
while (x != Root && x->color == false)
{
if (x == x->Parent->Left)
{
Node *w = x->Parent->Right;
if (w->color == true)
{
w->color = false;
x->Parent->color = true;
rotateLeft (x->Parent);
w = x->Parent->Right;
}
if (w->Left->color == false && w->Right->color == false)
{
w->color = true;
x = x->Parent;
}
else
{
if (w->Right->color == false)
{
w->Left->color = false;
w->color = true;
rotateRight (w);
w = x->Parent->Right;
}
w->color = x->Parent->color;
x->Parent->color = false;
w->Right->color = false;
rotateLeft (x->Parent);
x = Root;
}
}
else
{
Node *w = x->Parent->Left;
if (w->color == true)
{
w->color = false;
x->Parent->color = true;
rotateRight (x->Parent);
w = x->Parent->Left;
}
if (w->Right->color == false && w->Left->color == false)
{
w->color = true;
x = x->Parent;
}
else
{
if (w->Left->color == false)
{
w->Right->color = false;
w->color = true;
rotateLeft (w);
w = x->Parent->Left;
}
w->color = x->Parent->color;
x->Parent->color = false;
w->Left->color = false;
rotateRight (x->Parent);
x = Root;
}
}
}
x->color = false;
}
Node *findNode(KeyType key)
{
Node *current = Root;
while(current != NULL)
if(key == current->key)
return (current);
else
current = (key < current->key) ?
current->Left : current->Right;
return(0);
}
public:
class Iterator
{
friend class RBTree;
private:
Node* node;
RBTree* t;
public:
bool isEnd;
bool isBeg;
Iterator(Node* a=NULL)
{
node = a;
t = NULL;
isEnd = false;
isBeg = false;
}
void inc()
{
if (node->Right!=NULL)
{
node = node->Right;
while (node->Left!=NULL)
{
node = node->Left;
}
}
else
{
while (node!=NULL && node->Parent!=NULL && node == node->Parent->Right)
{
node = node->Parent;
}
if (node->Parent!=NULL)
node = node->Parent;
else
{
node = NULL;
isEnd = true;
return ;
}
}
value() = node->value;
}
void dec()
{
if (isEnd)
{
node = t->Root;
while (node->Right!=NULL)
node = node->Right;
isEnd = false;
value() = node->value;
}
else
{
if (node->Left!=NULL)
{
node = node->Left;
while (node->Right!=NULL)
{
node = node->Right;
}
}
else
{
if (node==node->Parent->Right)
{
node = node->Parent;
}
else
{
if (node->Parent->Parent!=NULL && node->Parent->Parent->Right==node->Parent)
{
node = node->Parent;
while(node!=NULL && node->Parent!=NULL && node == node->Parent->Right)
node = node->Parent;
}
else
if (node->Parent!=NULL)
{
node = NULL;
isBeg = true;
return ;
}
}
}
value() = node->value;
//key() = node->key;
}
}
const KeyType& key() const
{
return node->key;
}
T& value()
{
return node->value;
}
bool operator==(Iterator& a)
{
if ((a.isEnd) && (isEnd))
return true;
else
{
if ((a.isEnd) && !(isEnd))
{
return false;
}
else
{
if (!(a.isEnd) && (isEnd))
return false;
else
return (key() == a.key());
}
}
}
bool operator!=(Iterator& a)
{
if ((a.isEnd) && (isEnd))
return false;
else
{
if ((a.isEnd) && !(isEnd))
{
return true;
}
else
{
if (!(a.isEnd) && (isEnd))
return true;
else
return (key() != a.key());
}
}
}
};
class constIterator
{
friend class RBTree;
private:
Node* node;
const RBTree* t;
public:
bool isEnd;
bool isBeg;
constIterator(Node* a=NULL)
{
node = a;
t = NULL;
isEnd = false;
isBeg = false;
}
void inc()
{
if (node->Right!=NULL)
{
node = node->Right;
while (node->Left!=NULL)
{
node = node->Left;
}
}
else
{
while (node!=NULL && node->Parent!=NULL && node == node->Parent->Right)
{
node = node->Parent;
}
if (node->Parent!=NULL)
node = node->Parent;
else
{
node = NULL;
isEnd = true;
return ;
}
}
//value() = node->value;
}
void dec()
{
if (isEnd)
{
node = t->Root;
while (node->Right!=NULL)
node = node->Right;
isEnd = false;
value() = node->value;
}
else
{
if (node->Left!=NULL)
{
node = node->Left;
while (node->Right!=NULL)
{
node = node->Right;
}
}
else
{
if (node==node->Parent->Right)
{
node = node->Parent;
}
else
{
if (node->Parent->Parent!=NULL && node->Parent->Parent->Right==node->Parent)
{
node = node->Parent;
while(node!=NULL && node->Parent!=NULL && node == node->Parent->Right)
node = node->Parent;
}
else
if (node->Parent!=NULL)
{
node = NULL;
isBeg = true;
return ;
}
}
}
value() = node->value;
//key() = node->key;
}
}
const KeyType& key() const
{
return node->key;
}
const T& value() const
{
return node->value;
}
bool operator==(constIterator& a)
{
if ((a.isEnd) && (isEnd))
return true;
else
{
if ((a.isEnd) && !(isEnd))
{
return false;
}
else
{
if (!(a.isEnd) && (isEnd))
return false;
else
return (key() == a.key());
}
}
}
bool operator!=(constIterator& a)
{
if ((a.isEnd) && (isEnd))
return false;
else
{
if ((a.isEnd) && !(isEnd))
{
return true;
}
else
{
if (!(a.isEnd) && (isEnd))
return true;
else
return (key() != a.key());
}
}
}
};
Node* Root;
void erase(Iterator it)
{
Node* t;
t = findNode(it.key());
if (t!=NULL)
deleteNode(t);
}
int count(KeyType k) const
{
if (findNode(k)==NULL)
return 0;
else
return 1;
}
int size() const
{
return _size;
}
bool empty() const
{
return (_size==0);
}
Iterator begin()
{
Node* tmp = Root;
if (tmp==NULL)
{
Iterator x(tmp);
x.isEnd = true;
x.t = this;
return x;
}
while (tmp->Left!=NULL)
tmp = tmp->Left;
Iterator x(tmp);
x.value() = tmp->value;
x.t = this;
return x;
}
Iterator end()
{
Node* tmp =NULL;
Iterator x(tmp);
x.isEnd = true;
return x;
}
constIterator begin() const
{
Node* tmp = this->Root;
if (tmp==NULL)
{
constIterator x(tmp);
x.isEnd = true;
x.t = this;
return x;
}
while (tmp->Left!=NULL)
tmp = tmp->Left;
constIterator x(tmp);
//x.value() = tmp->value;
x.t = this;
return x;
}
constIterator end() const
{
Node* tmp =NULL;
constIterator x(tmp);
x.isEnd = true;
return x;
}
Iterator rbegin()
{
Node* tmp = Root;
while (tmp->Right!=NULL)
tmp = tmp->Right;
Iterator x(tmp);
x.value = tmp->value;
return x;
}
Iterator rend()
{
Node* tmp = NULL;
Iterator x(tmp);
x.isBeg = true;
return x;
}
Iterator find(KeyType key)
{
Node* t = findNode(key);
if (t==NULL)
{
Iterator x(t);
x.isEnd = true;
return x;
}
else
{
Iterator x(t);
return x;
}
}
T& operator[](KeyType key)
{
Node* t;
if ((t=findNode(key))!=NULL)
return t->value;
else
{
return (insertNode(key, T()))->value;
}
}
RBTree()
{
_size = 0;
Root = NULL;
}
Node *insertNode(KeyType key, T value)
{
Node* f;
if ((f=findNode(key))!=NULL)
return f;
Node *current, *Parent, *x;
current = Root;
Parent = 0;
while (current != NULL)
{
if (key == current->key)
return (current);
Parent = current;
current = (key< current->key) ?
current->Left : current->Right;
}
x = new RBTree<KeyType, T>::Node;
_size++;
x->value = value;
x->key = key;
x->Parent = Parent;
x->Left = NULL;
x->Right = NULL;
x->color = true;
if(Parent!=NULL)
{
if(key<Parent->key)
Parent->Left = x;
else
Parent->Right = x;
}
else
{
Root = x;
}
insertFixup(x);
return(x);
}
void deleteNode(Node *z)
{
Node *x, *y;
if (z == NULL)
return;
if (z->Left == NULL || z->Right == NULL)
{
y = z;
}
else
{
y = z->Right;
while (y->Left != NULL) y = y->Left;
}
if (y->Left != NULL)
x = y->Left;
else
x = y->Right;
if (x!=NULL)
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 != z)
{
z->value = y->value;
x->key = y->key;
}
if ((y->color == false) && (x!=NULL))
deleteFixup (x);
_size--;
delete y;
}
~RBTree()
{
for (Iterator it = begin(); it!=end();)
{
KeyType k = it.key();
Node* t = findNode(k);
it.inc();
deleteNode(t);
}
}
};