数据结构Map之TreeMap分析

今天又看了一遍TreeMap的源码,发现其中很有意思,并调试看看它内部是怎么进行添加元素,又是怎么进行比较插入的元素,又是怎么定位新插入的元素(到底放到左子树还是右子树)

列子如下:

TestMap.java

public class TestMap {
    public static void main(String[] args){
        HashMap hashMap = new HashMap<>();
        testHashMap(hashMap);
        LinkedHashMap linkedHashMap = new LinkedHashMap<>();
        testLinkedHashMap(linkedHashMap);
        TreeMap treeMap = new TreeMap<>();
        testTreeMap(treeMap);

    }
    public static void testHashMap(HashMap hashMap){
        hashMap.put('c',3);
        hashMap.put('d',2);
        hashMap.put('a',1);
    }
    public static void testLinkedHashMap(LinkedHashMap linkedHashMap){
        linkedHashMap.put('e',4);
        linkedHashMap.put('f',5);
        linkedHashMap.put('h',10);
    }
    public static void testTreeMap(TreeMap treeMap){
        treeMap.put('x',20);
        treeMap.put('v',10);
        treeMap.put('y',30);
        treeMap.put('a',1);
        treeMap.put('z',50);
    }
}
我在红颜色字的地方设断点进行调试

我设计的数据结构如图:(画的有点丑见谅)

数据结构Map之TreeMap分析_第1张图片

先看看TreeMap中的put方法:

public V put(K key, V value) {
        Entry t = root;
        if (t == null) {
            compare(key, key); // type (and possibly null) check

            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
        int cmp;
        Entry parent;
        // split comparator and comparable paths
        Comparator cpr = comparator;
        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 {
            if (key == null)
                throw new NullPointerException();
            @SuppressWarnings("unchecked")
                Comparable k = (Comparable) 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 e = new Entry<>(key, value, parent);
        if (cmp < 0)
            parent.left = e;
        else
            parent.right = e;
        fixAfterInsertion(e);
        size++;
        modCount++;
        return null;
    }
开始单步调试:

1:第一次插入x-->20

首先将第一个插入的值当作root节点此时他的parent,left,right都为null;然后判断root是否为空如果为空的话新建一个Entry将x和20放进去,然后将它的parent置为null,放回null

2:第二次插入v-->10

第二次插入的元素t不为空他的指向是x-->20空间,然后拿当前的key=v与t.key进行比较,看一看谁大,很显然,cmp<0,t = t.left,此时t.left = null; 说明root节点没有左子树,这个元素可以直接插入到左子树中了,即parent.left = e;

3:第三次插入y -->30

同理,同第二次插入的一样,root节点没有右子树那么可以放心的插入到root的右子树中去了,即parent.right = e;

4:第四次插入a-->1

第四次插入的时候比较a 和 x的大小

发现cmp < 0,好了,发现t.left != null,继续循环直到子节点的子节点为null,发现root的左子树只有一个节点,那么parent指向了v-->10,因为t.left = null 所以可以放心的插入其左子树了

5:第五次插入z-->50

 同理可以得到,z被插入到了y的右子树了



你可能感兴趣的:(数据结构,java基础)