在讲红黑树之前首先要讲的是平衡二叉树
平衡树,即平衡二叉树(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
以上是取自百度百科的定义
它还有两个重要的特点:
1.每个节点的左子树一定比节点小
2.每个节点的右子树一定比节点大
而红黑树就是平衡二叉树的一种实现
红黑树具有以下几个性质:
1.根节点一定为黑色
2.从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点
3.每个红色节点的子节点一定为黑色
4.节点为黑色或红色
5.每个叶子节点(NIL节点、空节点)是黑色的
这里的例子用的是这个网站,讲的非常好
根据以上性质可以定义红黑树节点的插入
插入情景1:红黑树为空树
最简单的一种情景,直接把插入结点作为根结点就行,但注意,根据红黑树性质2:根节点是黑色。还需要把插入结点设为黑色。
处理:把插入结点作为根结点,并把结点设置为黑色。
插入情景2:插入结点的Key已存在
插入结点的Key已存在,既然红黑树总保持平衡,在插入前红黑树已经是平衡的,那么把插入结点设置为将要替代结点的颜色,再把结点的值更新就完成插入。
处理:
把I设为当前结点的颜色
更新当前结点的值为插入结点的值
插入情景3:插入结点的父结点为黑结点
由于插入的结点是红色的,当插入结点的黑色时,并不会影响红黑树的平衡,直接插入即可,无需做自平衡。
处理:直接插入。
插入情景4:插入结点的父结点为红结点
再次回想下红黑树的性质2:根结点是黑色。如果插入的父结点为红结点,那么该父结点不可能为根结点,所以插入结点总是存在祖父结点。这点很重要,因为后续的旋转操作肯定需要祖父结点的参与。
情景4又分为很多子情景,下面将进入重点部分,各位看官请留神了。
插入情景4.1:叔叔结点存在并且为红结点
从红黑树性质4可以,祖父结点肯定为黑结点,因为不可以同时存在两个相连的红结点。那么此时该插入子树的红黑层数的情况是:黑红红。显然最简单的处理方式是把其改为:红黑红。
处理:
将P和S设置为黑色
将PP设置为红色
把PP设置为当前插入结点
插入情景4.2.1:插入结点是其父结点的左子结点
处理:
将P设为黑色
将PP设为红色
对PP进行右旋
插入情景4.2.2:插入结点是其父结点的右子结点
这种情景显然可以转换为情景4.2.1,如图所示,不做过多说明了。
处理:
对P进行左旋
把P设置为插入结点,
得到情景4.2.1进行情景4.2.1的处理
插入情景4.3:叔叔结点不存在或为黑结点,并且插入结点的父亲结点是祖父结点的右子结点
该情景对应情景4.2,只是方向反转,不做过多说明了,直接看图。
插入情景4.3.1:插入结点是其父结点的右子结点
处理:
将P设为黑色
将PP设为红色
对PP进行左旋
插入情景4.3.2:插入结点是其父结点的右子结点
处理:
对P进行右旋
把P设置为插入结点,
得到情景4.3.1进行情景4.3.1的处理
以上即为所有的插入情况。