【算法篇】红黑树初探,揭开红黑树的神秘面纱
本片文章主要记录对
红黑树插入
的学习记录,适合对红黑树感兴趣的伙伴阅读
我们先来看看红黑树长什么样子吧!!!
是不是觉得它很面熟?
没错!红黑树是一种平衡二叉树
有人说红黑树很难,很复杂,太绕脑,不好理解。确实红黑树比二叉搜索树确实多了很多情况和操作,但我相信,经过这篇文章,一定会让你对红黑树不再陌生。
接下来我们一起来揭开红黑树的面纱吧!!!加油coder
为什么会出现红黑树
在学习红黑树前大家应该对二叉搜索树
有了解,二叉搜索树在插入随机数时它的左右两边才会相对平衡,这就导致一个缺点,当我顺序插入节点时二叉搜索树就不再平衡了,例如我们需要顺序插入
1-8节点。
是不是感觉此时的二叉搜索树很想一种数据结构。没错——链表,大家都知道链表是通过线性查找的方式,所有效率比较慢,此时的二叉搜索树又何尝不是呢?这个时候红黑树就应运而生了。接下来大家一起来认识认识红黑树吧!!
什么是红黑树
红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。
红黑树是在1972年由Rudolf Bayer发明的,当时被称为平衡二叉B树(symmetric binary
B-trees)。后来,在1978年被 Leo J. Guibas 和 Robert Sedgewick 修改为如今的“红黑树”。
红黑树是一种特化的AVL树(平衡二叉树),都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。
它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n是树中元素的数目。
—— 百度百科
红黑树的特性
如果对二叉搜索树了解的小伙伴应该知道二叉搜索树具有一些特点和规则,而本文中讲解的红黑树除了符合二叉搜索树的基本规则外,还有一些属于自己的特性,正是这些特性促使它能够很好的保存平衡使它的查找接近于O(log n)。
- 节点是红色或黑色
- 根节点是黑色
- 每个叶子节点都是黑色的空节点(NIL节点),每个叶子节点需要补齐缺调的节点用NIL节点补齐
- 每个红色节点的两个子节点都是黑色(从每个叶子到根的所有路径上不能又两个连续的红色节点)
- 从任一节点到其每个叶子的所有路径都包含相同数量的黑色节点
- 从根到叶子的最长可能路径,不会超过最短可能路径的两倍长
- 插入的新节点通常是红色的,而插入黑色节点,必然会导致路径上多一个黑色节点,较难调整,红色节点可能也会导致红红相连的情况,这时可以通过颜色调换或旋转来调整
以上的这些特性需要牢记!!!它将影响你后续的学习,便于你更快速的理解红黑树的原理。
注意:下面的操作图除个别情况外不会补齐
NIL节点
,各位 coder 只要记得叶子节点下有NIL节点
红黑树的操作
当我们插入一个新节点时,有可能树不再平衡,可以通过三种方式的变换让树保持平衡:
-
换色:为了重新符合红黑树规则,将红色节点变为黑色,或者黑色变为红色
-
左旋转:逆时针旋转红黑树的两个节点,使得父节点被自己的右孩子取代,而自己成为右孩子的左孩子,此时若右节点存在左子节点需平移到10节点的右子节点位置,若右子节点存在节点则按照平衡二叉树规则向下逐层添加。(节选自红黑树中的一枝)
-
右旋转:顺时针旋转红黑树的两个节点,使得父节点被自己的左孩子取代,而自己成为右孩子的右孩子,此时若左节点存在右子节点需平移到12节点的左子节点位置,若左子节点存在节点则按照平衡二叉树规则向下逐层添加。(节选自红黑树中的一枝)
红黑树的五种插入规则
由于红黑树相对复杂,所以在本文中规定插入的新节点上层节点为父节点
,父节点的上层节点
称为祖节点
,祖节点另一子节点称为叔节点
。这里规定命名是便于大家更好的理解。
以一下五种插入规则需要认真记住,在处理红黑树时基本都是以下五种情况。
情况一
插入节点位于根节点上,因为根节点必须为黑色
的特点,所以直接设为黑色,这种情况最为简单。
情况二
插入节点的父节点为黑色,直接插入,这种情况下因为新插入节点默认为红色
的特点,所有插入后并不会影响原本二叉树平衡。
情况三
插入节点的父节点为红色,叔节点也为红色时,只需要改变节点的颜色即可。(节选自红黑树中的一枝)
口诀:父红叔红祖黑色 —> 父黑叔黑祖红
思维快的小伙伴已经发现问题所在了,如果祖节点为根节点时怎么办?这时又分为几种情况
- 祖节点替换颜色后变为红色,此时不满足红黑树特性
根节点必须为黑色
此时直接将根节点设置为黑色即可。 - 如果祖节点的上层为红色节点时,此时不满足红黑树特性
不可出现红红相连的情况
此时按照这五种情况中的其一进行递归处理即可。
情况四
插入节点的父节点为红色,叔节点为黑色时,插入节点为左子节点时,需要将父节点和祖节点的颜色进行变换,再进行右旋转。(节选自红黑树中的一枝)
口诀:父红叔黑为左子 —> 父黑祖红右旋转
情况五
情况五与情况四类似。插入节点的父节点为红色,叔节点为黑色时,插入节点为右子节点时,需要以父节点为根左旋转,将新节点变为黑色,祖节点变为红色,最后以祖为根进行右旋转。
(节选自红黑树中的一枝)
口诀:父红叔黑为右子 —> 以父为根左旋转 —> 新点变黑祖变红 —> 以祖为根右旋转
情况五经过第一次转换后类似情况四,所有情况四理解后情况五就好处理多了。
学到这里是不是感觉有点累了,那你觉得以上讲的都了解了吗,如果还是不太清楚,那就再多看两遍
到这里大家应该都对红黑树有一定的了解了,相信也有不少疑虑。
如果在做节点平移时,如果节点下任然有子节点怎么办?
其实大家可以自己画图推算一下,是不会有任何影响的。举个栗子!
可以看出虽然平移节点有子节点,但经过平移后依然没有发生变动,也就是红黑树的改变是向上发生改变而不会影响以下的子节点结构,大家可以自行绘图测试一下。
习题
顺序插入 10 9 8 7 6 5 4 3 2 1
答:
结语
到这里红黑树的插入就结束了,后续会更新红黑树的其余操作,希望对大家有帮助。
敬请期待!!!