红黑树

旋转
LEFT_ROTATE(T,x)
y = x.right
x.right = y.left
if y.left != T.nil
y.left.p= x
y.p = x.p
if x.p == T.nil
T.root = y
else if x == x.p.left
x.p.left = y
else x.p.right = y
y.left = x
x.p = y
插入
RB_INSERT(T,z)
y = T.til
x = T.root
while x != T.til
y = x
if z.key < x.key
x = x.left
else x = x.right
z.p = y
if y == T.nil
T.root = z
else if z.key < y.key
y.left = z
else y.right = z
z.left = T.nil
z.right = T.nil
RB_INSERT_FIXUP(T, x)
RB_INSERT_FIXUP(T,x)
while z.p.color == RED
if z.p == z.p.p.left
y = z.p.p.right
if y.color == RED
z.p.color = BLACK
z.p.p.color = RED
y.color = BLACK
else if z == z.p.right
z = z.p
LEFT_ROTATE(T,z)
esle
z.p.color = BLACK
z.p.p.color = RED
RIGHT_ROTATE(T,z)
else (same as then clause with right and left exchanged)
T.root.color = BLACK
情况1, z的叔节点y是红色的
情况2, z的叔节点y是黑色的,且z是一个右孩子节点
情况3, z的叔节点y是黑色的,且z是一个左孩子节点
情况2让z指向红色的z.p ,左旋到情况3, 在情况2和情况3 颜色不改变。 把z.p改成黑色。
删除
RB_TRANSPLANT(T, u, v)
if u.p = T.nil
T.root = v
else if u = u.p.left
u.p.left = v
else u.p.right = v
v.p = u.p
一颗二叉搜索树T中删除一个节点z的整个策略有三种基本情况
1,z没有孩子,那么简单删除它,并修改它的父节点,用Nil作为孩子来替换它
2,z只有一个孩子,那么将孩子提升为z的位置,并修改z的父节点,用z的孩子来替换z
3, 如果z有两个孩子,那么找z的后继y(一定是z的右子树中),并让y占据树中z的位置,z原来右子树部分成为y的新右子树,并且z的左子树成为y的新左子树
TREE_DELETE(T,z)
if z.left == NIL
TRANSPLANT(T, z, z.right)
else if z.right == NIL
TRANSPLANT(T, z, z.left)
else y = TREE_MINIMUM(z.right)
if y.p != z
TRANSPLANT(T, y, y.right)
y.right = z.right
y.right.p = y
TRANSPLANT(T, z, y)
y.left = z.left
y.left.p = y
TREE_MINIMUM(x)
while x.left != NIL
x = x.left
return x
RB_DELETE(T, z)
y = z
y.originalcolor = y.color
if z.left == T.nil
x = z.right
RB_TRANSPLANT(T,z,z.right)
else if z.right == T.nil
x = z.left
RB_TRANSPLANT(T, z, z.left)
else y = TREE_MINIMUM(z.right)
y.originalcolor = y.color
x = y.right
if y.p == z
x.p = y
else RB_TRANSPLANT(T, y, y.right)
y.right = z.right
y.right.p = y
RB_TRANSPLANT(T, z, y)
y.left = z.left
y.left. p = y
y.color = z.color
if y.originalcolor == Black
RB_DELETE_FIXUP(T, x)
如果Y 是黑色的,则会产生三个问题,可以通过RB_DELETE_FIXUP进行补救。
第一,如果y是原来的根结点。而y的一个红色的孩子成为新的根结点,这就违反了性质2
第二,如果x,和 x.p是红色的,则违反了性质4
第三,在树中移动y导致先前包含y的任何简单路径上黑结点个数少1,因此y的任何祖先不满足性质5
情况1, x的兄弟节点w是红色,因为 w必须是黑颜色,所有改变w和 x.p的颜色。然后对x.p进行一次左旋。 就会将情况1,转换为2,3,4处理。这些情况由W的子节点的颜色来区分。
情况2,x的兄弟节点为黑色,而且w的两个子节点都是黑色。因为w也是黑色的,所以从x和w上去掉一重黑色,使得x只有一重黑色,而w为红色。为了补偿从x和w去掉的一重黑色,在原来是红色或黑色的x.p
上新增一重额外的黑色。通过将x.p作为新的节点x来重复while循环。注意到,如果通过情况1 进入到情况2,则新节点x是红黑的,因为原来的x.p是红色的。因此新的节点x.color属性值c为红色。
情况3, x的兄弟节点w是黑色的,w的左孩子是红色的,右孩子是黑色的。交换w和左孩子的颜色,然后对w进行一次右旋。
情况4, x的兄弟节点w是黑色的,且w的右孩子是红色的。通过进行某些颜色修改,并对x.p进行一次左旋,可以去掉x的额外黑色,从而使他变成为单重黑色。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
2017-08-30 判断两个矩形相交以及求出相交的区域
2016-08-30 c++ comment
2016-08-30 C#使用StreamWriter类写入文件文件
2016-08-30 C#字符串操作大全
2016-08-30 c#FileStream文件读写(转)