TreeMap中红黑树,put新元素后fixAfterInsertion方法解释

先了解下红黑树的特性:
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]
(4)如果一个节点是红色的,则它的子节点必须是黑色的。
(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。


java中TreeMap数据结构采用红黑树实现;put方法每次新加元素后,都要调用fixAfterInsertion重新维持红黑树的平衡


贴源码:
    private void fixAfterInsertion(Entry<K,V> x) {
        x.color = RED;


        while (x != null && x != root && x.parent.color == RED) {
            if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
                Entry<K,V> y = rightOf(parentOf(parentOf(x)));
                if (colorOf(y) == RED) {
                    setColor(parentOf(x), BLACK);
                    setColor(y, BLACK);
                    setColor(parentOf(parentOf(x)), RED);
                    x = parentOf(parentOf(x));
                } else {
                    if (x == rightOf(parentOf(x))) {
                        x = parentOf(x);
                        rotateLeft(x);
                    }
                    setColor(parentOf(x), BLACK);
                    setColor(parentOf(parentOf(x)), RED);
                    rotateRight(parentOf(parentOf(x)));
                }
            } else {
                Entry<K,V> y = leftOf(parentOf(parentOf(x)));
                if (colorOf(y) == RED) {
                    setColor(parentOf(x), BLACK);
                    setColor(y, BLACK);
                    setColor(parentOf(parentOf(x)), RED);
                    x = parentOf(parentOf(x));
                } else {
                    if (x == leftOf(parentOf(x))) {
                        x = parentOf(x);
                        rotateRight(x);
                    }
                    setColor(parentOf(x), BLACK);
                    setColor(parentOf(parentOf(x)), RED);
                    rotateLeft(parentOf(parentOf(x)));
                }
            }
        }
        root.color = BLACK;
    }


文子版解释上述代码(暂时没图,有需要可以自己在本子上画画)


新插入节点为红色
一、父节点是黑色,直接插入不需要重构
二、父节点是红色 (基准节点不是根节点)
1、父亲是祖父的左儿子
①叔叔(右)节点是红色:表示祖父节点必然是黑色。直接开始变色(父亲和叔叔变黑,祖父变红。把基准节点定位到祖父节点,重复这步操作)
②叔叔(右)节点是黑色:
check:该节点是父亲的右儿子,则执行左旋操作(该节点变为父亲,原父亲节点变为左儿子);此时基准节点变为他的原父亲节点,也就是左旋后新的左儿子(最左儿子)
父亲变黑,祖父变红;此时的情况是父亲黑、叔叔黑、祖父红。导致从祖父到叔叔的路径黑色节点变少1个,以祖父节点为基点来一个右旋
2、父亲是祖父的右儿子
①叔叔(左)节点是红色:表示祖父节点必然是黑色。职介开始变色(父亲和叔叔变黑,祖父变红。把基准节点定位到祖父节点,重复这步操作)
②叔叔(左)节点是黑色:
check: 该节点是父亲的左儿子,则执行右旋操作(该节点变为父亲,原父亲节点变为右儿子);此时基准节点变为他的原父亲节点,也就是右旋后新的右儿子(最右儿子)
父亲变黑,祖父变红;此时的情况是父亲黑,叔叔黑,祖父红。导致从祖父到叔叔的路径黑色节点少了1个,以祖父节点为基准来一个左旋

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值