
#include<iostream>
using namespace std;
enum Colour
{
RED,
BLACK
};
template<class K,class V>
struct RBTreeNode
{
RBTreeNode* _left;
RBTreeNode* _right;
RBTreeNode* _parent;
pair<K, V> _kv;
Colour _col;
RBTreeNode(const pair<K, V>& kv)
:_left(nullptr)
,_right(nullptr)
,_parent(nullptr)
,_kv(kv)
,_col(RED)
{
}
};


template<class K, class V>
class RBTree
{
typedef RBTreeNode<K, V> Node;
public:
RBTree()
:_root(nullptr)
{
}
..../insert...
private:
Node* _root;
}
bool Insert(const pair<K, V>& kv)
{
if (_root ==nullptr)
{
_root = new Node(kv);
_root->_col = BLACK;//根节点必须是黑色
return true;
}
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (cur->_kv.first<kv.first)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_kv.first > kv.first)
{
parent = cur;
cur = cur->_left;
}
else
{
return false;//不允许冗余
}
}
cur = new Node(kv);
cur->_col = RED; //如果添加的是黑色,则对整个树都有影响,红色只对一个子树的一个路径有影响
cur->_parent = parent;
if (parent->_kv.first<cur->_kv.first)
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
//1,叔叔存在且为红,变色往上继续处理;2,叔叔不存在或存在且为黑:旋转+变色
//若插入节点双亲的颜色是黑色便不需要处理
while (parent&&parent->_col==RED)
{
Node* grandf = parent->_parent;//根不能是黑色,那么必定有个黑色的父亲
if (grandf->_left==parent)
{
Node* uncle = grandf->_right;
if (uncle && uncle->_col == RED)
{
parent->_col = uncle->_col = BLACK;//每条路径上的黑色节点个数保持不变
grandf->_col = RED;
cur = grandf;//祖父变红以后迭代往上更新,看没有连续的红色
parent = cur->_parent;
}
else//叔不存在或黑 旋转变色
{
//祖父为节点进行右单旋或双旋
if (cur=parent->_left)
{
//右单旋
RotateR(grandf);
grandf->_col = RED;
parent->_col = BLACK;
}
else//先左旋 ,再右旋
{
RotateL(parent);
RotateR(grandf);
cur->_col = BLACK;
grandf->_col = RED;
}
break;
}
}
else//(grandf->_right==parent) 叔叔存在为红,或不存在为黑
{
Node* uncle = grandf->_left;
if (uncle && uncle->_col == RED)
{
parent->_col = uncle->_col = BLACK;
grandf->_col = RED;
cur = grandf;//祖父变红以后迭代往上更新,看没有连续的红色
parent = cur->_parent;
}
else
{
if (cur=parent->_right)//左单旋
{
RotateL(grandf);
parent->_col = BLACK;
grandf->_col = RED;
}
else//先右旋,再左旋
{
RotateR(parent);
RotateL(grandf);
cur->_col = BLACK;
grandf->_col = RED;
}
break;
}
}
}
_root->_col = BLACK;//当叔叔存在且为红,祖父就是根,上面变完色出来把祖父的颜色改为黑色。
return true;
}
bool IsRBTree()
{
return _IsRBTree(_root);//包一层,方便外面对象调用
}
bool _IsRBTree(Node* cur)
{
if (cur==nullptr)
{
return true;//空树也是红黑树
}
if (cur->_col==RED)
{
cout << "根节点不是黑色,不是红黑树" << endl;
return false;
}
int Benchmark = 0;//基准值
Node* countcur = cur;
while (countcur)
{
if (countcur->_col==BLACK)//每一条路径都和我基准值一样则满足每条路径的黑色个数相等
{
++Benchmark;
}
countcur = countcur->_left;//任选一条路径作为基准值。
}
int layer_black = 0;//递归调用再传一个参数:记录一下每一层到上面总共有的黑色节点个数,这样就方便很多了
return red_node_is_black(cur)&&
black_num_is_same(cur, layer_black, Benchmark);
}
bool red_node_is_black(Node* cur)//看红色节点孩子是不是黑色等于是看有没有连续的红色。
{
if (cur==nullptr)
{
return true;
}
if (cur->_col == RED && cur->_parent->_col != BLACK)
{
return false;//当前节点是红,那么必有双亲节点是黑色。
}
return red_node_is_black(cur->_left) &&
red_node_is_black(cur->_right);
}
bool black_num_is_same(Node* cur, int layer_black, int Benchmark)
{
if (cur==nullptr)
{
if (layer_black==Benchmark)//路径走完,与基准值比较
{
return true;
}
else
{
return false;
}
}
if (cur->_col==BLACK)
{
++layer_black;
}
return black_num_is_same(cur->_left, layer_black, Benchmark) &&
black_num_is_same(cur->_right, layer_black, Benchmark);
}
下一篇是,将红黑树改造成 map和set 的 底层,模板参数再度来袭,红黑树的迭代器…