“test.cpp”
<strong><span style="font-size:18px;">#include<iostream>
using namespace std;
enum COLOUR
{
BLACK,
RED,
};
template<class K,class V>
struct RBTreeNode
{
K _key;
V _value;
COLOUR _col;
RBTreeNode<K,V>* _left;
RBTreeNode<K,V>* _right;
RBTreeNode<K,V>* _parent;
RBTreeNode(const K& key,const V& value)
:_key(key)
,_value(value)
,_col(RED)
,_left(NULL)
,_right(NULL)
,_parent(NULL)
{}
};
template<class K,class V>
class RBTree
{
typedef RBTreeNode<K,V> Node;
public:
RBTree()
:_root(NULL)
{}
bool Insert(const K& key,const V& value)
{
if(_root == NULL)
{
_root = new Node(key,value);
_root->_col = BLACK;
return true;
}
Node* cur = _root;
Node* parent = NULL;
while(cur)
{
if(cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else if(cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else
return false;
}
cur = new Node(key,value);
if(parent->_key > key)
{
parent->_left = cur;
cur->_parent = parent;
}
else
{
parent->_right = cur;
cur->_parent = parent;
}
//颜色调整
while(cur != _root && parent->_col == RED)
{
Node* grandfather = parent->_parent;
if(parent == grandfather->_left)
{
Node* uncle = grandfather->_right;
//第一种情况 uncle存在且为红色
if(uncle && uncle->_col == RED)
{
parent->_col = uncle->_col = BLACK;
grandfather->_col = RED;
cur = grandfather;
parent = cur->_parent;
}
//第二种和第三种情况
//uncle不存在/uncle存在且为黑色
else
{
//先处理第三种情况
if(cur == parent->_right)
{
//针对parent进行左单旋
_L_Roteta(parent);
swap(parent,cur);
}
//第三种情况处理升级后变成第二种情况
//和第二种情况一起处理
_R_Roteta(grandfather);
grandfather->_col = RED;
parent->_col = BLACK;
break;
}
}
else//parent == grandfather->_right
{
Node* uncle = grandfather->_left;
//第一种情况 uncle存在且为红
if(uncle && uncle->_col == RED)
{
parent->_col = uncle->_col = BLACK;
grandfather->_col = RED;
cur = grandfather;
parent = cur->_parent;
}
//第二种情况和第三种情况
//uncle不存在/uncle存在且为黑色
else
{
//先处理第三种情况
if(cur == parent->_left)
{
_R_Roteta(parent);
swap(parent,cur);
}
//第三种情况升级为第二种情况
//统一处理第二种情况
_L_Roteta(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
break;
}
}
}
_root->_col = BLACK;
return true;
}
void InOrder()
{
_InOrder(_root);
cout<<endl;
}
//判断一棵树是否是红黑树
bool IsBlance()
{
//空树也是一棵红黑树
if(_root == NULL)
return true;
//根节点的颜色是否是黑色
if(_root->_col != BLACK)
return false;
//计算其中一条路径黑色节点的个数
Node* cur = _root;
size_t blackcount = 0;
while(cur)
{
if(cur->_col == BLACK)
++blackcount;
cur = cur->_left;
}
size_t k = 0;
return _IsBlance(_root,k,blackcount);
}
protected:
bool _IsBlance(Node* root,size_t k,const size_t blackcount)
{
if(root == NULL)
return true;
//红黑树上不能有连续的两个红节点
if(root->_col == RED && root->_parent->_col == RED)
{
cout<<"连续的两个红节点"<<root->_key<<endl;
return false;
}
//计算当前路径下黑色节点的个数
if(root->_col == BLACK)
++k;
//每条路径下黑色节点的数目相同
if(root->_left == NULL && root->_right == NULL)
{
if(k != blackcount)
{
cout<<"黑色节点的数目不相同"<<root->_key<<endl;
return false;
}
}
return _IsBlance(root->_left,k,blackcount)\
&& _IsBlance(root->_right,k,blackcount);
}
void _InOrder(Node* root)
{
if(root == NULL)
{
return;
}
_InOrder(root->_left);
cout<<root->_key<<"("<<root->_col<<") ";
_InOrder(root->_right);
}
void _L_Roteta(Node* parent)
{
Node* ppNode = parent->_parent;
Node* subR = parent->_right;
Node* subRL = subR->_left;
parent->_right = subRL;
if(subRL)
subRL->_parent = parent;
subR->_left = parent;
parent->_parent = subR;
if(ppNode)
{
if(ppNode->_left == parent)
ppNode->_left = subR;
else
ppNode->_right = subR;
subR->_parent = ppNode;
}
else
{
_root = subR;
subR->_parent = NULL;
}
}
void _R_Roteta(Node* parent)
{
Node* ppNode = parent->_parent;
Node* subL = parent->_left;
Node* subLR = subL->_right;
parent->_left = subLR;
if(subLR)
subLR->_parent = parent;
subL->_right = parent;
parent->_parent = subL;
if(ppNode)
{
if(ppNode->_left == parent)
ppNode->_left = subL;
else
ppNode->_right = subL;
subL->_parent = ppNode;
}
else
{
_root = subL;
subL->_parent = NULL;
}
}
private:
Node* _root;
};
void test()
{
RBTree<int,int> rbt;
int arr[] = {16,3,7,11,9,26,18,14,15};
size_t size = sizeof(arr)/sizeof(arr[0]);
for(int i = 0;i < size;i++)
{
rbt.Insert(arr[i],i);
cout<<"Isblance? "<<rbt.IsBlance()<<endl;;
}
rbt.InOrder();
}
int main()
{
test();
return 0;
}</span></strong>