红黑树可厉害了,我举两个应用的场景
1.HashMap8级链表后转红黑树,解决严重冲突下的性能瓶颈
2.epoll fd是用红黑树管理的,结合epoll的一系列特性,性能非常好
借用Tinker的一句话——上亿的开发者都享受到了红黑树带来的优越性能,那么我们还有什么理由不学呢?
这是经典的二叉搜索树,想找到10,可以很方便的左右比较就可以快速找到,性能与二分一致,lgn,最差性能是由树深决定的。
查找没问题,但是插入就不好办了,因为很有可能插入成一个单链表了,那么性能就太糟糕了。所以最好是在插入的同时对树的结构进行调整,使得树的深度尽量地小。不同的数据接口有不同的做法,比如B、B+、红黑树,我们今天讨论红黑树,其实主要讨论红黑树是怎么在插入的时候调整树的结构就可以了。
插入14,并没有破坏规则
插入21,破怪了红节点不能相邻的规则。
解决方法:变色、旋转(左旋、右旋)
下面通过了变色解决了这一问题
左旋概念,右旋反之
刚刚那个问题其实通过变色,还没解决
又是两红相遇,难道继续通过变色解决吗?如果这么做了,遍历的节点就太多了,复杂度也就太高了。接下来采用左旋
但是根节点只能为黑色,所以需要变色
但是叶子黑色节点到根节点经过的黑节点个数不一样。如图中的6。然后需要进行右旋
最后变色一次,变黑11,最终红黑树就重新恢复平衡了
但是这样分析还远远不够,我们怎么知道什么时候该变色、自旋呢?所以需要掌握所有的情景。
case1是插入到根节点
case2
然后需要向上判断有没有破坏5大性质(5大性质文末会给出)
case3
接下来转变成case4要处理的问题了
case4
这样一来就结束了,同时黑高也没有变。
5大性质(这是面试的时候应当说的,面试的时候从5大性质出发,同时讲一下如何调整树)
1.或红或黑
2.根黑
3.叶节点NIL都是黑的
T.NIL是哨兵节点。
4.红不相邻
5.黑高相等
先学习了上面的图,再学习这5个性质,就显得再简单不过了。但是还有更为复杂的删除情况等着我们去分析呢~
删除
删除的核心在于找前驱或者后驱,然后交换彼此,前驱或者后驱必然最多只有一个孩子,实际删除前驱或者后驱,可以使得平衡的代价大大减小。接下来我们只需要考虑前驱或后驱即可。在前驱或后驱被删除后,如果前驱或后驱是红色的,那么黑高就没有变化,所以就不用管了。但是如果是黑色的,那么删除以后,黑高就变了,我们就不得不做出一些措施来调整了。主要有4大情形:
case1
声明一下,前驱或后驱已经被删了,这里的N标记的点,是前驱或者后驱的子节点。现在少了一级黑高,我们必须进行一定的调整,但是我们不可能一步就调整成功,我们这里只是尽可能地把它往对的地方去引。
这里进行了变色与左旋。
case2
对他进行变色
case3
对它变色与右旋
case4
对它变色与左旋。到达了4,就成功完成修复了。当然别忘了如果是根节点需要置黑
总结与面试说辞未完待续