参考CLRS第二版(ch 13)
#ifndef _C_RB_TREE_H_
#define _C_RB_TREE_H_
#define NULL 0
template < class KeyT, class DataT >
class RB_TREE{
public :
RB_TREE():root(NULL){}
void Insert(KeyT key, DataT data = NULL)
{
rb_nodes * node, * tmp;
node = root;
tmp = NULL;
while (node != NULL)
{
tmp = node;
if (key < node -> key)
node = node -> rb_left;
else if (key > node -> key)
node = node -> rb_right;
else
{
node -> data = data;
return ;
}
}
rb_nodes * newNode = new rb_nodes(key, data);
newNode -> rb_parent = tmp;
if (tmp == NULL)
root = newNode;
else
{
if (key < tmp -> key)
tmp -> rb_left = newNode;
else
tmp -> rb_right = newNode;
}
__rb_insert_fixup(newNode);
}
void Delete(KeyT key)
{
rb_nodes * node, * child, * parent;
Color color;
if ( ! (node = __rb_find_by_key(key))) return ;
if ( ! node -> rb_left ||! node -> rb_right)
{
if ( ! node -> rb_left)
child = node -> rb_right;
else
child = node -> rb_left;
parent = node -> rb_parent;
color = node -> rb_color;
if (child)
child -> rb_parent = parent;
if (parent)
{
if (parent -> rb_left == node)
parent -> rb_left = child;
else
parent -> rb_right = child;
}
else
root = child;
delete node;
}
else // find successor node
{
rb_nodes * old = node;
node = node -> rb_right;
while (node -> rb_left != NULL)
node = node -> rb_left;
child = node -> rb_right;
parent = node -> rb_parent;
color = node -> rb_color;
if (child)
child -> rb_parent = parent;
if (parent)
{
if (parent -> rb_left == node)
parent -> rb_left = child;
else
parent -> rb_right = child;
}
else
root = child;
if (node -> rb_parent == old)
parent = node;
node -> rb_parent = old -> rb_parent;
node -> rb_color = old -> rb_color;
node -> rb_right = old -> rb_right;
node -> rb_left = old -> rb_left;
if (old -> rb_parent)
{
if (old -> rb_parent -> rb_left == old)
old -> rb_parent -> rb_left = node;
else
old -> rb_parent -> rb_right = node;
}
else
root = node;
old -> rb_left -> rb_parent = node;
if (old -> rb_right)
old -> rb_right -> rb_parent = node;
delete old;
}
if (color == RB_BLACK)
__rb_delete_fixup(child, parent);
}
private :
enum Color{RB_RED,RB_BLACK};
class rb_nodes{
public :
rb_nodes(KeyT key, DataT data)
:rb_parent(NULL)
,rb_color(RB_RED)
,rb_left(NULL)
,rb_right(NULL)
{
this -> key = key;
this -> data = data;
}
rb_nodes * rb_parent;
Color rb_color;
rb_nodes * rb_left;
rb_nodes * rb_right;
KeyT key;
DataT data;
};
void __rb_rotate_left(rb_nodes * node)
{
rb_nodes * right = node -> rb_right;
if ((node -> rb_right = right -> rb_left) != NULL)
right -> rb_left -> rb_parent = node;
right -> rb_left = node;
if ((right -> rb_parent = node -> rb_parent) != NULL) // current node is not root
{
if (node == node -> rb_parent -> rb_left)
node -> rb_parent -> rb_left = right;
else
node -> rb_parent -> rb_right = right;
}
else
root = right;
node -> rb_parent = right;
}
void __rb_rotate_right(rb_nodes * node)
{
rb_nodes * left = node -> rb_left;
if ((node -> rb_left = left -> rb_right) != NULL)
left -> rb_right -> rb_parent = node;
left -> rb_right = node;
if ((left -> rb_parent = node -> rb_parent) != NULL)
{
if (node == node -> rb_parent -> rb_left)
node -> rb_parent -> rb_left = left;
else
node -> rb_parent -> rb_right = left;
}
else
root = left;
node -> rb_parent = left;
}
void __rb_insert_fixup(rb_nodes * node)
{
rb_nodes * parent, * gparent;
while ((parent = node -> rb_parent) && parent -> rb_color == RB_RED)
{
gparent = parent -> rb_parent;
if (parent == gparent -> rb_left)
{
rb_nodes * uncle = gparent -> rb_right;
if (uncle && uncle -> rb_color == RB_RED)
{
uncle -> rb_color = RB_BLACK;
parent -> rb_color = RB_BLACK;
gparent -> rb_color = RB_RED;
node = gparent;
continue ;
}
if (parent -> rb_right == node)
{
__rb_rotate_left(parent);
std::swap(parent, node);
}
parent -> rb_color = RB_BLACK;
gparent -> rb_color = RB_RED;
__rb_rotate_right(gparent);
}
else
{
rb_nodes * uncle = gparent -> rb_left;
if (uncle && uncle -> rb_color == RB_RED)
{
uncle -> rb_color = RB_BLACK;
parent -> rb_color = RB_BLACK;
gparent -> rb_color = RB_RED;
node = gparent;
continue ;
}
if (parent -> rb_left == node)
{
__rb_rotate_right(parent);
std::swap(parent, node);
}
parent -> rb_color = RB_BLACK;
gparent -> rb_color = RB_RED;
__rb_rotate_left(gparent);
}
}
root -> rb_color = RB_BLACK;
}
void __rb_delete_fixup(rb_nodes * node, rb_nodes * parent)
{
rb_nodes * other;
while (( ! node || node -> rb_color == RB_BLACK) && node != root)
{
if (parent -> rb_left == node)
{
other = parent -> rb_right;
if (other -> rb_color == RB_RED)
{
other -> rb_color = RB_BLACK;
parent -> rb_color = RB_RED;
__rb_rotate_left(parent);
other = parent -> rb_right;
}
if (( ! other -> rb_left || other -> rb_left -> rb_color == RB_BLACK)
&& ( ! other -> rb_right || other -> rb_right -> rb_color == RB_BLACK))
{
other -> rb_color = RB_RED;
node = parent;
parent = node -> rb_parent;
}
else
{
if ( ! other -> rb_right || other -> rb_right -> rb_color == RB_BLACK)
{
rb_nodes * tmp;
if ((tmp = other -> rb_left) != NULL)
tmp -> rb_color = RB_BLACK;
other -> rb_color = RB_RED;
__rb_rotate_right(other);
other = parent -> rb_right;
}
other -> rb_color = parent -> rb_color;
parent -> rb_color = RB_BLACK;
if (other -> rb_right)
other -> rb_right -> rb_color = RB_BLACK;
__rb_rotate_left(parent);
node = root;
break ;
}
}
else
{
other = parent -> rb_left;
if (other -> rb_color == RB_RED)
{
other -> rb_color = RB_BLACK;
parent -> rb_color = RB_RED;
__rb_rotate_right(parent);
other = parent -> rb_left;
}
if (( ! other -> rb_left || other -> rb_left -> rb_color == RB_BLACK)
&& ( ! other -> rb_right || other -> rb_right -> rb_color == RB_BLACK))
{
other -> rb_color = RB_RED;
node = parent;
parent = node -> rb_parent;
}
else
{
if ( ! other -> rb_left || other -> rb_left -> rb_color == RB_BLACK)
{
rb_nodes * tmp;
if ((tmp = other -> rb_right) != NULL)
tmp -> rb_color = RB_RED;
__rb_rotate_left(other);
other = parent -> rb_left;
}
other -> rb_color = parent -> rb_color;
parent -> rb_color = RB_BLACK;
if (other -> rb_left)
other -> rb_left -> rb_color = RB_BLACK;
__rb_rotate_right(parent);
node = root;
break ;
}
}
}
if (node)
node -> rb_color = RB_BLACK;
}
rb_nodes * __rb_find_by_key(KeyT key)
{
rb_nodes * node = root;
while (node)
{
if (key < node -> key)
node = node -> rb_left;
else if (key > node -> key)
node = node -> rb_right;
else
return node;
}
return NULL;
}
private :
rb_nodes * root;
};
#endif
Test:
#include " crbtree.h "
#include < iostream >
using namespace std;
int main()
{
RB_TREE < int , int > rbtree;
rbtree.Insert( 10 , 100 );
rbtree.Delete( 10 );
rbtree.Insert( 10 , 100 );
rbtree.Insert( 9 , 100 );
rbtree.Insert( 15 , 100 );
rbtree.Insert( 11 , 100 );
rbtree.Insert( 3 , 100 );
rbtree.Insert( 55 , 100 );
rbtree.Insert( 8 , 100 );
rbtree.Insert( 100 , 100 );
rbtree.Delete( 15 );
rbtree.Delete( 8 );
rbtree.Delete( 9 );
rbtree.Delete( 3 );
rbtree.Delete( 10 );
rbtree.Delete( 3 );
rbtree.Delete( 55 );
rbtree.Delete( 100 );
rbtree.Delete( 11 );
return 0 ;
}