当前位置: 首页> 房产> 建材 > 免费网站推广工具有哪些_青岛网络科技公司排名_电商网_上海搜索引擎优化公司排名

免费网站推广工具有哪些_青岛网络科技公司排名_电商网_上海搜索引擎优化公司排名

时间:2025/9/6 16:48:28来源:https://blog.csdn.net/m0_71927622/article/details/142785930 浏览次数:1次
免费网站推广工具有哪些_青岛网络科技公司排名_电商网_上海搜索引擎优化公司排名

什么是红黑树?

红黑树是一种具有特殊结构的二叉搜索树。它除了存储数据和节点关系之外,还用一个位来存储它的颜色是红色还是黑色。
在这里插入图片描述

红黑树的性质

1、 每个节点不是黑色就是红色
2、 根节点为黑色
3、所有的NIL节点为黑色,NIL节点指的是叶子节点指向的空节点。
4、同一路径下不能有连续的红色节点。如果当前节点是红色,则父亲节点和子节点都必须为黑色节点。
5、任一节点到其每个叶子(NIL节点)的所有路径都包含相同数目的黑色节点。

性质1到性质5结合起来便维持了树的相对平衡。从根到NIL节点的 最长路径 <= 最短路径的二倍,从而使树保持大致平衡。

定义红黑树的节点

下面,通过实现一份简易的红黑树代码,来学习这个数据结构。

红黑树的节点需要定义成三叉链的形式来对红黑树进行操作。还需要额外定义一个成员变量颜色。
在这里插入图片描述

红黑树的插入接口的实现

通过学习插入操作可以让我们更加直观地对红黑树的性质能有更深层次的理解。以及为什么红黑树相比于AVL树更加优秀一点点。

插入的新节点应该是什么颜色的呢?从红黑树的性质上看,新插入节点为黑节点会破坏上面列举的红黑树的性质5,所以新插入的节点应该选择红色。红黑树的性质规定同一路径下不能有连续的红节点。这样定义颜色方便我们进行向上调整树的颜色,以便于我们控制树的结构。

插入的主逻辑还是和搜索二叉树的逻辑一致,唯一有的不同是需要对新插入节点的颜色。根节点的颜色为黑色,其余新插入节点的颜色为红色。
在这里插入图片描述

接下来就是红黑树的主要控制逻辑部分。

树为空时,需要第一个插入的节点修改成黑色

当插入新节点的父亲为黑色时,不需要进行调整,直接插入结束返回。
在这里插入图片描述

那么当父亲节点存在且父亲节点为红色时,说明红黑树需要向上调整。 下面我以cur表示新插入节点,cur的父亲用p表示,u用于表示cur的叔叔节点,g用于表示p的父亲节点也就是祖先节点。
在这里插入图片描述

向上调整的策略主要是看叔叔节点的情况,来进行对应的调整。此时一般分成三大种情况,情况一是u存在且为红。 情况二是u不存在。情况三是u存在且为黑

先讲讲情况一,情况一的解决思路是将p和u修改成黑色,g改成红色。然后判断g是不是根节点,如果是根节点将g修改成黑色。g不是根节点就让g的值赋给cur,再让cur的p赋值给p向上迭代继续处理。

在这里插入图片描述
在这里插入图片描述
再讲讲情况二 无论是p在g的右边还是左边,cur在p的右边或是左边。当uncle存在时,由于需要满足任意节点出发到NIL节点的黑节点数量相同的性质,需要对当前的g进行旋转进行调整。在对g进行旋转之前还需要考虑是否触发双旋的场景。

下面在看情况二的特殊样例,此时cur为红色,p为红色,祖父节点的颜色为黑色。我们需要对祖父节点进行右旋转,然后将parent的颜色修改成黑色,将grandfather的颜色修改成红色
在这里插入图片描述
再看下图的场景,此时,根据前面对于AVL树部分的学习可知。要让树平衡需要对p进行左单旋,让后对g进行右单旋。然后将cur修改成黑色,g修改成红色
在这里插入图片描述

