什么是红黑树?
红黑树是一种自平衡二叉查找树,和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。
特性
- 根节点是黑色。
- 节点不是红色就是黑色。
- 每个叶子节点都是黑色的空节点(NIL节点)。
- 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)。
- 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
- 默认新增的叶子节点是红色的。
如图
这是一个典型的红黑树结构。
规则修复
红黑树的插入和删除节点,有时会破坏红黑树的结构平衡,为了保证新的树结构满足红黑树的规则,需要进行修复。修复除了平衡二叉树的左旋和右旋外,增加了变色特点。
看一下整个红黑树的添加过程:
新节点的添加分为以下几种情况:
-
从无到有,即新增的是根节点 ( 15 ):
原树是空树,新节点默认是红色,此时只会违反特性1。
修改策略:直接把此结点该为黑色------ 注意根节点的父节点一定为null
-
新增的结点(8 或 24)的父结点(15)是黑色。
此时红黑树规则没有被破坏。
对策:什么也不做。
-
当前结点(N)的父结点(P)是红色且祖父结点(G)的另一个子结点(叔叔结点)是红色。
此时违反特性4, 出现两个红色节点相连。
对策:变色
将当前节点的父节点和叔叔节点涂黑,祖父结点涂红,把当前结点指向祖父节点,从新的当前节点重新开始。
此时 当前节点为 15 ,判断其父节点是否为NULL,如果是强行变色
-
当前结点(N)的父结点(P)是红色且祖父结点(G)的另一个子结点(叔叔结点)是黑色(NIL空节点默认是黑色),且当前节点是左子树,需要右旋:
此时分为两种情况:
4.1 当前节点(N)的父节点(P)在祖父(G)的左侧:
即N为P左子树,P为G的左子树
对策: P变黑,G变红,以G为支点右旋,指针停留在G。
4.2 当前节点(N)的父节点(P)在祖父(G)的右侧:
即N为P左子树,P为G的右子树
对策:以P为支点右旋,指针停留在P。
-
当前结点(N)的父结点(P)是红色且祖父结点(G)的另一个子结点(叔叔结点)是黑色(NIL空节点默认是黑色),且当前节点是右子树,需要左旋:
此时分为两种情况:
5.1 当前节点(N)的父节点(P)在祖父(G)的右侧:
即N为P右子树,P为G右子树
对策:G变红,P变黑,以G为支点左旋,指针停留在G。
5.2 当前节点(N)的父节点(P)在祖父(G)的左侧:
即N为P右子树,P为G左子树
对策:以P为支点左旋,指针停留在P。
此时N,P , G 满足 4.1 ,继续按照4.1右旋,一直循环检查当前节点(N),直到满足红黑树规则(不再赘述)。
参考文献:
教你透彻了解红黑树(修订版)
红黑树浅析