&
colorOf(rightOf(sib)) == BLACK) {
setColor(sib, RED);
x = parentOf(x);
} else {
if (colorOf(rightOf(sib)) == BLACK) {
setColor(leftOf(sib), BLACK);
setColor(sib, RED);
rotateRight(sib);
sib = rightOf(parentOf(x));
}
setColor(sib, colorOf(parentOf(x)));
setColor(parentOf(x), BLACK);
setColor(rightOf(sib), BLACK);
rotateLeft(parentOf(x));
x = root;
}
} else { // symmetric
Entry<K,V> sib = leftOf(parentOf(x));
if (colorOf(sib) == RED) {
setColor(sib, BLACK);
setColor(parentOf(x), RED);
rotateRight(parentOf(x));
sib = leftOf(parentOf(x));
}
if (colorOf(rightOf(sib)) == BLACK &&
colorOf(leftOf(sib)) == BLACK) {
setColor(sib, RED);
x = parentOf(x);
} else {
if (colorOf(leftOf(sib)) == BLACK) {
setColor(rightOf(sib), BLACK);
setColor(sib, RED);
rotateLeft(sib);
sib = leftOf(parentOf(x));
}
setColor(sib, colorOf(parentOf(x)));
setColor(parentOf(x), BLACK);
setColor(leftOf(sib), BLACK);
rotateRight(parentOf(x));
x = root;
}
}
}
setColor(x, BLACK);
}
说明:结构调整这部分有点复杂,回头再深入理解todo
6.6 寻找后继函数successor()解析
//寻找任意节点后继
static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) {
if (t == null)
return null;
//情况1:右孩子不为空,向后代遍历:找到右孩子中孙子最小的那个节点(不断寻找left,直至为空)
else if (t.right != null) {
Entry<K,V> p = t.right;
while (p.left != null)
p = p.left;
return p;
} else {
// 情况2:右孩子为空,向祖先遍历,当任意节点是它父亲的左孩子时,则该节点的父亲为t的后继
Entry<K,V> p = t.parent;
Entry<K,V> ch = t;
while (p != null && ch == p.right) {
ch = p;
p = p.parent;
}
return p;
}
}
寻找后继的算法说明: 对于任意k:
- 情况一:k的右孩子不为空,向后代遍历:找到右孩子的子孙子中辈分最低的左孩子(不断寻找left,直至为空)
- 情况二:key的右孩子为空,向祖先遍历:当任意节点是它父亲的左孩子时,则该节点的父亲为t的后继
右孩子不为空的后继寻找:
右孩子为空为空的后继寻找:
7 解惑:
1 TreeMap支持key自定义排序,而红黑树对key的固定的排序规则,两者如何兼容的?
- 支持key自定义排序:指通过自定义的排序器,计算出任意key相对其它key的大小关系
- 红黑树对key的固定的排序:指按照红黑树的数据结构(二叉排序树+红黑节点规则),来组织key的树状结构,其中二叉排序的大小关系是根据排序器的计算出来的
- 两者不冲突
|