文章目录
- 参考链接
- 红黑树简介
- RB Tree的五条基本性质
- RB Tree的基本操作
- 增
- 情景1:红黑树为空树
- 情景2:插入结点的Key已存在
- 情景3:插入结点的父结点为黑结点
- 情景4:插入结点的父结点为红结点
- 情景4.1:叔叔结点存在并且为红结点
- 情景4.2:叔叔结点不存在或为黑结点,并且插入结点的父亲结点是祖父结点的左子结点
- 情景4.3:叔叔结点不存在或为黑结点,并且插入结点的父亲结点是祖父结点的右子结点
- 删
- 情景1:替换结点是红色结点
- 情景2:替换结点是黑结点
- 情景2.1:替换结点是其父结点的左子结点
- 删除情景2.2:替换结点是其父结点的右子结点
- 寻找前后继
- 改
- 查
参考链接
看了这么多篇红黑树文章,你理解了嘛?
红黑树原理和算法介绍
红黑树简介
- 红黑树是一种
自平衡二叉查找树
,是计算机科学领域中的一种数据结构,典型的用途是实现关联数组,存储有序的数据。
- 它是复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的。它可以在
O(logn)
时间内做查找,插入和删除, - 红黑树和平衡二叉树(AVL树)都是二叉查找树的变体,但
红黑树的统计性能要好于AVL树
。因为,AVL树是严格维持平衡的,红黑树是黑平衡的。维持平衡需要额外的操作,这就加大了数据结构的时间复杂度,所以红黑树可以看作是二叉搜索树和AVL树的一个折中
,维持平衡的同时也不需要花太多时间维护数据结构的性质。
RB Tree的五条基本性质
(1)每个节点只有两种颜色:红色和黑色。
(2)根节点是黑色的。
(3)每个叶子节点(NIL)都是黑色的空节点。
(4)从根节点到叶子节点,不会出现两个连续的红色节点。
(5)从任何一个节点出发,到叶子节点,这条路径上都有相同数目的黑色节点。
RB Tree的基本操作
增
时间复杂度:O(logn)
旋转量级:O(1) 最多两次
情景1:红黑树为空树
把插入结点作为根结点,并把结点设置为黑色。
情景2:插入结点的Key已存在
1)把插入结点设为当前结点的颜色。
2)更新当前结点的值为插入结点的值。
情景3:插入结点的父结点为黑结点
直接插入。
情景4:插入结点的父结点为红结点
情景4.1:叔叔结点存在并且为红结点
1)将P和S设置为黑色(当前插入结点I)
2)将PP设置为红色
3)把PP设置为当前插入结点,继续上溯。
情景4.2:叔叔结点不存在或为黑结点,并且插入结点的父亲结点是祖父结点的左子结点
-
情景4.2.1:插入结点是其父结点的左子结点
-
情景4.2.2:插入结点是其父结点的右子结点
情景4.3:叔叔结点不存在或为黑结点,并且插入结点的父亲结点是祖父结点的右子结点
- 情景4.3.1:插入结点是其父结点的右子结点
- 情景4.3.2:插入结点是其父结点的右子结点
删
时间复杂度:O(logn)
旋转量级:O(1) 最多三次
二叉树删除结点找替代结点有3种情情景:
- 情景1:若删除结点无子结点,直接删除。
- 情景2:若删除结点只有一个子结点,用子结点替换删除结点。
- 情景3:若删除结点有两个子结点,用后继结点(大于删除结点的最小结点)替换删除结点。
- 基于此,上面所说的3种二叉树的删除情景可以相互转换并且最终都是转换为情景1!!
- 情景2:删除结点用其唯一的子结点替换,子结点替换为删除结点后,可以认为删除的是子结点,若子结点又有两个子结点,那么相当于转换为情景3,一直自顶向下转换,总是能转换为情景1。(根据红黑树的性质来说,只存在一个子结点的结点肯定在树末了)
- 情景3:删除结点用后继结点(后继结点肯定不存在左结点),如果后继结点有右子结点,那么相当于转换为情景2,否则转为为情景1。
红黑树删除后自平衡的处理可以总结为:
- 自己能搞定的自消化(情景1)
- 自己不能搞定的叫兄弟帮忙(除了情景1、情景2.1.2.3和情景2.2.2.3)
- 兄弟都帮忙不了的,通过父母,找远方亲戚(情景2.1.2.3和情景2.2.2.3)
情景1:替换结点是红色结点
颜色变为删除结点的颜色(替换结点Q,删除结点P)
情景2:替换结点是黑结点
情景2.1:替换结点是其父结点的左子结点
- 情景2.1.1:替换结点的兄弟结点是红结点
- 情景2.1.2:替换结点的兄弟结点是黑结点
-
情景2.1.2.1:替换结点的兄弟结点的右子结点是红结点,左子结点任意颜色
即将删除的左子树的一个黑色结点,显然左子树的黑色结点少1了,然而右子树又有红色结点,那么我们直接向右子树“借”个红结点来补充黑结点就好啦,此时肯定需要用旋转处理了。
平衡后的图怎么不满足红黑树的性质?前文提醒过,R是即将替换的,它还参与树的自平衡,平衡后再替换到删除结点的位置,所以R最终可以看作是删除的。另外图15是考虑到第一次替换和自底向上处理的情况,如果只考虑第一次替换的情况,根据红黑树性质,SL肯定是红色或为Nil,所以最终结果树是平衡的。如果是自底向上处理的情况,同样,每棵子树都保持平衡状态,最终整棵树肯定是平衡的。后续的情景同理,不做过多说明了。
-
情景2.1.2.2:替换结点的兄弟结点的右子结点为黑结点,左子结点为红结点
兄弟结点所在的子树有红结点,我们总是可以向兄弟子树借个红结点过来,显然该情景可以转换为情景2.1.2.1。如图17所示。
-
删除情景2.1.2.3:替换结点的兄弟结点的子结点都为黑结点
好了,此次兄弟子树都没红结点“借”了,兄弟帮忙不了,找父母呗,这种情景我们把兄弟结点设为红色,再把父结点当作替代结点,自底向上处理,去找父结点的兄弟结点去“借”。但为什么需要把兄弟结点设为红色呢?显然是为了在P所在的子树中保证平衡(R即将删除,少了一个黑色结点,子树也需要少一个),后续的平衡工作交给父辈们考虑了,还是那句,当每棵子树都保持平衡时,最终整棵总是平衡的。
删除情景2.2:替换结点是其父结点的右子结点
- 情景2.1.1:替换结点的兄弟结点是红结点
- 情景2.1.2:替换结点的兄弟结点是黑结点
- 删除情景2.2.2.1:替换结点的兄弟结点的左子结点是红结点,右子结点任意颜色
- 删除情景2.2.2.2:替换结点的兄弟结点的左子结点为黑结点,右子结点为红结点
- 删除情景2.2.2.3:替换结点的兄弟结点的子结点都为黑结点
寻找前后继
改
时间复杂度:O(logn)
不能改key值,只能改value值。
查
时间复杂度:O(logn)
查操作与二叉查找树相同。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)