红黑树C++实现

参考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:

View Code
   
     
#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 ;
}

你可能感兴趣的:(C++)