[map的实现原理--红黑树]
1|0map--红黑树
1|1事情起因于pta的某道题-树种统计
数据结构题肯定不能用STL里面的map,但是这个题明显就是用map做,于是我想能不能自己实现一个map呢?了解到map的实现原理是红黑树!
2|0前置知识:二叉搜索树
红黑树的基本原理就是二叉搜索树,二叉搜索树又叫二叉排序树,定义是左儿子比他小,右儿子比他大。那么这样查找的时候,就可以按照这种方式以logn的级别去查找,效率很高。但要考虑一种最坏的情况那就是从开头到结尾,元素的插入都是按照从大到小(或从大到小)的顺序去插入,比如插入的数是 5 4 3 2 1,那么这个树的形状就是这个样子
那么这样的话,查找的复杂度就会变成O(n),因为他每次都会从他的左儿子往下找,就相当于遍历一个数组一样,那么有没有一种方法可以解决这种问题呢?有!它就是红黑树,那么它为什么可以控制这个链状的结构呢,那就是跟他的性质有关系了。
3|0性质
1.结点有颜色,且要么是红,要么是黑。
2.根结点是黑色。
3.所有叶子都是黑色。(注意这里的叶子指的是空结点)
4.每个红色结点的两个子结点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色结点)
5.从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点。
这些约束强制了红黑树的关键性质: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长,如图所示
这样的话,因为每条路径的黑结点数要相同,所以要使路径足够长的话,就是往任意两个黑结点中间插入一个红结点。就是这样的性质,保证了他不会出现只有一条链的情况,他的复杂度可以稳定在O(logn)
4|0维护
4|1既然了解了它的性质,那么如何在插入的时候就保持这样的性质呢?
首先新插入的结点把它设置为红色结点。然后我们来看这么一种情况
我们发现违反了性质4,那么我们要修正他,情况1:自己的父亲和叔叔都是红色,那么就令他的爸爸和叔叔的颜色都设置为黑色,把它爷爷的颜色设置为红色,那么他就会变成这个样子
那么我们来考虑情况2:如果将它爷爷设置为红色后,发现它爷爷的上一个也是红色怎么办?
我们发现此时它爷爷的叔叔并不是红色,那么此时就要考虑变色+旋转,方法是将新结点爷爷的父亲改为黑色,将它爷爷的爷爷设置为红色,然后以它爷爷的爷爷为旋转点旋转。(此情况为右旋),旋转为如图所示
我们再来稍微多考虑一个情况2中的小情况比如这样:
我们发现它不同于情况1的描述,与情况2的描述,但是又跟情况2有相似之处,因为他的叔叔空节点(默认为黑色),此时我们要先以它的父亲为旋转点左旋,如图所示
然后再接着跟情况2一样了,如果没有左旋的话,直接右旋会出现问题,具体可以自己手动模拟一下(自主思考还是很重要的!)
然后最后放一下树种统计的代码,如果会二叉搜索树的话,只需要看如何稳定时间logn就好了!
__EOF__

本文作者:风丨铃
本文链接:https://www.cnblogs.com/-Wind-/p/16745890.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/-Wind-/p/16745890.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!