先是普通二叉树的删除
在右子树中找到它右子树中最小的那个节点A,将要删除的节点的值和A互换,现在的问题就是删除这个A节点
根据红黑树的性质,A的颜色有红黑两种可能,分三种情况讨论,只需要处理第三种(注意因为A是根节点右子树中最小的节点,那么A就不可能有左子节点)
1、如果A是红色节点,那么没有(非nil的)子节点(因为此时A是不可能有左子节点的,所以只有可能有右子节点,
右子节点如果是黑色会让以A为根节点的子树左右不平衡,右子节点如果是红色会使得A和A的右子节点是两个连续的红色),可以直接删除。
2、如果A是黑色节点,如果有右子节点,右子节点一定是红色,那么删除A,右子节点替换到A的位置,红色变为黑色。
3、如果A是黑色节点且没有子节点。那么要删除这个黑色节点,就会出现黑色数目不一致的情况。
可以这样解决:
x方案:如果在A和A的父节点之间增加一个黑色节点(实际是通过旋转得到),A就可以直接删除。
y方案:如果把A的兄弟节点D(需为黑色节点)在允许的情况下(D的两个子节点都是黑色)变红,再把A的父节点看做A来接着调整平衡性,A同样可以直接删除(其实就是先保证删除A之后,A的父节点左右平衡了,只不过根节点左右不平衡,而这种不平衡在最极端的情况下上传给根节点,根节点时没有父节点的,问题直接就解决了)。
根据这两个思路,考虑到A面临的所有情况,都可以往这两种情况上转化。
A现在面临四种情况:
1、A的兄弟节点D为黑色,B的右子节点E为红色(左子节点不管是不是黑色,不重要),那么可以旋转A的父节点B的这棵树,交换B和D的颜色,涂黑E,进入x
2、A的兄弟节点D为黑色,B的右子节点E为黑色,但是左子节点C为红色,那么右旋D,交换D和C的颜色,进入1
3、A的兄弟节点D为黑色,B的两个子节点都是黑色,进入y
4、A的兄弟节点D为红色,那么B的两个子节点都为黑色,那么左旋A的父节点D,进入3