前言

首先我们需要二叉搜索树的主要优点:可以快速查找特定key值的节点可以进快速进行删除和查找工作,
但同样二叉排序树也并非十全十美,比如连续插入一串有序的值的时候,如图:
image.png
如上图所示,我们得到的二叉树是十分不均匀的,一个好的二叉树必须满足均匀分布的特点,故此我们把这类树称为不平衡树,对于平衡树而言,插入/查找等操作时的效率围殴O(logN),但对于一个非平衡树而言,我们相当于重新编写了一个链表,效率就变为了O(N)
故此为了保证平衡树的实现,我们引入了AVL树和红黑树

红黑树

我常听过这样一句话“当面试官问你红黑树时,你基本已经挂了”,所以为了稍微稍微防止下这种情况,我们还是需要了解下红黑树的原理(代码就算了)

红黑树基本规则

  • 节点是红色或黑色的
  • 根节点是黑色
  • 每个叶子结点都是黑色的空结点(NIL节点)
  • 每个红色节点的两个儿子节点都是黑色节点(故此每个叶子到根的路径上不能有两个连续的红色节点)
  • 从任意结点到每个叶子的所有路径都包含相同数目的黑色结点

这些规则的约束就可以构成红黑树的关键特性(相对平衡)

  • 从根到叶子的最长可能路径,不会超过最短可能路径的两倍
  • 这个树是一个平衡树,且高效

红黑树的变换

当我们插入一个新节点时,有可能不变的不再平衡,可以通过三种方式的转换将其变得平衡

  • 变色
  • 左旋转
  • 右旋转

    变色

    image.png
    简单来说就是把红色变为黑色,把黑色变为红色(一头雾水)
    首先我们需要知道,我们插入时往往插入的时红色节点,原因是:

  • 插入一次红色结点大概率是不会违反红黑树规则的

  • 插入黑色结点的话,就会导致多了黑色结点,很难调整
  • 红色结点可能出现红红相连的情况,这种情况下需要变色和旋转

image.png

旋转

  • 左旋转

逆转红黑树的两个结点,使得父节点被自己的右孩子代替,而自己变成了左孩子
image.png

  • 右旋转

逆转红黑树的两个结点,使得父节点被自己的左孩子代替,而自己变成了右孩子
image.png

旋转后原分支的叶子结点大部分情况下都是通过平移解决,且旋转后原子树不会受到影响

红黑树的插入

接下来我们讨论红黑树的插入的情况,设要插入的结点为N,其父节点为P,其祖父结点为G,其父亲的兄弟结点为U
image.png
由上文可知,我们默认插入的结点为红色结点

情况一

新节点位于红黑树的根上,没有父节点,这样只需把N结点变为黑色即可(自黑

情况二

新节点的父节点为黑色结点,尽管新节点有两个黑色的NIL结点,但其为红色结点,所以路径中黑色结点的个数依然相同,满足性质(父黑

情况三

image.png
新节点为红色左子结点,其父节点也为红色结点,其叔叔结点也为红色结点,故此祖父结点肯定为黑色结点(父红叔红祖黑自为左孩
解决
我们要做的操作就是将P和U结点变为黑色结点,G结点变为红色结点,这样一来新节点N有一个黑色父亲结点P,所以每条路径上的黑色结点数目没有变,而从更高路径向下看,都会经过G点,故此路径上的黑色结点数目也满足性质(父黑叔黑祖变红
问题:
如果G结点的父亲结点为红色的话,就不满足性质,此时可以通过递归来调整颜色,但是到了根节点,就得通过旋转来解决问题,这个之后再说

情况四

image.png
P结点为红色结点,U结点为黑色结点,G结点为黑色结点,N为左孩子(父红叔黑祖黑自为左孩
解决
G结点进行右旋转,旋转后以前的父节点P变成了以前祖父结点G的父结点,交换P结点和G结点的颜色,
B结点向右平移,变成G的左子结点(父黑组红右旋转),但是最好先变色后旋转

情况五

image.png
P为红色结点,U为黑色结点,G为黑色结点,N为右孩子(父红叔黑祖红自为右孩
解决:
对P进行左旋转,形成情况四,再对G进行一次右旋转,再变色(父左组右再变色

红黑树插入案例

案例:有1 2 3 4 5 6 7 8 9 10,依次插入10 9 8 7 6 5 4 3 2 1
插入结点10:
插入结点10,将10的颜色变为黑色
image.png
插入结点9:
符合情况二,不需要改变
image.png
插入结点8
满足情况四
image.png
插入结点7
满足情况三
父红叔黑组黑→父黑叔黑组红
但是会违背规则二
image.png
插入结点6
满足情况四
父变黑,祖变红,进行右旋转
image.png
插入结点5
满足情况三
6,8变为黑,7变为红
image.png
插入结点4
满足情况四
5变为黑,6变为红,再旋转
image.png
插入结点3
第一次变化:满足情况三,3,4,6变黑,5变红
第二次变化:满足情况四,7变黑,9变红,右旋转
image.png
插入结点2
满足情况四,3变黑,4变红,右旋转
image.png
插入结点1
第一次变化:2,4变黑,3变红
第二次变化:5,9变黑,7变红
image.png
就到这里吧

红黑树的删除更难,我就算了把。。。