1. 红黑树的定义
a. 二叉查找树,任何一个节点的左右子树的高度差不超过两倍
b. 根节点为黑色
c. 红色节点的父节点和子节点的颜色必须是黑色
d. 从任何一个叶节点到根节点的路径经过相同数目的黑色节点
2. 二叉树的调整,结构的调整和颜色的调整
a. 设置插入节点x的颜色为红色
b. 判断插入节点的父节点颜色为红色还是黑色
b.1 父节点的颜色为红色
继续判断父节点是否是左节点,下面按照父节点是左节点来的,如果父节点是右子节点,将插入节点通过右旋调整到父节点位置,父节点成为子节点。
b.1.1 父节点的兄弟节点为红色
调整方案:
需要继续向上调整,因为c节点的颜色为红色,需要判断c节点的父节点颜色是红色还是黑色
b.1.2 父节点的兄弟节点为黑色
b.1.2.1.1 如果当前节点是父节点的右子节点
调整方案
后面的同b.1.2.2
最终结果:
b.1.2.2 如果当前节点是父节点的左子节点
调整方案
b.2 父节点的颜色为黑色
不需要调整
java TreeSet 调整的代码如下:
private void fixAfterInsertion(Entry<K,V> x) { x.color = RED; while (x != null && x != root && x.parent.color == RED) { if (parentOf(x) == leftOf(parentOf(parentOf(x)))) { Entry<K,V> y = rightOf(parentOf(parentOf(x))); if (colorOf(y) == RED) { setColor(parentOf(x), BLACK); setColor(y, BLACK); setColor(parentOf(parentOf(x)), RED); x = parentOf(parentOf(x)); } else { if (x == rightOf(parentOf(x))) { x = parentOf(x); rotateLeft(x); } setColor(parentOf(x), BLACK); setColor(parentOf(parentOf(x)), RED); rotateRight(parentOf(parentOf(x))); } } else { Entry<K,V> y = leftOf(parentOf(parentOf(x))); if (colorOf(y) == RED) { setColor(parentOf(x), BLACK); setColor(y, BLACK); setColor(parentOf(parentOf(x)), RED); x = parentOf(parentOf(x)); } else { if (x == leftOf(parentOf(x))) { x = parentOf(x); rotateRight(x); } setColor(parentOf(x), BLACK); setColor(parentOf(parentOf(x)), RED); rotateLeft(parentOf(parentOf(x))); } } } root.color = BLACK; }