red_black_tree.cpp
#include
#include
#include
#include
using namespace std;
namespace algo
{
/// @param TKey 节点键的类型
/// @param TValue 节点值的类型
template
class RBTree
{
public:
enum RBTreeNodeColor
{
BLACK,
RED
};
struct RBTreeNode
{
TKey Key;
TValue Value;
RBTreeNodeColor Color;
RBTreeNode *Parent;
RBTreeNode *Left;
RBTreeNode *Right;
inline bool IsValid() const
{
return (this != s_nil);
}
};
RBTree()
{
if(!s_nil)
{
s_nil = new RBTreeNode();
s_nil->Color = BLACK;
}
_root = s_nil;
}
~RBTree()
{
_RecursiveReleaseNode(_root);
}
bool Insert(TKey key,TValue value)
{
if(Search(key)->IsValid())
{
return false;
}
else
{
RBTreeNode *new_node = new RBTreeNode();
new_node->Key = key;
new_node->Value = value;
new_node->Color = RED;
new_node->Left = new_node->Right = s_nil;
_InsertAsNormalBSTree(new_node);
_InsertFixup(new_node);
return true;
}
}
bool Delete(TKey key)
{
RBTreeNode *z = Search(key);
if(z->IsValid())
{
RBTreeNode *y = NULL;
if(!z->Left->IsValid() || !z->Right->IsValid())
{
y = z;
}
else
{
y = _Successor(z);
}
RBTreeNode *x = (y->Left->IsValid() ? y->Left : y->Right);
x->Parent = y->Parent;
if(!y->Parent->IsValid())
{
_root = x;
}
else
{
if(y == y->Parent->Left)
{
y->Parent->Left = x;
}
else
{
y->Parent->Right = x;
}
}
if(y != z)
{
z->Key = y->Key;
z->Value = y->Value;
}
if(y->Color == BLACK)
{
_DeleteFixup(x);
}
delete y;
return true;
}
else
{
return false;
}
}
RBTreeNode * Search(TValue const &value)
{
RBTreeNode *node = _root;
while(node != s_nil && node->Value != value)
{
node = (value < node->Value ? node->Left : node->Right);
}
return node;
}
bool Empty()
{
return !(_root->IsValid());
}
void Display() const
{
_Display(_root);
}
private:
void _RecursiveReleaseNode(RBTreeNode *node)
{
if(node->IsValid())
{
_RecursiveReleaseNode(node->Left);
_RecursiveReleaseNode(node->Right);
delete node;
}
}
void _Display(RBTreeNode *node) const
{
if(node->IsValid())
{
cout << " node" << node->Value << "\t" << (node->Color == RED ? "red" : "black") << "\t" << endl;
if(node->Left->IsValid())
{
cout << " \node" << node->Value << "\t" << node->Left->Value << endl;
_Display(node->Left);
}
if(node->Right->IsValid())
{
cout << " \node" << node->Value << "\t" << node->Right->Value << endl;
_Display(node->Right);
}
}
}
void _InsertAsNormalBSTree(RBTreeNode *node)
{
if(!_root->IsValid())
{
_root = node;
_root->Left = _root->Right = _root->Parent = s_nil;
_root->Color = BLACK;
return;
}
RBTreeNode *current_node = _root;
while(true)
{
RBTreeNode *&next_node_pointer = (node->Key > current_node->Key ? current_node->Right : current_node->Left);
if(next_node_pointer->IsValid())
{
current_node = next_node_pointer;
}
else
{
node->Parent = current_node;
next_node_pointer = node;
break;
}
}
}
void _InsertFixup(RBTreeNode *node)
{
while(node->Parent->Color == RED)
{
bool parent_is_left_child_flag = (node->Parent == node->Parent->Parent->Left);
RBTreeNode *uncle = parent_is_left_child_flag ? node->Parent->Parent->Right : node->Parent->Parent->Left;
if(uncle->Color == RED)
{
//case 1
node->Parent->Color = BLACK;
uncle->Color = BLACK;
node->Parent->Parent->Color = RED;
node = node->Parent->Parent;
}
else
{
if(node == (parent_is_left_child_flag ? node->Parent->Right : node->Parent->Left))
{
//case 2
node = node->Parent;
parent_is_left_child_flag ? _LeftRotate(node) : _RightRotate(node);
}
//case 3
node->Parent->Color = BLACK;
node->Parent->Parent->Color = RED;
parent_is_left_child_flag ? _RightRotate(node->Parent->Parent) : _LeftRotate(node->Parent->Parent);
}
}
_root->Color = BLACK;
}
void _LeftRotate(RBTreeNode *node)
{
if(!(node->IsValid() && node->Right->IsValid()))
{
cout << "错误!\n" << endl;
return;
}
else
{
RBTreeNode *right_son = node->Right;
node->Right = right_son->Left;
if(right_son->Left->IsValid())
{
right_son->Left->Parent = node;
}
right_son->Parent = node->Parent;
if(!(node->Parent->IsValid()))
{
_root = right_son;
}
else
{
if(node == node->Parent->Left)
{
node->Parent->Left = right_son;
}
else
{
node->Parent->Right = right_son;
}
}
right_son->Left = node;
node->Parent = right_son;
}
}
void _RightRotate(RBTreeNode *node)
{
if(!(node->IsValid() && node->Left->IsValid()))
{
cout << "错误!\n" << endl;
return;
}
else
{
RBTreeNode *left_son = node->Left;
node->Left = left_son->Right;
if(left_son->Right->IsValid())
{
left_son->Right->Parent = node;
}
left_son->Parent = node->Parent;
if(!(node->Parent->IsValid()))
{
_root = left_son;
}
else
{
if(node == node->Parent->Left)
{
node->Parent->Left = left_son;
}
else
{
node->Parent->Right = left_son;
}
}
left_son->Right = node;
node->Parent = left_son;
}
}
void _DeleteFixup(RBTreeNode *x)
{
while(x != _root && x->Color == BLACK)
{
bool node_is_parent_left_child = (x == x->Parent->Left);
RBTreeNode *w = node_is_parent_left_child ? x->Parent->Right : x->Parent->Left;
if(w->Color == RED)
{
//case 1
w->Color = BLACK;
x->Parent->Color = RED;
_LeftRotate(x->Parent);
w = x->Parent->Right;
}
//case 2
if(w->Left->Color == BLACK && w->Right->Color == BLACK)
{
w->Color = RED;
x = x->Parent;
}
else
{
//case 3
if((node_is_parent_left_child ? w->Right->Color : w->Left->Color) == BLACK)
{
(node_is_parent_left_child ? w->Left->Color : w->Right->Color) = BLACK;
w->Color = RED;
node_is_parent_left_child ? _RightRotate(w) : _LeftRotate(w);
w = (node_is_parent_left_child ? x->Parent->Right : x->Parent->Left);
}
//case 4
w->Color = x->Parent->Color;
x->Parent->Color = BLACK;
(node_is_parent_left_child ? w->Right->Color : w->Left->Color) = BLACK;
node_is_parent_left_child ? _LeftRotate(x->Parent) : _RightRotate(x->Parent);
x = _root;
}
}
x->Color = BLACK;
}
RBTreeNode * _Successor(RBTreeNode *node)
{
if(node->Right->IsValid())
{
node = node->Right;
while(node->Left->IsValid())
{
node = node->Left;
}
return node;
}
else
{
RBTreeNode *y = node->Parent;
while(!y->IsValid() && node == y->Right)
{
node = y;
y = y->Parent;
}
return y;
}
}
RBTreeNode *_root;
static RBTreeNode *s_nil;
};
template
typename RBTree::RBTreeNode * RBTree::s_nil = NULL;
}
#include "red_black_tree.cpp"
using namespace std;
int main()
{
int init[] = {12,1,9,2,0,11,7,19,4,15,18,5,14,13,10,16,6,3,8,17};
algo::RBTree bst;
for(int i=0;i bst.Display();
getchar();
}
for(int i=0;i {
bst.Delete(init[i]);
bst.Display();
getchar();
}
return 0;
}
这里就只演示前15个节点的插入操作吧,实测无误(参考July的红黑树系列http://blog.csdn.net/v_july_v/article/details/6284050)。
至于删除就不演示了,源代码里有,只是并不是逆过程,读者可以自己试试。