定义:自平衡二叉查找树,每个节点都带有颜色属性,颜色或红色或黑色。
运算限制:1节点是红色或黑色。2根节点是黑色。3每个叶节点(NIL节点,空节点)是黑色的。4每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)。5从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
基本概念:左旋就是把原节点摘下来,用原节点的右子节点替换原节点,原节点变成右子节点的左子节点,如果原右子节点存在左子节点,则把该左子节点当成原节点的右子节点。右旋就是把原节点摘下来,用原节点的左子节点替换原节点,原节点变成做左子节点的右子节点,如果原左子节点存在右子节点,则把该右子节点当成原节点的左子节点。右旋跟左旋一样,是左旋的逆过程。下面有图。
基本运算:
1,插入。
2,删除 。
3,查找,跟二叉树一样,省略
左旋与右旋
对x左旋得到右图,对y右旋得到左图
看代码,下面代码摘自jdk treemap 类,看解析部分就可以了,下面辅助代码的作用在解析中都说了。
public class RBTree<K, V> implements Tree<K, V> {
private Node<K, V> root;
private static final boolean RED = false;
private static final boolean BLACK = true;
private int size = 0;
private int modCount = 0;
@SuppressWarnings("unchecked")
public V put(K key,V value){
if (key == null) throw new NullPointerException();
//如果跟节点是空,就插入到跟节点
if (root == null){
root = new Node<>();
root.key = key;
root.value = value;
size = 1 ;
modCount ++ ;
return null;
}
//从根节点开始循环,找到插入节点的位置和它的父节点,这里跟二叉查找树是一样的,主要是下面自平衡部分,也就是红黑树优于查找树的原由
Node<K, V> current = root;
Node<K,V> parent;
Comparable<? super K> k = (Comparable<? super K>) key;
int comparaberResult ;
do {
parent = current;
comparaberResult = k.compareTo(current.key);
if (comparaberResult < 0)//小于向左找
current = current.leftChild;
else if (comparaberResult > 0)//大于向右找
current = current.rightChild;
else{
//已经存在这个key,修改key的值
current.value=value;
return value ;
}
//循环直到找到新节点要插入的位置,并找到父节点parent和插入规则comparaberResult
} while (current != null);
//走到这里表示上面的修改没进行,所以是插入新节点
Node<K,V> node = new Node<>();
node.key = key;
node.value = value;
node.parent = parent;
//根据比较结果,知道新节点是左子节点还是右子节点
if (comparaberResult < 0)