TreeMap源码分析

/**

  • The comparator used to maintain order in this tree map, or
  • null if it uses the natural ordering of its keys.
  • @serial
    */
    //自然排序
    private final Comparator<? super K> comparator;
    //根节点
    private transient Entry<K,V> root;

    /**

  • The number of entries in the tree
    */
    //大小
    private transient int size = 0;

public TreeMap() {
comparator = null;
}

public V put(K key, V value) {
Entry<K,V> t = root;//红黑树的根节点
if (t == null) {
compare(key, key); // type (and possibly null) check

        root = new Entry<>(key, value, null);//构造根节点,root没有父节点,传入null
        size = 1;
        modCount++;
        return null;
    }
    int cmp;
    Entry<K,V> parent;  //定义节点
    // split comparator and comparable paths
    Comparator<? super K> cpr = comparator; //获得比较器
    if (cpr != null) {//定义了比较器,采用自定义比较器进行比较
        do {
            parent = t;//将红黑树根节点赋值给parent
            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);
    }
    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);
    }
    //创建新节点,并指定父点
    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;
}

/** From CLR */
private void fixAfterInsertion(Entry<K,V> x) {
    //加入的节点默认的颜色是红色
    x.color = RED;
    //情形1:新节点x是树的根节点,没有父节点不需要任何操作
    //情形2:新节点x的父节点颜色是黑色的,不需要操作
    while (x != null && x != root && x.parent.color == RED) {
        //情形3:新节点的父节点颜色是红色的
        //判断x的节点的父节点位置,是否属于左子节点
        if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
            //获取x节点的父节点的兄弟节点,上面语句已经判断出x节点的父节点为左子节点,所以直接取右子节点
            Entry<K,V> y = rightOf(parentOf(parentOf(x)));
            //判断是否x节点的父节点的兄弟节点为红色
            if (colorOf(y) == RED) {
                setColor(parentOf(x), BLACK);//x节点的父节点设置为黑色
                setColor(y, BLACK);//y节点的颜色设置为黑色
                setColor(parentOf(parentOf(x)), RED);//x的父节点的父节点设置为红色
                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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值