红黑树本质上是一种二叉查找树,但它在二叉查找树的基础设额外添加了一个标记(颜色),同时具有一定的规则。这些规则使红黑树保证了一种平衡,插入、删除、查找最坏的时间复杂度都为。
红黑树是在1972年由Rudolf Bayer发明,当时被称为平衡树(symmetric binary B-trees)。后来在1978年被Leo J.Guibas和Robert Sedgewick修改为如今的“红黑树”。
红黑树的本质就是在节点上追加了一个表示颜色的操作信息。
enum Color{
RED,BLACK;
}
class BinaryTree<T>{
private T data;
private Node parent;
private Node left;
private Node right;
private Color color;
}
对于Node节点中的颜色标记也可以使用true或者false来实现。
红黑树特点
- 每个节点或者是黑色,或者是红色;
- 根节点必须是黑色;
- 每个叶子节点是黑色;
- Java实现的红黑树将使用null来代表空节点,因此遍历红黑树时将看不到黑色的叶子节点,反而看到每个叶子节点都是红色的;
- 如果一个节点是红色的,则它的子节点必须是黑色的;
- 从每个根到节点的路径上不会有连续两个的红色节点,但黑色节点是可以连续的。若给定黑色节点的个数N。每个最短路径是连续的
个黑色,树的高点为
;最长路径的情况为节点红黑相间,树的高度为
;
- 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点数量;
- 称为红黑树最主要的条件,后序的插入、删除操作都是为了遵守整个规定
红黑树基本结构
简单理解红黑树的结构就是为了可以进行左旋和右旋操作以保证树的平衡性。但是对于平衡性,还要考虑增加和删除数据的平衡。
数据插入处理
- 第一次插入,由于原树为空,所以只会违反红黑树的规则2,所以只要把根节点涂黑即可;
- 如果插入节点的父节点是黑色的,那不会违背红黑树的规则,什么也不需要做;但如果遇到如下三种情况时,就要开始变色和旋转了:
- 插入节点的父节点和其叔叔节点(祖父节点的另一个子节点)均为红色;
- - 插入节点的父节点是红色,叔叔节点是黑色,且插入节点是其父节点的左子节点。
- - 插入节点的父节点是红色,叔叔节点是黑色,且插入节点是其父节点的右子节点;
-
在红黑树进行修复处理中,它需要根据当前节点以及当前节点的父节点和叔叔节点之间的颜色来推断树是否需要进行修复处理。
数据删除平衡修复
- 删除操作后,如果当前节点是黑色的根节点,那么不用任何操作,因为并没有破坏树的平衡性,即没有违背红黑树的规则。
- 如果当前节点是红色的,说明刚刚移走的后记节点是黑色的,那么不管后继节点的父节点是啥颜色,只要将当前节点涂黑就可以了,红黑树的平衡性就可以恢复。
- 但是如果遇到以下四种情况,就需要通过变色或旋转来恢复红黑树的平衡了:
- 当前节点是黑色的,且兄弟节点是红色的(那么父节点和兄弟节点的子节点肯定是黑色的);
- 当前节点是黑色的,且兄弟节点是黑色的,且兄弟节点的两个子节点均为黑色的;
- 当前节点是黑色的,且兄弟节点是黑色的,且兄弟节点的左子节点是红色,右子节点是黑色的;
- 当前节点是黑色的,且兄弟节点是黑色的,且兄弟节点的右子节点是红色,左子节点任意颜色。
参考资料:
https://edu.aliyun.com/lesson_1012_9035#_9035