TreeMap使用了红黑树的结构,看下源码,记录用。
public V put(K key, V value) {
Entry<K,V> t = root;
//初始化
if (t == null) {
//key为null会报错,因此是保证key非null
compare(key, key); //
//K-V 放到root
root = new Entry<>(key, value, null);
//实体的数量
size = 1;
//操作数
modCount++;
return null;
}
//比较结果
int cmp;
// 父节点
Entry<K,V> parent;
Comparator<? super K> cpr = comparator;
//从root开始,用key和节点的key进行比较,小的找左树,大的找右树,相同就赋值然后返回。当t==null时,parent就是该节点父节点
//使用自定义比较器
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);
}
//使用key的默认比较器
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);
}
//新节点e
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;
}
private void fixAfterInsertion(Entry<K,V> x) {
//根据RBTREE要求,新插入节点为红色
x.color = RED;
//该节点不为null,不是root,且父节点为RED时开始修复平衡
while (x != null && x != root && x.parent.color == RED) {
//x的爸爸是 爷爷的左儿子
if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
// y是爷爷的右儿子
Entry<K,V> y = rightOf(parentOf(parentOf(x)));
//如果y是红色的
if (colorOf(y) == RED) {
//把爷爷的左儿子置为黑色
setColor(parentOf(x), BLACK);
//把爷爷的右儿子置为黑色
setColor(y, BLACK);
//把爷爷置为黑色
setColor(parentOf(parentOf(x)), RED);
//把x变为爷爷
x = parentOf(parentOf(x));
//y是黑色的
} else {
//如果x是爸爸的右儿子
if (x == rightOf(parentOf(x))) {
//x设为爸爸
x = parentOf(x);
//左旋X
rotateLeft(x);
}
//把x的父亲设为黑色
setColor(parentOf(x), BLACK);
//把x的爷爷设为红色
setColor(parentOf(parentOf(x)), RED);
//右旋x的爷爷
rotateRight(parentOf(parentOf(x)));
}
//爸爸是爷爷的右儿子
} else {
//y是爷爷的左儿子
Entry<K,V> y = leftOf(parentOf(parentOf(x)));
//y是红色
if (colorOf(y) == RED) {
//x的父亲设为黑色
setColor(parentOf(x), BLACK);
//y设为黑色
setColor(y, BLACK);
//爷爷设为红色
setColor(parentOf(parentOf(x)), RED);
//x变为爷爷
x = parentOf(parentOf(x));
//y是黑色
} else {
//如果x是父亲的左儿子
if (x == leftOf(parentOf(x))) {
//x变为父亲
x = parentOf(x);
//右旋x
rotateRight(x);
}
//设置x父亲颜色为黑色
setColor(parentOf(x), BLACK);
//爷爷为红色
setColor(parentOf(parentOf(x)), RED);
//左旋爷爷
rotateLeft(parentOf(parentOf(x)));
}
}
}
//根永远是黑色
root.color = BLACK;
}
原文:https://www.cnblogs.com/june777/p/11726105.html