TreeMap put 操作分析

2020-02-18 16:25:41 浏览数 (3)

代码语言:javascript复制
 1 public V put(K key, V value) {
 2         //t 表示当前节点,记住这个很重要!先把TreeMap 的根节点root 的引用赋值给当前节点
 3         TreeMap.Entry<K,V> t = root;
 4         //如果当前节点为null ,即是空树,新增的KV 形成的节点就是根节点
 5         if (t == null) {
 6             //看似多此一举,实际上预检了Key 是否 可以比较
 7             compare(key, key); // type (and possibly null) check
 8             // 使用Kv 构造出新的Entry 对象,其中第三个参数就是parent ,根节点没有父亲节点
 9             root = new TreeMap.Entry<>(key, value, null);
10             size = 1;
11             modCount  ;
12             return null;
13         }
14         // cmp 用来接收比较结果
15         int cmp;
16         TreeMap.Entry<K,V> parent;
17         // split comparator and comparable paths
18         //构造方法中置入的外部比较器
19         Comparator<? super K> cpr = comparator;
20         // 重点步骤:根据二叉树的特性,找到新的节点插入的合适位置
21         if (cpr != null) {
22             //循环的目标:根据key 与当前节点key 不断地进行对比
23             do {
24                 //当前节点赋值个父亲节点,故从根节点开始遍历比较
25                 parent = t;
26                 //比较输入的参数的key和当前节点Key 的大小
27                 cmp = cpr.compare(key, t.key);
28                 //参数的key 更小,向左边走,把当前节点引用移动至它的左子节点上
29                 if (cmp < 0)
30                     t = t.left;
31                 //参数的key 更大,向右边走,把当前节点引用移动至它的右子节点上
32                 else if (cmp > 0)
33                     t = t.right;
34                 //如果相等,则会残忍的覆盖当前节点的Value 值,并返回更新的前的值
35                 else
36                     return t.setValue(value);
37             } while (t != null);
38         }
39         //在没有比较器的情况下,调用自然排序的Comparable 比较
40         else {
41             if (key == null)
42                 throw new NullPointerException();
43             @SuppressWarnings("unchecked")
44             Comparable<? super K> k = (Comparable<? super K>) key;
45             do {
46                 parent = t;
47                 cmp = k.compareTo(t.key);
48                 if (cmp < 0)
49                     t = t.left;
50                 else if (cmp > 0)
51                     t = t.right;
52                 else
53                     return t.setValue(value);
54             } while (t != null);
55         }
56         // 创建Entry 对象,并把parent 置入参数
57         TreeMap.Entry<K,V> e = new TreeMap.Entry<>(key, value, parent);
58         //新节点找到自己的位置,原本以为可以安顿下来----------
59         if (cmp < 0)
60             //如果比较结果小于0 ,则成为parent 的左孩子
61             parent.left = e;
62         else
63             //如果比较结果大于0 ,则成为parent 的右孩子
64             parent.right = e;
65         //还需要重新对这个节点进行着色,旋转操作,已达到平衡
66         fixAfterInsertion(e);
67         size  ;
68         modCount  ;
69         //成功插入新节点后,返回null
70         return null;
71     }

0 人点赞