红黑树简介
红黑二叉查找树背后的基本思想是标准的二叉查找树(完全由2-节点构成)和一些额外信息(替换3-节点)来表示2-3树中的节点分为两种类型:红链接将两个2-节点链接起来构成一个3-节点,黑链接则是2-3树中普通的节点。
红黑树的定义
红黑树的一种定义是含有红黑链接并且满足下列条件的二叉查找树:
- 红链接均为左链接;
- 没有任何一个节点同时和两条红链接相连;
- 该树是完美黑色平衡的,任意空链接到根节点的路径上的黑链接数量相同。
满足这样定义的红黑树和2-3树是一一对应的。
红黑树的性质
- 每个节点要么是红色,要么是黑色;
- 根节点永远是黑色的;
- 所有叶子节点都都是空节点,并且都是黑色的;
- 每个红色节点的两个子节点都是黑色,从每个叶子节点到根节点的路径上不会有两个连续的红节点;
- 从任意节点到其子树的中每个叶子节点的路径都包含相同数量的黑色节点。
红黑树的节点表示
private static final boolean RED = true;
private static final boolean BLACK = false;
private Node root; // 根节点
// 节点类型
private class Node {
private Key key; // 键
private Value val; // 节点的值
private Node left, right; // 指向左右节点的链接
private boolean color; // 父节点的颜色
private int size; // 节点数
public Node(Key key, Value val, boolean color, int size) {
this.key = key;
this.val = val;
this.color = color;
this.size = size;
}
红黑树的旋转
在实现某些操作时可能会出现红色右链接或者两条连续的红链接,因此在操作完成前需要对红黑树进行修复,使之符合红黑树的定义。这些修复操作主要有左旋转、右旋转和颜色转换。
左旋
只需要将两个键中较大者作为根节点(之前较小的是根节点)。将较大节点的左子节点链接到较小节点的右子节点,然后改变节点的颜色。
右旋
只需要将两个键中较小者作为根节点(之前较大的是根节点)。将较小节点的右子节点链接到较大节点的左子节点,然后改变节点的颜色。
改变颜色
红黑树的插入
向2-节点插入新键
向3-节点插入新键
向树底的3-节点插入新键
红黑树的插入操作小结
只要选择左旋转、右旋转、颜色转换3种简单操作,就可以保证插入节点后红黑树和2-3树的一一对应关系。
其变换规律如下:
- 如果右子节点是红色的,而左子节点是黑色的,进行左旋转;
- 如果左子节点是红色的且他的左子节点的左子节点也是红色的,进行右旋转;
- 如果左右子节点均为红色的,则进行颜色转换。
红黑树的删除
- 以排序二叉树的方法删除指定的节点;
- 进行树的旋转和颜色转换,使红黑树满足定义的要求。