RBTree

红黑树保证最长路径不超过最短路径的2倍,因而近似平衡
1、每个节点,不是红色就是黑色
2、根节点是黑色
3、如果一个节点是红色的,则他的两个子节点是黑色的(没有连续的红节点)
4、每条路径上黑色节点数量相等
5、每个叶子节点都是黑的(这里的叶子节点指的是空节点)
当新插入节点是红色的,其父亲也是红色的,那么就知道了祖父是黑色的,所以叔叔的颜色比较重要
第一种:cur为红,p为红,g为黑,u存在且为红,则将p,u改为黑,g改为红,然后把g当成cur,继续向上调整。
第二种:cur为红,p为红,g为黑,u不存在/u为黑,p为g的左孩子,cur为p的左孩子,则进行右单旋;相反,p为g的右孩子,cur为p的右孩子,则进行左单旋;p,g变色--p变黑,g变红。
第三种:cur为红,p为红,g为黑,u不存在/u为黑,p为g的左孩子,cur为p的右孩子,则针对p做左单旋;相反,p为g的右孩子,cur为p的左孩子,则针对p做右单旋;然后转换为情况2
图1(第一种情况):

图2(RBTree左右双旋):

代码:

bool Insert(const K& key, const V& value)
{
if (_root == NULL)//如果根为空,创建一个根节点,把要插入的key给他,颜色置黑
{
_root = new Node(key, value);
_root->_col = BLACK;
return true;
}
Node* parent = NULL;//定义 parent为空
Node* cur = _root;
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->_right = cur;
cur->_parent = parent;
}
else
{
parent->_left = cur;
cur->_parent = parent;
}
return true;
//检查
//1、p为黑
//2、p为红,u为红
//3、p为红,u不存在,或者为黑
while (parent->_col == RED)//parent的颜色为黑就截止了
{
Node* grandfa = parent->_parent;
if (parent == grandfa->_left)
{
Node* uncle = grandfa->_right;
if (uncle && uncle->_col == RED)
{
parent->_col = uncle->_col = BLACK;
grandfa->_col = RED;
//继续向上调整
cur = grandfa;
parent = cur->_parent;
}
else//叔叔不存在或叔叔为黑
{
if (cur == parent->_right)
{
RotateL(parent);
}
RotateR(grandfa);
parent->_col = BLACK;
grandfa->_col = RED;
}
}
else//parent==grandfa->_right
{
Node* uncle = grandfa->_left;
if (uncle && uncle->_col == RED)
{
parent->_col = uncle->_col = BLACK;
grandfa->_col = RED;
cur = grandfa;
parent = cur->_parent;
}
else
{
if (cur == parent->_left)
{
RotateR(parent);
}
RotateL(grandfa);
parent->_col = BLACK;
grandfa->_col = RED;
}
}
}
_root->_col = BLACK;
return true;

}

void RotateR(Node* parent)
{
Node* subL = parnet->_left;
Node* subLR = subL->_right;
parent->_left = subLR;
if (subLR)
{
subLR->_parent = parent;
}
subL->_right = parent;
Node* ppNode = parent->_parent;
parent->_parent = subL;
if (ppNode == NULL)
{
_root = subL;
}
else
{
if (ppNode->_left == parent)
{
ppNode->_left = subL;
}
else
{
ppNode->_right = subL;
}
subL->_parent = ppNode;
}
_root->_parent = NULL;
}
void RotateL(Node* parent)//左单旋
{
Node* subR = parent->_right;
Node* subRL = subR->_left;//先定义两节点
parent->_right = subRL;//parent的右指向subRL
if (subRL)//subRL可能不会存在,也可能存在
{
subRL->_parent = parent;
}
subR->_left = parent;//subR的左指向parent
subR->_parent = parent->_parent;//subR的父亲就是parent的父亲了
Node* ppNode = parent->_parent;//定义ppNode节点为parent的父亲节点
parent->_parent = subR;//parent的父亲节点也就是subR
if (ppNode == NULL)//如果ppNode为空,
{
_root = subR;
subR->_parent = NULL;
}
else if (ppNode->_left == parent)
{
ppNode->_left = subR;
}
else
{
ppNode->_right = subR;
}
subR->_parent = ppNode;
}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
void _InOrder(Node* root)
{
if (root == NULL)
return;
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
bool IsBalance()//类似计算huffmannode,走一个加1
{
//检查
//1、根节点黑的
//2、每条路径上都有相同数量的黑节点,遇到黑节点加1,递归走每条路径
//3、需要一个数值来记录“从根节点到当前节点的黑节点的数量”
if (_root&&_root->_col == RED)
{
return false;
}
//如果是黑就继续走
int k = 0;
Node* cur = _root;
while (cur)
{
if (cur->_col == BLACK)
{
++k;
}
cur = cur->_left;
}
int blacknum = 0;
return  _IsBalance(_root,k,blacknum);
}
bool _IsBalance(Node* cur,const int k,int blacknum)
{
if (cur == NULL)
{
if (k != blacknum)
{
cout << "黑节点的数量不相等" << endl;
return false;
}
return true;//空树不违反规则
}
if (cur->_col == RED && cur->_parent->_col == RED)//连续红节点
{
cout << "存在连续的红节点" << cur->_key << endl;
return false;
}
if (cur->_col == BLACK)
{
++blacknum;
}


return _IsBalance(cur->_left, k,blacknum)
  &&_IsBalance(cur_ > _right, k, blacknum);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值