红黑树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;
}

posted on 2011-02-23 21:29  ltang  阅读(416)  评论(0编辑  收藏  举报

导航