再谈一谈情况三的场景,uncle存在且为黑节点。那么此时无论p在g的右边还是左边,cur在p的左边还是右边,都是需要旋转+变色操作的。所以我们可以将情况二和情况三放在同一个逻辑处理模块进行处理。

再看看情况三的特殊样例,对g进行一个左单旋,然后让修改g和p的颜色即可。

在这里插入图片描述

在这里插入图片描述
其实情况二和情况三是可以放在同一个模块处理的。因为这两个情况都是先旋转后变色。唯一需要控制的旋转的逻辑是单旋还是双选,以及颜色的修改。下图以p在g的左边为例,反之,p在g右边同理。
在这里插入图片描述

下面就是参考代码

在这里插入图片描述

验证插入接口

通过红黑树的性质,写一个接口来判断当前树是否是红黑树。接口设计思路如下,采取主函数调用子函数递归的方式进行接口的设计。

主函数部分,需要对边界情况进行处理。当根节点不是黑节点时,则表示当前树不符合红黑树的性质,需要进行相应的处理。将基准值给统计出来,这里我以最左路径的黑节点的个数为基准值为例。然后将基准值交个子函数进行验证。

在这里插入图片描述
子函数部分实现思路如下,采用后序遍历的思路进行分治子树。我们需要一个形参记录当前路径的黑色节点的个数,用于与基准值进行比较。当遍历到NIL节点(NULL节点)时,让当前路径的黑节点数量与基准值进行比较。相等表示该条路径符合红黑树的性质,反之则不符合。当然,如果递归时碰到连续的红节点时,也不符合红黑树的性质,需要进行相应的处理。
在这里插入图片描述

红黑树与AVL树的比较

从性能的角度来说,由于AVL树的绝对高度差必须为1,所以插入和删除要经过大量的旋转操作。而红黑树它是一个近似平衡的高度差,要求最长路径不超过最短路径的两倍。这意味着红黑树的插入和删除操作更加高效。虽然红黑树查找的平均效率不如AVL树,但是整体来说,它们俩是处于一个量级的。红黑树的整体性能也是稍稍优于AVL树的。

下面以大量随机值插入的场景为例,比较AVL树和红黑树的旋转次数以及高度。
在这里插入图片描述
通过上图可以看到,当数据在1000w的量级下,红黑树相比AVL树的高度高了7层,旋转次数少了70w次左右。整体的整体的性能还是更加优秀一点点。如果红黑树是10分,难么AVL树就是9.5分。

红黑树的插入接口相较于AVL树的插入结果还是比较容易控制的。AVL树需要考虑平衡因子的设置,还是比较麻烦的。不得不感慨红黑树的发明者真TM的是个天才。只需要维持着红黑树的五个性质就能让搜索二叉树的高度近似平衡。

红黑树的应用

在C++的STL库中的map、set、multimap等容器的底层就是用的红黑树。JAVA的TreeMap底层也是用的红黑树。当然红黑树不仅仅被应用在编程语言的容器库中。还被应用在Linux内核的许多模块中,如进程调度模块、文件模块等等。

总结

红黑树是一种复杂的数据结构,它能够保证二叉搜索树的高度近似平衡。这样达到了增删改查都是O(logN)量级。它是通过五个性质来保证最长路径长度不超过最短路径长度的二倍,达到高度达到近似平衡的。它相较于AVL树的实现方式和性能等方面都要略微优秀那么一点点,但总体来说就是95分和100分的区别。

学习红黑树是为了让我们更加了解map/set的底层实现,这样对于学习map/set更加有帮助。接下来会用上面实现的demo代码来对map/set进行简单模拟实现以更深理解这两个容器。

关键字:免费网站推广工具有哪些_青岛网络科技公司排名_电商网_上海搜索引擎优化公司排名

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: