根节点 最长路2*B和最短路B相差 黑结点个数。
非根节点分支,最长路和最短路,相差黑节点个数,
操作最少
【insert】
存在两种可能
多次变色直到到插入最多两次旋转【无黑高度增加】
多次变色直到树根变色【增加黑高度】
代码步骤描述
1默认插入红【保证黑高度增加仅在整棵树根节点变色】,空结点为标志黑【保证旋转判断】
2根节点-变黑--结束,否则3
3parent黑,直接红结束,否则4
4GPN同直线|GPN折线,parent红,G黑,[U红] ,PUG变色---子根继续,
5GPN同直线,parent红,G黑,[U黑/nil],旋转结束
6GPN折线,parent红,G黑,[U黑/nil] PN旋转-5
【delete】
简单删除或替换后删除变色【无黑高度减少】_简单删除或替换后逐步变色最多三次旋转【减少黑高度】
删除点A单子或无子则本身为删除点B,否则子支中序遍历的下一个作为替换点B,即替换点作为删除点B。
当前作为删除点的必定没有左子,那么后续为三种情况,无右子[红-nil 或黑-nil]或有右红子[黑-红]。
判断概述:
情况1,[红-nil]直接删除。无须再平衡。
情况2,[黑-nil]删除,需要再平衡。且父节点的另一支只有一个黑高度。
情况3,[黑-红]删除,红替换变为黑。无须再平衡。
删除和需要再平衡详的
一、实际删除点左右子支有无子情况分类讨论
1-1开始删除和判断再平衡的条件
1.待删除的左子为空,右存或为空,父节点调整。
1.1若黑-r红,直接删掉,右子红变色且替换,不需要再平衡。NO
1.2若红-nil,直接删掉,不需要再平衡。指向调整。NO
1.3若黑-nil,节点黑色需要再平衡。YES
2.待删除节点右子为空,左存在。【已经排除1中的nilnil】父节点调整。
待删除两边黑高度一样,因此待删除为黑-l红,删除替换换色,不需再平衡。NO
1-2先替换以满足可以执行1-1
3实际待删除左右皆有子。取右边的最接近删除值的替换当前点【即右边的最左,没有左子】,且采用被删除点的颜色。 详细
3.1 右边值紧邻且为右子的为s替换 ,parent为替换的s,child2为替换的右子树子根。
3.2被采用的不是紧邻的,查找,得到替换的s,s 的父parent,以及右子。
查询结束
删除/替换位置调整。调整后可以使用1-1条件。
--------------
二、再平衡实操:删除点为末尾的黑 或者 替换点为末尾的黑
balance初始为删除点或替换的位置n=nil 。左右均为空。p即平衡点
1 黑高度少的为左支
1.1s为同辈节点,必存在。
1.1.1若s红,逆时针旋,变色p s,当前分支黑高度均为减少。1.1.3
1.1.2若s黑,s左右均为黑/nil[防止红连续],s变红,p红变黑结束;p黑,子树向上继续。
1.1.3若s黑,左子红,右子黑/nil,左子红右小旋,左子红做S,原S做右子即可执行1.1.4的操作
1.1.4若s黑,右子红,左子随机,逆时针大旋,颜色替换。结束
1 黑高度少的为右支
上面操作镜像
pppp pppp pppp pppp pppp pppp pppp ppyy
struct rb_node *节点指针地址对齐原因低位为0
用户构造层
1自定义结构中包含rb所需的结点信息、定义rb哨兵指针结点。
2插入函数(自定义比较对象)-调用 rb入口函数、连接函数、颜色调整函数
__rb_insert(node, root, false, NULL, dummy_rotate);