0
点赞
收藏
分享

微信扫一扫

Java数据结构-TreeMap


内部结构图

Java数据结构-TreeMap_红黑树

通常称之为红黑树(平衡二叉树)(红黑树(平衡二叉树)是一种特殊的排序二叉树)

实现原理

由于红黑树过于复杂,下诉实现原理只是排序二叉树的原理,红黑树以此类似。

TreeMap内部维护着一个​​Entry<K,V>​​对象,该对象包含五个属性,

K key;                   调用put方法的时候传的key
V value; 调用put方法的时候传的value
Entry<K,V> left = null; 左节点
Entry<K,V> right = null; 右节点
Entry<K,V> parent; 父节点
boolean color = BLACK; 节点颜色

当我们往TreeMap中put值时,第一个put的值会作为跟节点,往后put的值会拿put的key和根节点的key做比较,如果新key>根key,则拿新key和根节点的右节点做比较,如果小于,则又和左节点做比较,如果等于,则替换节点的值,直到节点为null,就把新的作为此节点,如此反复,就会形成图中的结构。

关于红黑树:这种排序二叉树在极端情况下(程序员本身插入的key就是有序的)(比如我们插入的key是abcdefg…)的时候,就有可能形成

Java数据结构-TreeMap_红黑树_02

这种链状引用,这个时候进行检索效率是非常低下的(类似于链状结构检索),所以为了解决这个问题,java中的TreeMap使用的是红黑树结构,红黑树具体实现原理过于复杂,涉及树的旋转之类。本文不诉,具体是当我们插入的是abcdefg这种本身就是有序的,形成的结构不是引用的,而是类似于

Java数据结构-TreeMap_红黑树_03

这种相对平衡的结构。这样检索的时候就相对较快。

特点

1.有序,顺序是根据插入的key的顺序来排的。

2.无法插入null的key

3.TreeMap通常比HashMap慢一点(树和哈希表的数据结构使然)

常用方法源码

put(K key, V value)

public V put(K key, V value) {
Entry<K,V> t = root;
if (t == null) {
compare(key, key); //检查key不能为null
root = new Entry<>(key, value, null);//第一次put的时候创建根节点
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
Comparator<? super K> 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();
Comparable<? super K> k = (Comparable<? super K>) key;
do {//递归比较新key是放入左节点还是右节点
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;
}

get(Object key)

public V get(Object key) {
Entry<K,V> p = getEntry(key);
return (p==null ? null : p.value);
}

final Entry<K,V> getEntry(Object key) {
// Offload comparator-based version for sake of performance
if (comparator != null)
return getEntryUsingComparator(key);
if (key == null)
throw new NullPointerException();
Comparable<? super K> k = (Comparable<? super K>) key;
Entry<K,V> p = root;
while (p != null) {//递归直到找到对应的元素
int cmp = k.compareTo(p.key);
if (cmp < 0)
p = p.left;
else if (cmp > 0)
p = p.right;
else
return p;
}
return null;
}



举报

相关推荐

0 条评论