Java基础-理解红黑树(删除)

上一篇文章讲解了 红黑树的插入操做  ,这篇讲解一下红黑树的删除操做。


在讲解红黑树删除以前,先简单回顾下二叉树的删除操做。post


若是如今有一个二叉树如上图所示,我须要删除66这个节点该怎么作最快呢?3d

首先分析一下66这个节点的特色,在66的右边子树中,全部的节点都是比66大的。因此要想最快完成删除操做,只须要在右边子树中,找出一个最小的来,替换掉66便可。而真正从树上被剔除的节点,则是右子树中最小节点的位置。如图:cdn


一样的思路,左边子树找出一个最大的替换也是能够的。固然若是被删除的节点自己左右两个子节点只有一个或者都没有值的话,那操做就更简单了,直接剔除便可。blog

下面开始分析红黑树的删除操做:get

红黑树删除操做以下:it

  1. 根据二叉树的删除操做,找到真正须要从树上剔除的节点。
  2. 若是须要剔除的节点为黑色,调整红黑树的平衡(调整步骤以下)。
那么调整平衡的时候,可能会遇到几种状况呢?其实不用说也应该知道,和插入操做的情形同样,理论上讲也是2种状况。

第一种状况,剔除节点(B)的兄弟节点(C)为红色(左下角为须要剔除的节点):io


这种状况咱们须要作的就是将兄弟节点(C)变为黑色,将父节点(A)变为红色,对父节点
class

进行右旋操做。将C的左子节点做为B的兄弟节点。
二叉树


直接删除B的话,会致使A左右两边黑色节点数不一致。形成红黑树失去平衡。最好的办法就是把A的右边也删除一个黑色节点。可是由于B的兄弟节点C是红色,因此不能直接对C进行变色操做。因此只能将AC的颜色互换,而后对A进行右旋操做。将C的左子节点赋给B,做为B的兄弟节点,而由于C是红节点,红黑树不能出现连续两个红节点,因此C的子节点必然是黑色。
lazyload

因此,通过一步调整,在不破换树平衡的状况下,咱们就能够为B找到黑色的兄弟节点了。

接下来的操做遵循状况二便可。

第二种状况,剔除节点(B)的兄弟节点(C)为黑色(左下角为须要剔除的节点):


这种状况的话,能够分为两种子状况讨论。

首先,C节点的两个子节点都为黑色。若是是这种状况的话,操做就更简单了,直接将C节点变为红色,而后以剔除节点(B)的父节点A进行迭代判断便可。此处为何要迭代呢?由于从A往下看他的左右两边虽然是平衡了,可是两个子分支都少了一个黑色节点,因此必然会致使树不平衡。若是A自己是红色的话,那直接将A改为黑色便可,若是A是黑色的话那就没办法了,只能以A为基准向上迭代判断。

而后若是C节点下面挂有红色节点该怎么办?(C节点不能直接变红)思路就是若是C节点下面挂有红色节点,咱们应该想办法把红色节点挪到左边去,让他代替B节点,这样就能够直接调整到位,不破坏树的平衡。具体调整步骤以下:


将D和A节点设置为黑色,将C节点设置为A原来的颜色,而后对A进行左旋操做便可。



因此其实理解一下的话,红黑树仍是很简单的。