TreeMap--put和delete
http://cmsblogs.com/?p=1013原文出处
put 操作,按照上面说的五种情况进行处理。
对于delete操作,首先找到替换节点,替换之后,再删除该节点。替换节点用的右分支最左边。它需要根据删除节点的兄弟节点进行旋转处理。
-
红黑树删除节点
针对于红黑树的增加节点而言,删除显得更加复杂,使原本就复杂的红黑树变得更加复杂。同时删除节点和增加节点一样,同样是找到删除的节点,删除之后调整红黑树。但是这里的删除节点并不是直接删除,而是通过走了“弯路”通过一种捷径来删除的:找到被删除的节点D的子节点C,用C来替代D,不是直接删除D,因为D被C替代了,直接删除C即可。所以这里就将删除父节点D的事情转变为了删除子节点C的事情,这样处理就将复杂的删除事件简单化了。子节点C的规则是:右分支最左边,或者 左分支最右边的。
红-黑二叉树删除节点,最大的麻烦是要保持 各分支黑色节点数目相等。 因为是删除,所以不用担心存在颜色冲突问题——插入才会引起颜色冲突。
红黑树删除节点同样会分成几种情况,这里是按照待删除节点有几个儿子的情况来进行分类:
1、没有儿子,即为叶结点。直接把父结点的对应儿子指针设为NULL,删除儿子结点就OK了。
2、只有一个儿子。那么把父结点的相应儿子指针指向儿子的独生子,删除儿子结点也OK了。
3、有两个儿子。这种情况比较复杂,但还是比较简单。上面提到过用子节点C替代代替待删除节点D,然后删除子节点C即可。
下面就论各种删除情况来进行图例讲解,但是在讲解之前请允许我再次啰嗦一句,请时刻牢记红黑树的5点规定:
1、每个节点都只能是红色或者黑色
2、根节点是黑色
3、每个叶节点(NIL节点,空节点)是黑色的。
4、如果一个结点是红的,则它两个子节点都是黑的。也就是说在一条路径上不能出现相邻的两个红色结点。
5、从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
(注:已经讲三遍了,再不记住我就怀疑你是否适合搞IT了 O(∩_∩)O~)
诚然,既然删除节点比较复杂,那么在这里我们就约定一下规则:
1、下面要讲解的删除节点一定是实际要删除节点的后继节点(N),如前面提到的C。
2、下面提到的删除节点的树都是如下结构,该结构所选取的节点是待删除节点的右树的最左边子节点。这里我们规定真实删除节点为N、父节点为P、兄弟节点为W兄弟节点的两个子节点为X1、X2。如下图(2.1)。
-
现在我们就上面提到的三种情况进行分析、处理。
情况一、无子节点(红色节点)
这种情况对该节点直接删除即可,不会影响树的结构。因为该节点为叶子节点它不可能存在子节点—–如子节点为黑,则违反黑节点数原则(规定5),为红,则违反“颜色”原则(规定4)。 如上图(2.2)。
情况二、有一个子节点
这种情况处理也是非常简单的,用子节点替代待删除节点,然后删除子节点即可。如上图(2.3)
情况三、有两个子节点
这种情况可能会稍微有点儿复杂。它需要找到一个替代待删除节点(N)来替代它,然后删除N即可。它主要分为四种情况。
1、N的兄弟节点W为红色
2、N的兄弟w是黑色的,且w的俩个孩子都是黑色的。
3、N的兄弟w是黑色的,w的左孩子是红色,w的右孩子是黑色。
4、N的兄弟w是黑色的,且w的右孩子时红色的。
情况3.1、N的兄弟节点W为红色
W为红色,那么其子节点X1、X2必定全部为黑色,父节点P也为黑色。处理策略是:改变W、P的颜色,然后进行一次左旋转。这样处理就可以使得红黑性质得以继续保持。N的新兄弟new w是旋转之前w的某个孩子,为黑色。这样处理后将情况3.1、转变为3.2、3.3、3.4中的一种。如下:
-
情况3.2、N的兄弟w是黑色的,且w的俩个孩子都是黑色的。
-
这种情况其父节点可红可黑,由于W为黑色,这样导致N子树相对于其兄弟W子树少一个黑色节点,这时我们可以将W置为红色。这样,N子树与W子树黑色节点一致,保持了平衡。如下
-
将W由黑转变为红,这样就会导致新节点new N相对于它的兄弟节点会少一个黑色节点。但是如果new x为红色,我们直接将new x转变为黑色,保持整棵树的平衡。否则情况3.2 会转变为情况3.1、3.3、3.4中的一种。
-
情况3.3、N的兄弟w是黑色的,w的左孩子是红色,w的右孩子是黑色。
-
针对这种情况是将节点W和其左子节点进行颜色交换,然后对W进行右旋转处理。
-
此时N的新兄弟X1(new w)是一个有红色右孩子的黑结点,于是将情况3转化为情况4.
-
情况3.4、N的兄弟w是黑色的,且w的右孩子时红色的。
-
交换W和父节点P的颜色,同时对P进行左旋转操作。这样就把左边缺失的黑色节点给补回来了。同时将W的右子节点X2置黑。这样左右都达到了平衡。
-
总结
-
个人认为这四种情况比较难理解,首先他们都不是单一的某种情况,他们之间是可以进行互转的。相对于其他的几种情况,情况3.2比较好理解,仅仅只是一个颜色的转变,通过减少右子树的一个黑色节点使之保持平衡,同时将不平衡点上移至N与W的父节点,然后进行下一轮迭代。情况3.1,是将W旋转将其转成情况2、3、4情况进行处理。而情况3.3通过转变后可以化成情况3.4来进行处理,从这里可以看出情况3.4应该最终结。情况3.4、右子节点为红色节点,那么将缺失的黑色节点交由给右子节点,通过旋转达到平衡。
-
通过上面的分析,我们已经初步了解了红黑树的删除节点情况,相对于增加节点而言它确实是选的较为复杂。下面我将看到在Java TreeMap中是如何实现红黑树删除的。
排序,无参构造函数用的是key自带的compare方法,比如说如果key是int类型,String类型,就用其自带的。当然你也可以自己实现比较器,它提供了一个带比较器的构造函数。
浙公网安备 33010602011771号