1. 概念介绍
红黑树是一种自平衡二叉查找树,由于自平衡的特性,保证了最坏情况下在O(logn)时间复杂度内完成查找、增加、删除等操作,性能表现稳定。
在JDK中,TreeMap、TreeSet以及JDK1.8的HashMap底层都采用了红黑树。
2. 为什么需要红黑树
由于二叉查找树在节点值顺序排序时会退化为一个线性结构,树的高度为节点个数,此时查找时间复杂度会变为O(n)。为了解决这个缺陷,红黑树便诞生了。
3. 红黑树特点
- 每个节点非红即黑,黑色决定平衡,红色不决定平衡
- 根节点总是黑色的
- 每个叶子节点都是黑色的空节点(NIL节点,有时会不进行显示)
- 如果节点是红色的,则它的子节点必须是黑色的(反之不一定)。通常这条规则也叫不会有连续的红色节点,一个节点最多会有3个节点,中间是黑色节点,左右是红色节点。
- 从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)。每一层都只是有一个节点贡献了树高决定平衡性,也就是对应红黑树的黑色节点。
4. 红黑树结构实现
public class Node {
public Class<?> clazz;
public Integer value;
public Node parent;
public Node left;
public Node right;
// AVL 树所需属性
public int height;
// 红黑树所需属性
public Color color = Color.RED;
}
针对添加节点,进行平衡调整操作如下:
- 左倾染色
- 染色时根据当前节点的爷爷节点,找到当前节点的叔叔节点。
- 再把父节点染黑、叔叔节点染黑,爷爷节点染红。但爷爷节点染红是临时的,当平衡树高操作后会把根节点染黑。
-
右倾染色
-
左旋调衡
一次左旋
右旋+左旋
- 右旋
一次右旋
左旋+右旋