前言
大家好,我是春风。
在经过一周的用上下班坐地铁的时间刷红黑树讲解视频后,我也算是终于弄懂了红黑树这个数据结构的底层原理,也理解了TreeMap的底层源码,原来都是知其然,不知其所以然。今天便记录一下所学笔记~也是对红黑树知识做一个全面的总结。
一、二叉树搜索树(BST)
二叉树中每一个节点最多有两个节点,按照从左到右的有序性。
二叉树遍历:
- 前序:根左右
- 中序:左中右
- 后序:左右中
前驱与后继:
- 二叉树前驱节点:左子树中最大的节点;
- 二叉树后继节点:右子树中最小的节点
前驱与后继的作用:在删除操作中用来替换被删除节点。
删除操作:
- 叶子节点直接删除;
- 只有一个子节点的用子节点替换被删除节点;
- 有两个的用前驱或者后继节点替换被删除节点;
删除操作与红黑树相同,只是红黑树多了变色操作。
BST存在的问题: 如下图:极端情况下,左倾或者右倾会导致二叉树退化为链表,查询的时间复杂度也退化到log(N)。
因此,出现了平衡二叉树(AVL),平衡二叉树即左右子树高度不超过1。
1. AVL如何实现平衡?
通过左旋或者右旋操作
2. 为什么有了AVL还要红黑树呢?
AVL实现比较复杂,而且删除和插入性能差。AVL树每次插入和删除都需要计算每个节点左右子树的高度差,调整时需要进行很多的左旋或者右旋操作,而红黑树只需通过判断颜色匹配规则然后进行简单的调整即可达到整棵树的平衡。
二、2-3-4树
也是4阶B树
2-3-4树节点只能是2节点、3节点、4节点之一。
- 2节点:包含1个元素,有2个子节点
- 3节点:包含2个元素,有3个子节点
- 4节点:包含3个元素,有4个子节点
2-3-4树的分裂过程:
当元素个数到4个时,排序第二的元素向上提升,第一个元素变为它的左子节点,3、4元素为一个3节点,作为他的右子节点。
2-3-4树每次按照这种规则分裂,使得整棵树是从叶子节点往上生长,也使得整棵树成为了一颗满树,所有叶子节点拥有相同的高度。
2-3-4树是一颗满树,它转化为二叉树时,一定是平衡的,但是由于其本身节点的元素不确定,所以直接使用2-3-4树会比较复杂,但是我们可以使用其对等的平衡二叉树-红黑树
2-3-4树和红黑树的对等关系:
2-3-4树中只有2节点、3节点、4节点和分裂过程,我们只需看这几种情况和红黑树的对等关系即可。
节点插入:
2-3-4树的节点插入由下到上,当元素个数超过3个时,就会向上提升,父节点元素超过则递归处理。
红黑树+新增一个节点(红色) = 对等的2-3-4树+新增一个元素
红黑树:
- 新插入的节点为红色,这样才不会对红黑树的高度产生影响;
- 2节点对应红黑树中单个的黑色节点,插入时直接成功;
- 3节点对应红黑树中的 红+黑 子树,插入后将其修复为 红+黑+红 子树(对等3节点分裂提升)
- 4节点对应红黑树中的 红+黑+红 子树,插入后将其修复为 红色爷爷+黑色叔叔和父亲+红色孩子 子树,然后再把爷爷的红色节点向上修复
2-3-4树的删除节点可以全部转换为叶子节点的删除,红黑树删除可以转换为叶子节点和叶子节点上一层节点的删除。
三、红黑树
红黑树5大特性:
- 节点是红色或者黑色;
- 根节点是黑色;
- 所有叶子节点是黑色的null节点;
- 不能有连续的红色节点;
- 从根节点到任何一个叶子节点的黑高相同
由特性5可以得出:
红黑树即使在最差的情况下,左子树全部是黑色,右子树红黑相间,则左右子树的高度差也只会相差一半,不会退化为链表
红黑树在插入时(删除不用)需要通过变色、左旋、右旋来调整颗树,已满足上面的5大特性,主要是判断4特性,而且调整时,尽量控制在子树内调整,就能满足条件。
新增节点:
对应2-3-4树新增节点的情况:
红黑树每次插入的节点先都是红色
- 如果插入的是根节点,直接插入,红色变黑色;
- 如果父节点为黑色,则直接插入,对应2-3-4树中2节点增加元素;
- 如果父节点为黑色,兄弟节点为红色,则直接插入,对应2-3-4树中3节点增加元素;
- 如果父节点和叔叔节点为红色,则爷爷节点一定为黑色,此时插入红色的孩子节点时,需要将父节点和叔叔节点变为黑色,爷爷节点变为红色,此时,如果爷爷节点是根节点,则变回黑色,如果不是,则把爷爷节点当做新插入的节点,再次校验爷爷节点和太爷爷节点的颜色并做处理。对应2-3-4树中4节点增加元素;
- 如果父节点是红色,没有叔叔节点,则以爷爷节点为支点左右旋,旋转后,原来的爷爷节点变为红色,原来的父节点变为黑色。对应2-3-4树中3节点增加元素。
删除节点
删除节点通俗的讲就是:自己能搞定的自己搞定;搞不定的找兄弟和父亲帮忙;父亲和兄弟都搞不定的就有难同当。
删除并不是直接删除被删节点,而是找被删节点的前驱节点或者后继节点做替换,同二叉树删除
而我们找到的前驱或者后继节点一定只有两种情况:
- 要么是叶子节点,比如0,9,11;
- 要么是只有一个子节点的节点,比如7。
而对应到2-3-4树,则一定在叶子节点;
对应2-3-4树中删除节点情况:
-
自己能搞定的自己搞定 如果删除的节点对应2-3-4树中3节点或者4节点,则直接删除; 如果删除的是红色节点,则直接删;如果是黑色节点,则其中一个红色节点上来替代,然后变黑
-
自己搞不定的找兄弟和父亲帮忙 如果要删除的节点没有子节点,且是黑色,则为了维持黑高平衡,就需要找父亲借,父亲下来顶替被删节点的位置,然后兄弟节点提升成为新的父节点;
(涉及到左右旋操作)
借一个节点,需要旋转两次,一次借两个节点,则只需要旋转一次,treemap使用的就是第二种。 旋转一次:只用沿着父节点进行左右旋一次即可;
-
父亲和兄弟都搞不定的就有难同当
被删节点是一个黑节点,且没有子节点,而且兄弟节点也没有,兄弟节点没有的借,则兄弟节点自损变为红色,这个时候父一级黑色节点又不平衡了,所以要依次往上递归自损。
总结
- 理解2-3-4树后,对应理解红黑树,就能真正理解红黑树为什么有这些特性,以及理解红黑树的新增和删除过程;
- 红黑树有平衡二叉树查询效率高且稳定的特性,但又比二叉树好实现,其中颜色的判断来调整子树,就能比较容易的调整整棵树的平衡。
最后的最后,求点赞!非常感谢!
我是春风,春风和煦,不负归期! 公H:程序员春风