数据结构与算法之树

简介: 红黑树1.如果一个树要是红黑树,那么这个树首先就要满足平衡二叉树的性质。

红黑树

1.如果一个树要是红黑树,那么这个树首先就要满足平衡二叉树的性质。

为什么需要平衡二叉树呢???
  也许在我们在构建树的时候会发生如下的情况

       20191021184503315.png                                      


这种情况根本就体现不出我们用树的好处所在了,所以为了避免这种情况的发生,我们希望能有一种算法,将上述情况的转化为平衡二叉排序树,这样就可以让我们的二叉排序树的结构达到最优化的状态。

所以我们就有了平衡因子的概念。


平衡因子:   左右子树的高度之差。 
    当高度之差 大于1时我们就需要进行旋转了。

接下来给大家介绍一下平衡二叉树的旋转(红黑树的旋转也是和这个一样的)。


右旋的情况


  1. LL型(右旋):此时平衡因子大于1.所以我们现在就要进行旋转了,方法如下。
    以B为支点让A进行右旋

20191021185533361.png

2.LR型(先转换成LL型在右旋):

首先我们交换B、C的位置,由性质我们知道此时B小于C所以此时我们的C就会在B的左边,就会变成第二个图片所示,现在就变成了我们的第一种情况(LL型了。我们只需要让其右旋就可以使平衡因子的绝对值不大于1)


       20191021185803454.png                        

左旋的情况!

1.RR型(左旋):RR型其实和LL行的型的情况的情况相反 我们只需要逆向思考就行。以B为支点让A进行左旋


20191021190402479.png

2.RL型: 首先我们交换B、C的位置,由性质我们知道此时B大于C所以此时我们的C就会在B的右边,就会变成第二个图片所示,现在就变成了我们的第一种情况(RR型了。我们只需要让其右旋就可以使平衡因子的绝对值不大于1)

20191021190757342.png


以上就是旋转了。

通过以上方法我们就能完成对平衡二叉排序树的构建,那么接下来我们来介绍一下红黑树:

红黑树的性质:


1)节点是红色或黑色;

2)根节点是黑色;

3)所有叶子节点都是黑色节点(NULL);

4)每个红色节点必须有两个黑色的子节点(如果叶子结点是红色,那么我的黑色结点可以不画出来)。(从每个叶子到根的所有路径上不能有两个连 续的红色节点。)

5)从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。


我们来介绍一下红黑树的旋转吧:


左旋:我们现在旋转方框所示。现在进行左旋。

首先我们能将E作为支点把B进行左旋,此时会遇到B和F抢夺位置,因为B小于F所以我们将F移动到B的右侧.如中间所示,然后再让A链接E,即完成左旋。

20191021192737217.png


右旋的思想概念和左旋一样,就行读者自己理解了(不好画图。。。。体谅一下。)

红黑树的插入:

注意!!!!   我们插入的一般是红色节点(可以减少调整次数)。
Q:那么当我们插入一个红色节点后,可能会使原树的那些性质发生改变?
A:1. 如果插入的节点位置是根节点,则性质2会受到破坏
   2. 插入的节点的结点是红色,则会破坏性质四。


总而言之: 当我们插入一个红色节点,只会破坏性质2 和性质4

那么我们只需要准备好对应的修复方法即可使其再次成为红黑树。


      下面是会遇到的情况!


1.情况1:插入的是根节点。

原树是空树,此情况只会违反性质2。


对策:直接把此节点涂为黑色。


2.情况2:插入的节点的父节点是黑色。

此不会违反性质2和性质4,红黑树没有被破坏。


对策:什么也不做。


情况3:变化前[当前结点为4节点]:

3.当前节点的父节点是红色且祖父节点的另一个子节点(叔叔节点)是红色。

此时父节点的父节点一定存在,否则插入前就已不是红黑树。与此同时,又分为父节点是祖父节点的左子

还是右子,对于对称性,我们只要解开一个方向就可以了。 在此,我们只考虑父节点为祖父左子的情况。

