zoukankan      html  css  js  c++  java
  • TreeMap数据结构(jdk8)

    TreeMap使用了红黑树的结构,看下源码,记录用。

        public V put(K key, V value) {
            Entry<K,V> t = root;
            //初始化
            if (t == null) {
                //key为null会报错,因此是保证key非null
                compare(key, key); // 
                //K-V 放到root
                root = new Entry<>(key, value, null);
                //实体的数量
                size = 1;
                //操作数
                modCount++;
                return null;
            }
            //比较结果
            int cmp;
            // 父节点
            Entry<K,V> parent;
            Comparator<? super K> cpr = comparator;
            //从root开始,用key和节点的key进行比较,小的找左树,大的找右树,相同就赋值然后返回。当t==null时,parent就是该节点父节点
            //使用自定义比较器
            if (cpr != null) {
                do {
                    parent = t;
                    cmp = cpr.compare(key, t.key);
                    if (cmp < 0)
                        t = t.left;
                    else if (cmp > 0)
                        t = t.right;
                    else
                        return t.setValue(value);
                } while (t != null);
            }
            //使用key的默认比较器
            else {
                if (key == null)
                    throw new NullPointerException();
                @SuppressWarnings("unchecked")
                    Comparable<? super K> k = (Comparable<? super K>) key;
                do {
                    parent = t;
                    cmp = k.compareTo(t.key);
                    if (cmp < 0)
                        t = t.left;
                    else if (cmp > 0)
                        t = t.right;
                    else
                        return t.setValue(value);
                } while (t != null);
            }
            //新节点e
            Entry<K,V> e = new Entry<>(key, value, parent);
            // 小的放在左儿子
            if (cmp < 0)
                parent.left = e;
            //其它放右儿子
            else
                parent.right = e;
            //修复树的平衡
            fixAfterInsertion(e);
            size++;
            modCount++;
            return null;
        }
    
        private void fixAfterInsertion(Entry<K,V> x) {
            //根据RBTREE要求,新插入节点为红色
            x.color = RED;
            //该节点不为null,不是root,且父节点为RED时开始修复平衡
            while (x != null && x != root && x.parent.color == RED) {
                //x的爸爸是 爷爷的左儿子
                if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
                    // y是爷爷的右儿子
                    Entry<K,V> y = rightOf(parentOf(parentOf(x)));
                    //如果y是红色的
                    if (colorOf(y) == RED) {
                        //把爷爷的左儿子置为黑色
                        setColor(parentOf(x), BLACK);
                        //把爷爷的右儿子置为黑色
                        setColor(y, BLACK);
                        //把爷爷置为黑色
                        setColor(parentOf(parentOf(x)), RED);
                        //把x变为爷爷
                        x = parentOf(parentOf(x));
                    //y是黑色的
                    } else {
                        //如果x是爸爸的右儿子
                        if (x == rightOf(parentOf(x))) {
                            //x设为爸爸
                            x = parentOf(x);
                            //左旋X
                            rotateLeft(x);
                        }
                        //把x的父亲设为黑色
                        setColor(parentOf(x), BLACK);
                        //把x的爷爷设为红色
                        setColor(parentOf(parentOf(x)), RED);
                        //右旋x的爷爷
                        rotateRight(parentOf(parentOf(x)));
                    }
                //爸爸是爷爷的右儿子
                } else {
                    //y是爷爷的左儿子
                    Entry<K,V> y = leftOf(parentOf(parentOf(x)));
                    //y是红色
                    if (colorOf(y) == RED) {
                        //x的父亲设为黑色
                        setColor(parentOf(x), BLACK);
                        //y设为黑色
                        setColor(y, BLACK);
                        //爷爷设为红色
                        setColor(parentOf(parentOf(x)), RED);
                        //x变为爷爷
                        x = parentOf(parentOf(x));
                    //y是黑色
                    } else {
                        //如果x是父亲的左儿子
                        if (x == leftOf(parentOf(x))) {
                            //x变为父亲
                            x = parentOf(x);
                            //右旋x
                            rotateRight(x);
                        }
                        //设置x父亲颜色为黑色
                        setColor(parentOf(x), BLACK);
                        //爷爷为红色
                        setColor(parentOf(parentOf(x)), RED);
                        //左旋爷爷
                        rotateLeft(parentOf(parentOf(x)));
                    }
                }
            }
            //根永远是黑色
            root.color = BLACK;
        }
    
    
    
  • 相关阅读:
    IOS 开发者账号 (team账号)
    我能否把一个开发者帐号下的app转移到另一个开发者帐号下面?
    Xcode清楚缓存、清理多余证书
    CABasiAnimation的变化属性
    CATransform3DMakeRotation注意
    绘图详解(转摘)
    iOS开发UI篇—核心动画(UIView封装动画)(转摘)
    iOS开发UI篇—核心动画(转场动画和组动画)(转摘)
    iOS开发UI篇—核心动画(关键帧动画)(转摘)
    iOS开发UI篇—核心动画(基础动画)
  • 原文地址:https://www.cnblogs.com/june777/p/11726105.html
Copyright © 2011-2022 走看看