ARTS (第9周)
开篇词
学而时习之,不亦乐乎。
温故而知新。
这几天抽空看了之前写的专栏文章,发现了一些之前的遗漏和一些引申的思考,所以在此,我写出了上面2句话。
本周:
红黑树(未完成)
Algorithm 算法
红黑树部分结构和算法(删除部分暂未完善)
红黑树(Red Black Tree) 是一种自平衡二叉查找树,其实红黑树的结构并不能完全符合平衡二叉树。
因为极端情况下,红黑树的某个最长分支可能会比最短的分支长一倍,但最多也就是一倍,这不是不可接受的,并且红黑树产生变化(即新增、删除)之后的平衡操作的时间复杂度并不高,再加上二叉树本身的高效的查找,因此红黑树的性能十分稳定。
而一些完全符合平衡二叉树定义的树,在平衡操作上所花的复杂度要比红黑树大得多。
红黑树的核心思路就是
性质1. 节点是红色或黑色。
性质2. 根节点是黑色。
性质3 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
性质4. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
红黑树的颜色:节点有红色和黑色,并且是可以进行改变的。
红黑树的左旋、右旋:
也就是我这里说写的rotateleft和rotateright方法。
需要把该节点的父节点指向该节点的子节点,然后把子节点的一条腿接到该节点上。
并且左旋/右旋有一个很重要的特性,就是进行旋转之后,树的结构还是符合二叉树结构的要求的。
所以,我在这里就猜想作者的最初设计思路,
应该是想设计一个红黑树这样的有两个颜色的树结构,利用左旋右旋的特性来进行调整,让树结构能够符合自己的预期。并且总结出了这类树结构的各种情况下的旋转变色操作(或者说是公式)。
具体代码如下:各个功能的注释都有写
1 | /** |
Review 英文文章
Ambari的介绍。
Tip 技巧
极客时间的专栏《数据结构与算法之美》
本周学习了该专栏中的25-26篇(红黑树)
学习了红黑树的结构,但这篇专栏对于红黑树的描写比较简略,因此我去另外找了别的文章看。
出处:《数据结构与算法之美》(作者:王争)
https://time.geekbang.org/column/intro/126
【算法】红黑树(二叉树)
https://blog.csdn.net/lsr40/article/details/85230703
这篇文章作者一共写了5篇,在这里都有列出来。
红黑树之删除节点
https://www.cnblogs.com/qingergege/p/7351659.html
这篇文章我做了个小总结
一、删除红色的叶子节点D 直接删除D就好 然后找继承节点 不存在继承节点则不需要更多操作
PS:删除的红色节点只有左子树或只有右子树 红黑树中根本不存在这种情况
二、删除的黑色节点仅有左子树或者仅有右子树(子孩子必定为红)
删除黑色的叶子节点D
用D的孩子(左或右)替换D,
将D孩子的颜色改成黑色即可
(因为路径上少了一个黑节点,所已将红节点变成黑节点以保持红黑树的性质)。
三、删除黑色的叶子节点D
情况1:待删除节点D的兄弟节点S为红色
将父亲节点和兄弟节点的颜色互换,也就是p变成红色,S变成黑色,父亲节点右旋(或者左旋,删除节点是左节点还是右节点)
情况2:兄弟节点S为黑色,且远侄子节点为红色。
D为左孩子对的情况,这时D的远侄子节点为S的右孩子
父节点、另一个侄子节点则不关心(不影响最后的结构)(即红黑都可以)
删除节点D之后,D的子节点(可能为NULL节点)的路径的黑色节点个数就会减1,
但是我们看到S的孩子中有红色的节点,如果我们能把这棵红色的节点移动到左侧,并把它改成黑色,那么就满足要求了,
将父节点和兄弟的颜色对调,然后对右旋的操作,最后把SR节点变成黑色,并删除D即可。
D为右孩子对的情况,这时D的远侄子节点为S的左孩子,操作类似而相反。
情况3:兄弟节点S为黑色,远侄子节点为黑色,近侄子节点为红色
D为左孩子的情况,此时近侄子节点为S的左孩子
将S右旋,并将S和近侄子的颜色互换,这个时候就变成了情况4或者5。
D为右孩子的情况,此时近侄子节点为S的左孩子
将S左旋,并将S和近侄子的颜色互换,这个时候就变成了情况4或者5。
情况4:父亲节点p为红色,兄弟节点和兄弟节点的两个孩子(只能是NULL节点)都为黑色的情况。
如果删除D,那经过P到D的子节点NULL的路径上黑色就少了一个,这个时候我们可以把P变成黑色,这样删除D后经过D子节点(NULL节点)路径上的黑色节点就和原来一样了。但是这样会导致经过S的子节点(NULL节点)的路径上的黑色节点数增加一个,所以这个时候可以再将S节点变成红色,这样路径上的黑色节点数就和原来一样啦!
所以做法是,将父亲节点P改成黑色,将兄弟节点S改成红色,然后删除D即可。
情况5:父亲节点p,兄弟节点s和兄弟节点的两个孩子(只能为NULL节点)都为黑色的情况
方法是将兄弟节点S的颜色改成红色,这样删除D后P的左右两支的黑节点数就相等了,但是经过P的路径上的黑色节点数会少1,这个时候,我们再以P为起始点,继续根据情况进行平衡操作(这句话的意思就是把P当成D(只是不要再删除P了),再看是那种情况,再进行对应的调整,这样一直向上,直到新的起始点为根节点)。结果如下图:
Share 分享
为什么HTTPS比HTTP更安全?