同时,还可以分为当前节点是其父节点的左子还是右子,但是处理方式是一样的。我们将此归为同一类。

20191021200656646.png

对策:将当前节点的父节点和叔叔节点涂黑,祖父节点涂红,把当前节点指向祖父节点,从新的当前节点重新开始算法。


按照我们上面的操作步骤可以得到(下面画方框的是经过我们的步骤后所得到的效果)。此时他依然不是红黑树,那么我们还需要继续进行变色。


20191021194216588.png


  1. 情况4:[当前节点为7节点]:
    当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的右子

20191021194553959.png

对策:当前节点的父节点做为新的当前节点,以新当前节点为支点左旋。

如下图所示,


变换之后

20191021195043675.png

可以看出经过死的变换依然不满足红黑树的性质。那么我们在经过左后一步即可得到一个红黑树,那就是步骤五。


  1. 情况5:[当前节点为2节点]
    当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的左子

2019102119533829.png

对策:父节点变为黑色,祖父节点变为红色,把祖父节点右旋

       20191021195824345.png                        

此时的树就完全满足了红黑树的性质,此时插入完成!!!!


那么现在我们就能对红黑树的插入进行总结了!!!!


经过上面情况3、情况4、情况5等3种插入修复情况的操作示意图,大家应该能发现,后面的情况4、情况5都是针对情况3插入节点4以后,进行的一系列插入修复情况操作。同样的。你可以认为:整个变换过程下来,情况3、4、5就是一个完整的插入修复情况的操作流程(读者们如果遇到情况三那么就可以直接将套用我们的345修复情况。)情况四、五也是独立的情况,不要误认为只有在情况三发生之后才会遇到情况四和五。


现在就先写到红黑树的插入的,后面的删除部分比较复杂,下面的博客再给大家分享。


目录
相关文章
|
5天前
|
存储 算法 Java
Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。
【6月更文挑战第21天】Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。二叉树遍历通过访问根、左、右子节点实现。DFS采用递归遍历图的节点,而BFS利用队列按层次访问。以下是简化的代码片段:[Java代码略]
16 4
|
4天前
|
算法 Java 机器人
Java数据结构与算法:AVL树
Java数据结构与算法:AVL树
|
3天前
|
机器学习/深度学习 算法
梯度提升树GBDT系列算法
在Boosting集成算法当中,我们逐一建立多个弱评估器(基本是决策树),并且下一个弱评估器的建立方式依赖于上一个弱评估器的评估结果,最终综合多个弱评估器的结果进行输出。
|
5天前
|
存储 算法 Python
python常用算法(5)——树,二叉树与AVL树(一)
python常用算法(5)——树,二叉树与AVL树
|
7天前
|
算法 数据可视化 Python
Python中的决策树算法探索
Python中的决策树算法探索
|
8天前
|
存储 算法
【树】数据结构——树和二叉树的概念&笔记
【树】数据结构——树和二叉树的概念&笔记
|
13天前
|
机器学习/深度学习 算法 前端开发
决策树与随机森林算法在分类问题中的应用
本文探讨了决策树和随机森林两种监督学习算法,它们在分类任务中表现出强大的解释性和预测能力。决策树通过特征测试进行分类,构建涉及特征选择、树生成和剪枝。随机森林是集成学习方法,通过构建多棵决策树并汇总预测结果,防止过拟合。文中提供了Python代码示例,展示如何使用sklearn构建和应用这些模型,并讨论了参数调优和模型评估方法,如交叉验证和混淆矩阵。最后,强调了在实际问题中灵活选择和调整模型参数的重要性。
40 4
|
11天前
数据结构 树(第10-14天)
数据结构 树(第10-14天)
|
1天前
|
存储 算法
【C/数据结构与算法】:树和二叉树
【C/数据结构与算法】:树和二叉树
5 0
|
1天前
数据结构篇:旋转操作在AVL树中的实现过程
数据结构篇:旋转操作在AVL树中的实现过程
3 0