-
参考资料
《数据结构:思想与实现》,翁惠玉,俞勇
-
定义
(0) 首先是一棵__二叉查找树__
(1) 每个结点要么是红色,要么是黑色
(2) 根结点一定是黑色
(3) NULL结点是黑色
(4) 每个红色结点的两个子节点必然是黑色
推论:任意路径上不能出现连续的两个红色结点
(5) 从__任意__一个结点到NULL结点的所有路径都包含相同数量的黑色结点
推论1:如果只看黑色结点,这棵树是完全平衡的(这也说明了整体来看,并不是完全平衡的)
推论2:如果一个黑色结点存在子结点,那么它一定有两个子结点
根据(4)、(5)
推论:最长路径最多是最短路径的2倍(最长路径是黑红……黑红的那条,最短路径是黑……黑的那条)
示例
最大特性:自平衡 -
红黑树的3种内部基本操作
(1) 左旋(逆旋)
相当于一只手把结点V(当前结点的右结点)拽住,让V到P现在的位置,然后由于V的左子结点变成了P,所以原来的左子结点R就变成了P的右子结点(2) 右旋(顺旋)
(3) 变色红色结点变成黑色结点,黑色结点变成红色结点
左旋只影响旋转结点和其右子树的结构,把右子树的结点往左子树挪了;
右旋只影响旋转结点和其左子树的结构,把左子树的结点往右子树挪了。
红黑树总是通过旋转和变色达到自平衡
-
红黑树的__查找__操作
(1) 和普通的二叉搜索树一样,最坏时间复杂度是O(2logN) = O(logN),之所以有2是因为最坏的情况是恰好一条红黑相间,一条全是红
-
红黑树的__插入__操作
(1) 插入操作分为两个部分:找到待插入的位置 + 调整使得平衡
(2) 找到待插入的位置的操作
和查找操作基本相同,只不过如果查到了key相同的结点,那么就直接更新这个结点的非key值部分就行了;如果一直查不到key相同的结点的话,说明这个结点是要被插入的,那么__它的初始待插入位置一定是叶结点__(例如我想在图8-24中插入10,那么经过一顿操作,首先找到的待插入位置是12的左子结点)
那这个新结点要涂成什么颜色呢?当然是__红色__,因为定义(5),所以先插个红色结点再说,然后再调整
(3) 调整使得平衡的操作
不写了太复杂,但是大概就是__分情况讨论__ + 各种情况下运用左旋、右旋、变色三个基本操作
-
红黑树的__删除__操作
(1) 删除操作分为两个部分:找到要删除的位置 + 调整
(2) 找到待删除的位置的操作
和查找相同。 如果要是没找到的话那就太好了,啥也不用干
(3) 待删除的结点一共有__3种__情景
二叉树删除结点找替代结点有3种情情景:
情景1:若删除结点无子结点,直接删除
情景2:若删除结点只有一个子结点,用子结点替换删除结点
情景3:若删除结点有两个子结点,用后继结点(大于删除结点的最小结点)替换删除结点
(4) 针对情景3,什么叫“大于删除结点的最小结点”呢?
把二叉树所有结点投射在X轴上,所有结点都是从左到右排好序的,所有目标结点的前后结点就是对应前继和后继结点
也就是说,把二叉搜索树拍扁,那么它们从左到右会依次增大
(5) 根据(4),情景3这种最麻烦的情况可以变得稍微简单一些,删除一个中间结点也可以变成删除一个叶结点
所以,情景2、3总是可以通过一系列操作转换为情景1。也就是说,删除操作删除的结点可以看作删除替代结点,而替代结点经过一系列操作最后总是叶结点
(6) 接下来就是研究删除最后的叶结点的各种情况,然鹅还是很复杂要分多种情况讨论,还是通过左旋+右旋+变色操作,让红黑树自平衡,太复杂不说了
4_红黑树
最新推荐文章于 2025-06-10 23:59:31 发布