zoukankan      html  css  js  c++  java
  • TreeMap 源码

    public class TreeSet<E>{
        
        private static final Object PRESENT = new Object();
        //1-1. 调用无参构造函数
        public TreeSet() {
            this(new TreeMap<E,Object>());
        }
        
        public TreeSet(Comparator<? super E> comparator) {
            this(new TreeMap<>(comparator));
        }
        
        public TreeSet(SortedSet<E> s) {
            this(s.comparator());
            addAll(s);
        }
        
        //实际调用的是TreeMap的put方法
        public boolean add(E e) {
            return m.put(e, PRESENT)==null;
        }
        
        
        //-------------以下是TreeMap的源码------------------
        
        private final Comparator<? super K> comparator;
        
        private transient Entry<K,V> root;
        
        private transient int size = 0;
        
        private transient int modCount = 0;
        
        
        
        //1-2.没有传入外部比较器,外部比较器为空,使用元素自己实现的内部比较器
        public TreeMap() {
            comparator = null;
        }
        
        public TreeMap(Comparator<? super K> comparator) {
            this.comparator = comparator;
        }
        
        //2-1.调用put方法 key=Student{id=1, name='lili'} value=PRESENT
        //3-1.添加第二个元素 key=Student{id=2, name='huahua'}
        //4-1.添加第三个元素 key=Student{id=3, name='xixi'}
        public V put(K key, V value) {
            //2-2.t = null
            //3-2. t= root=Student{id=1, name='lili'}
            //4-2. t= root=Student{id=1, name='lili'}
            Entry<K,V> t = root;
            if (t == null) {
                //2-3.进入compare方法 key=key=Student{id=1, name='lili'}
                //compare(key,key) 3种可能,要么>0的数,要么=0,要么<0的数
                compare(key, key); // type (and possibly null) check
    
                //2-4.给root赋值  root=Student{id=1, name='lili'}
                root = new Entry<>(key, value, null);
                size = 1;
                modCount++;
                //2-5.添加第一个元素结束
                return null;
            }
            int cmp;
            Entry<K,V> parent;
            // split comparator and comparable paths
            Comparator<? super K> cpr = comparator;
            
            //外部比较器除了compara方法参数是两个之外,其余都一样。
            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);
            }
            else {
                //3-3.TreeMap不能添加null
                if (key == null)
                    throw new NullPointerException();
                @SuppressWarnings("unchecked")
                    Comparable<? super K> k = (Comparable<? super K>) key;
                do {
                    //4-5.parent=Student{id=2, name='huahua'}
                    parent = t;
                    //3-4.当前元素=Student{id=2, name='huahua'}跟root=Student{id=1, name='lili'}比较
                    //4-3.当前元素=Student{id=3, name='xixi'}跟root=Student{id=1, name='lili'}比较
                    //4-6.当前元素=Student{id=3, name='xixi'}跟t=Student{id=2, name='huahua'}比较
                    cmp = k.compareTo(t.key);
                    if (cmp < 0)
                        //3-5.如果当前元素小,t=null
                        t = t.left;
                    else if (cmp > 0)
                        //3-6.当前元素>root,t=t.right=null
                        //4-4. 当前元素>root, t=t.right=Student{id=2, name='huahua'}
                        //4-7.当前元素>t,t=t.right=null
                        t = t.right;
                    else
                        //返回老值
                        return t.setValue(value);
                } while (t != null);
            }
            //3-7.创建当前元素Student{id=2, name='huahua'}的Entry实例
            //4-8.创建当前元素Student{id=3, name='xixi'}的Entry实例
            Entry<K,V> e = new Entry<>(key, value, parent);
            if (cmp < 0)
                //3-8.如果当前元素小,就放到root的左边
                parent.left = e;
            else
                //3-9.如果当前元素大,就放到root的右边
                //4-9.当前元素Student{id=3, name='xixi'}放到parentStudent{id=2, name='huahua'}的右边
                parent.right = e;
            //3-10. 红黑树的过程
            //4-10. 红黑树后改变形态,下一次root会变,以此类推
            fixAfterInsertion(e);
            size++;
            modCount++;
            return null;
        }
        
        //有外部比较器时用外部比较器,没有外部比较器用要插入的元素的内部比较器,并且实现compareTo方法
        final int compare(Object k1, Object k2) {
            return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
                : comparator.compare((K)k1, (K)k2);
        }
            
        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;
        }
        
        //------------内部类Entry的源码-------------------------
        
        public V setValue(V value) {
                V oldValue = this.value;
                this.value = value;
                return oldValue;
            }
        
    }
    萝莉身,御姐心。。。。。
  • 相关阅读:
    multimap-swap
    multimap-size
    multimap-rend
    CentOS的利手:“Screen”一个可以在多个进程之间多路复用一个物理终端的窗口管理器
    对TCP/IP网络协议的深入浅出归纳
    程序员的数学:汉诺塔递归与非递归求解
    多柱汉诺塔问题探究
    汉诺塔问题的递归实现(扩展)
    CentOS---网络配置详解
    VMWare虚拟机下CentOS 配置网络实现远程连接,提供Web访问
  • 原文地址:https://www.cnblogs.com/bentuzi/p/15164650.html
Copyright © 2011-2022 走看看