C++红黑树:插入与平衡操作详解
欢迎来到干货小仓库
奔跑吧,少年
1.红黑树的概念
红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或 Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。
2.红黑树性质
1. 每个结点不是红色就是黑色
2. 根节点是黑色的
3. 如果一个节点是红色的,则它的两个孩子结点是黑色的
4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点
5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)
3.AVL树 和 红黑树的区别
4.红黑树的插入
情况一:当插入的节点其父节点的颜色是黑色那就没问题
情况二: 当新插入节点其父节点是红色那就需要调整
①其uncle存在,且为红色(变色+继续向上更新)
②其uncle不存在(旋转+变色)
③其uncle存在且为黑(旋转+变色)
综合上面需要更新的情况总结:
红黑树插入这么更新关键看uncle
1、uncle存在且为红------ 策略:变色+继续往上更新
2、uncle不存在 ------策略:旋转+继续往上更新
3、uncle存在且为黑------策略:旋转+继续往上更新(这种情况由 第一种情况演变而来)
5.红黑树底层结构
enum COLOR
{
RED,
BLACK
};
template
struct RBTreeNode
{
pair _kv;
RBTreeNode* _left;
RBTreeNode* _right;
RBTreeNode* _parent;
COLOR _color;
RBTreeNode(const pair& kv)
:_kv(kv)
,_left(nullptr)
,_right(nullptr)
,_parent(nullptr)
,_color(COLOR::RED)
{ }
};
template
class RBTree
{
typedef RBTreeNode Node;
private:
Node* _root=nullptr;
};
6.插入逻辑代码
bool insert(const pair& kv)
{
//二叉搜索树的插入
if (_root == nullptr)
{
Node* newNode = new Node(kv);
_root = newNode;
_root->_color = BLACK;
return true;
}
Node* cur = _root;
Node* parent = nullptr;
while (cur)
{
if (cur->_kv.first > kv.first)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_kv.first _right;
}
else
return false;
}
cur = new Node(kv);
if (parent->_kv.first > cur->_kv.first)
{
parent->_left = cur;
}
else
{
parent->_right = cur;
}
cur->_parent = parent;
//调节颜色
while (parent && parent->_color == RED)
{
Node* grandfather = parent->_parent;
if (grandfather->_left == parent)
{
Node* uncle = grandfather->_right;
if (uncle && uncle->_color == RED)
{
//变色
parent->_color = uncle->_color = BLACK;
grandfather->_color = RED;
//继续向上处理
cur = grandfather;
parent = cur->_parent;
}
else //(uncle==nullptr || (uncle && uncle->_color==BLACK))
{
if (parent->_left == cur)
{
// g
// p
// c
RotateR(grandfather); //右旋
parent->_color = BLACK;
grandfather->_color = RED;
}
else if ( parent->_right == cur)
{
// g
// p
// c
RotateL(parent); //左旋
RotateR(grandfather); //右旋
cur->_color = BLACK;
grandfather->_color = RED;
}
else
assert(false);
break;
}
}
else //grandfather->_right == parent
{
Node* uncle = grandfather->_left;
if (uncle && uncle->_color == RED)
{
//变色
parent->_color = uncle->_color = BLACK;
grandfather->_color = RED;
//继续向上处理
cur = grandfather;
parent = cur->_parent;
}
else //uncle不存在/uncle存在且为黑
{
if ( parent->_right == cur)
{
// g
// p
// c
RotateL(grandfather); //左旋
grandfather->_color = RED;
parent->_color = BLACK;
}
else if (parent->_left == cur)
{
// g
// p
// c
RotateR(parent); //右旋
RotateL(grandfather); //左旋
cur->_color = BLACK;
grandfather->_color = RED;
}
else
assert(false);
break;
}
}
}
_root->_color = BLACK;
return true;
}
//左旋
void RotateL(Node* parent)
{
++rotateCount;
Node* cur = parent->_right;
Node* curLeft = cur->_left;
if (curLeft)
curLeft->_parent = parent;
parent->_right = curLeft;
Node* ppNode = parent->_parent;
parent->_parent = cur;
cur->_left = parent;
//修改cur的父亲
if (ppNode == nullptr)
{
cur->_parent = nullptr;
_root = cur;
}
else
{
if (ppNode->_left == parent)
ppNode->_left = cur;
else
ppNode->_right = cur;
cur->_parent = ppNode;
}
}
//右旋
void RotateR(Node* parent)
{
++rotateCount;
Node* cur = parent->_left;
Node* curRight = cur->_right;
parent->_left = curRight;
if (curRight)
curRight->_parent = parent;
Node* ppNode = parent->_parent;
parent->_parent = cur;
cur->_right = parent;
//修改cur的父亲
if (ppNode == nullptr)
{
_root = cur;
cur->_parent = nullptr;
}
else
{
if (ppNode->_left == parent)
ppNode->_left = cur;
else
ppNode->_right = cur;
cur->_parent = ppNode;
}
}
觉得不错的,大家可以点赞+收藏咯
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。









