性质
1)非红即黑;
2)根节点黑色;
3)叶子节点(NIL)黑色;
4)红色节点不能相连;
5)每个节点到叶子节点(树尾端,Java 中为 null 的结点)包含相同数量的黑色节点;
插入后保持黑色平衡规则
默认插入节点为红色,先根据key大小,从根节点开始比较,找到父节点
1)空树,直接插,变黑
2)key相同,替换
3)父为黑,则直接 插
4)父为红
4.1)叔为红,则父,叔变黑,爷爷变红,再以爷爷为当前节点观察;
4.2)叔为黑或无,当前节点的父在爷爷的左边
4.2.1)当前节点在父的左边,父变黑,爷爷变红,对爷爷节点进行右旋
4.2.2)当前节点在父的右边,对父节点进行左旋,得到4.2.1情况
4.3)叔为黑或无,当前节点的父在爷爷的右边
4.3.1)当前节点在父的右边,父变黑,爷爷变红,对爷爷节点进行左旋
4.3.2)当前节点在父的左边,对父节点进行右旋,得到4.3.1情况
删除操作
删除操作较为复杂,暂时不写入笔记,详情见:
https://blog.csdn.net/zzy520comzzy/category_9029851.html
中的删除篇
https://blog.csdn.net/weixin_39777213/article/details/111094251
好的,我先提前告诉你们一点提示,假如xp的右子树,也就是x替代节点的叔叔及其后代有红节点,那么我们把这个红节点拿到左子树这边,然后把它变成黑色不就行了吗,这样左边补充了一个黑色节点,右边黑色节点也不会变少,这样刚好满足红黑树的性质,哈哈,思路确实是这样,但是实现起来可不简单哦,且看我分析每一种情况,以及怎么变色旋转。
思路:首先我们可以这样去理解,假如替换节点是R,那么以R为根的子树是少一个黑色节点的,是违背红黑树的性质的,那么调整的目的就是从R的叔叔节点借一个红色节点过来,然后把这个红节点变成黑色,这样左右子树的黑节点就平衡了。还有一种情况,就是叔叔子树没有红节点,那没法借一个红节点过来,那我们可以把他的叔叔节点变成红色,这样左右子树就平衡了,但是这样带来一个新问题,就是R的父节点为根的子树比他的叔叔子树又少一个黑色节点,因此类比,我们进行自底向上的处理,把R的父节点当成替代节点,让该父节点的叔叔子树去接一个红节点,如果还借不到,继续向上处理(直至root)找兄弟借。