平衡二叉树之红黑树(Red-Black Tree)简介及Java实现
与其他平衡二叉树不同,红黑树的每个节点有个额外的位来存储节点的颜色(红色或者黑色)。这些颜色位保证了在树的插入和删除时能保持平衡。
尽管红黑树的平衡不是完美的,但是它也足够保证搜索的时间效率为$O(\log n)$。追踪节点的颜色仅仅需要每个节点多保存一位数据,因为它只有两种颜色。除此之外,它不保存任何其他信息,因此,它的内存使用和典型的二叉查找树差不多,并不会造成额外的内存占用。
红黑树依靠节点的颜色来调整树的平衡(这和AVL树使用平衡因子来判断类似,后面会具体描述),其对颜色的要求如下:
- 每个节点只能是红色或者黑色两种
- 根节点是黑色的(但是这个规则有时候也不提,因为根节点总是可以从红色变成黑色,但是反过来不一定,它对分析的影响很小)
- 所有的叶子节点(NIL)都是黑色的
- 如果一个节点是红色的,那么它所有的子节点都是黑色的
- 从给定的节点到它的后代叶子节点中包含的黑色节点数量是一样的
这里说一下红黑树的叶子节点是不包含任何信息的,这些叶子不需要在计算机内存中显式存在,使用空子指针就可以编码这个叶子节点。但是如果叶子确实是显式节点,它会简化了一些在红黑树上操作的算法。所以,为了节省执行时间,有时指向单个sentinel节点(而不是空指针)的指针执行所有叶节点的角色; 从内部节点到叶节点的所有引用然后指向sentinel节点。因此,通常也称红黑树的叶子节点为NIL节点(NIL Leaves,NIL是0的意思,暗指不包含任何信息)。

