数据结构:红黑树
满足五条性质:
1. 根节点一定是黑色
2. 叶节点一定是黑色空心
3. 节点非黑即红
4. 红色节点孩子节点一定是黑色的
即不会出现连续的红色节点
5. 任意一个节点到叶节点路径上黑色节点数量一样多
右旋操作:把节点旋转到左孩子的右孩子处,如果冲突了,原右孩子成为该节点的左孩子
1. 该节点和左孩子断开连接
2. 左孩子替代该节点位置
3. 左孩子的右节点成为原节点的左孩子
4. 原节点成为左孩子的右孩子
插入操作:插入操作主要可能破坏红色平衡,需要平衡红色
1. 按照二叉查找树的方式插入
2. 将插入的新节点染红
3. 如果其和parent节点都为红色,则需要双红修正
双红修正
情况1:uncle节点存在且为红色
1.parent和uncle都调整为黑色,grandparent调整为红色,node设置为grandparent
2. 检查当前node也就是grandparent是否为根节点,如果不是继续调整
情况2:uncle节点不存在或者为黑色
情况2.1:node为parent的左孩子
1.parent染黑,grandparent染红
2. grandparent右旋
情况2.2:node为parent的右孩子
1. node染黑,grandparent染红
2. parent左旋,grandparent右旋
删除操作:插入操作主要可能破坏黑路同平衡,需要平衡黑色
情况1:没有孩子
情况1.1:节点本身是红色
直接删除不会破坏黑路同
情况1.2:节点本身是黑色,先删除该节点,使得该节点变成双黑色,然后分情况
情况1.2.1:兄弟节点是黑色
情况1.2.1.1:兄弟节点至少有一个红孩子,标记p(parent),s(兄弟节点),r(红孩子)
当psr位置关系是LL(s是p的left,r是s的left)时:
1. r颜色改成s颜色,s颜色改成p颜色,p改成黑色
2. p右旋
3. 双黑变单黑
当psr位置关系是RR时:同LL,只是p右旋变左旋
当位置关系是LR时:
1. r颜色改成p颜色,p改黑色
2. s左旋,p右旋
3. 双黑变单黑
当位置关系是RL时:同LR,只是先s右旋再p左旋
情况1.2.1.2:兄弟节点全是黑孩子(包括叶空节点)
1. 兄弟变红
2. 双黑上移:遇到红节点或根节点变单黑
情况1.2.2:兄弟节点是红色
1. p,s变色
2. p朝双黑方向旋转
3. 保持双黑继续调整
情况2:只有左或右孩子
因为红黑数的“不红红”“黑路同”原则,情况2只能是这两种方式
那么只需要直接让孩子替代过去变黑。
情况3:左右孩子都有
找到直接前驱
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通