一、红黑树的删除
红黑树的删除主要分为两大类:删除RED
节点和删除BLACK
节点两种
情况,无论是B树的删除或者是二叉搜索树的删除,其实它们的做法都是一样的,先找到删除节点的前驱或者后继节点,然后再删除叶子节点就可以了。所以红黑树的删除我们考虑的是删除叶子节点的情况。
1.删除RED节点
,直接删除即可,不用做任何调整,因为删除后还是一颗红黑树。
2.删除BLACK节点,分为3种
情况:
- 拥有
2个RED子节点
的BLACK
节点,例如25
。- 不可能被直接删除,因为会找它的
前驱
或后继子节点替代删除
,因此不用考虑这种情况。(在BST的remove中已经处理过了)
- 不可能被直接删除,因为会找它的
- 拥有
1个RED子节点
的BLACK
节点,例如46,76
。 BLACK叶子节点
,例如88
。
2.1 删除拥有1个RED子节点的BLACK节点
判定条件:删除指定节点(46)后,用以代替的子节点(50)是RED。
(这里的判断条件, 用以替代46的结点是RED结点(50), 也就是说当删除46, 76后, 替代它们的节点是50, 72, 都是红色的; 用来区别删除88的情况)
将替代的子节点染成BLACK即可保持红黑树的性质。
例如删除46和76。
2.2 删除的叶子节点是88
这种是最复杂的,88删除后会导致B树下溢,首先回顾一下B树下溢的解决办法,当它的兄弟节点有孩子时,那就借一个元素。
第一种情况:它的兄弟节点都至少有一个红色子节点。
举例:图1
- 删除88。
- 76
左旋转
,80右旋转
。 - 中心节点(78)
继承
parent的颜色(80)。 - 80旋转下去之后,染成
BLACK
, 成为独立的节点。 -
第二种情况:它的兄弟节点没有RED子节点
这里又要分三种情况:哈哈哈,好崩溃。
当删除的节点父节点是红色节点时:将兄弟节点染成RED
,父节点染成BLACK
即可修复红黑树性质。
当删除的节点父节点和兄弟节点是黑色节点时:会导致父节点也下溢,
这时只需要把父节点当做删除的节点处理即可,相当于递归调用。
当删除的节点父节点是黑色,兄弟节点是红色时:
- 如果兄弟节点是
RED
:- 兄弟节点染成
BLACK
,父节点染成RED
,进行旋转
。 - 于是又回到兄弟节点是
BLACK
的情况。
- 兄弟节点染成
AVL树 VS 红黑树
AVL树
平衡标准比较严格:每个左右子树的高度差不超过1
最大高度是 1.44 ∗ log2 n + 2 − 1.328(100W个节点,AVL树最大树高28)
搜索、添加、删除都是 O(logn) 复杂度,其中添加仅需O(1)次旋转调整、删除最多需要 O(logn)次旋转调整
红黑树
平衡标准比较宽松:没有一条路径会大于其他路径的2倍
最大高度是 2 ∗ log2(n + 1)( 100W个节点,红黑树最大树高40)
搜索、添加、删除都是 O(logn) 复杂度,其中添加、删除都仅需 O(1) 次旋转调整
◼ 搜索的次数远远大于插入和删除, 选择AVL树
◼ 搜索、插入、删除次数几乎差不多, 选择红黑树
所以它们最主要的区别就是:删除的时候AVL树所需要旋转的次数明显多于红黑树。
◼ 相对于AVL树来说,红黑树牺牲了部分平衡性以换取插入/删除操作时少量的旋转操作,整体来说性能要优于AVL树; 红黑树的平均统计性能优于AVL树,实际应用中更多选择使用红黑树