数据结构与算法学习——红黑树

二叉搜索树的缺陷

二叉搜索树作为数据存储的结构有重要的优势:
可以快速的查找给定关键字的数据项,并且可以快速的插入和删除数据项,但是,二叉搜索树有一个很麻烦的问题:如果插入的数据是有序的数据,比如下面的情况有一棵初始化为9 8 12的二叉树
数据结构与算法学习——红黑树_第1张图片

非平衡树:
比较好的二叉搜索树数据应该是左右均匀分布的
但是插入连续数据后,分布的不均匀,我们称这种树为非平衡树
对于一颗平衡二叉树来说,插入/查找等操作的效率是O(logN)
对于一颗非平衡树,相当于编写了一个链表

树的平衡性

为了能以较快的时间O(logN)来操作一棵树,我们需要保证树总是平衡的:
至少大部分是平衡的,那么时间复杂度也是接近O(logN)的
也就是说树中每个节点的左边的子孙节点的个数,应该尽可能的等于右边的子孙节点的个数
常见的平衡树有哪些?

AVL树:

AVL树是较早的一种平衡树,它有些办法保存树的平衡(每个节点多存储了一个额外的数据)
因为AVL树是平衡的,所以时间复杂度也是O(logN)
但是,每次插入/删除操作相对于红黑树效率不高,所以整体效率不如红黑树

红黑树:

红黑树也是通过一些特性来保持树的平衡
因为红黑树,所以时间复杂度也是在O(logN)
另外插入/删除等操作,红黑树的性能要优于AVL树,所以现在平衡树的应用基本都是红黑树

红黑树

红黑树规则:

红黑树,除了符合二叉搜索树的基本规则外,还添加了以下特性:
【性质1】.节点是红色或黑色
【性质2】.根节点是黑色
【性质3】.每个叶子节点都是黑色的空节点(NIL节点)
【性质4】.每个红色节点的子节点都是黑色(从每个叶子到根的路径上不能有两个连续的红色节点)
【性质5】.从任意节点到其每个节点的所有路径都包含相同数目的黑色节点
规则很重要,下面练习会用到,下图就是一个红黑树,上面的五点都符合
数据结构与算法学习——红黑树_第2张图片

红黑树的相对平衡

前面的约束,确保了红黑树的关键特性:
从根到叶子的最长可能路径,不会超过最短可能路径的两倍长
结果就是这个树基本是平衡的
虽然没有做到绝对的平衡,但是可以保证在最坏的情况下,依然是高效的

为什么可以做到最长路径不超过最短路径的两倍呢?

【性质4】决定了路径不能有两个相连的红色节点
【性质5】所有路径都有相同数目的黑色节点
这就表明了没有路径能多余任何其他路径的两倍长

插入新节点遇到情况的解决办法

插入一个新节点时,有可能树不再平衡,可以通过三种方式的变换,让树保持平衡
换色/左旋转/右旋转

变色

为了重新符合红黑树的规则,尝试把红色节点变成黑色,或者把黑色节点变成红色
首先需要知道插入的新节点通常默认为红色节点
因为在插入节点为红色的时候,有可能插入一次是不违反红黑树任何规则的(插入9)
数据结构与算法学习——红黑树_第3张图片

而插入黑色节点,必然会导致有一条路径上多了黑色节点,这是很难调整的
红色节点有可能导致出现红红相连的情况,但是这种情况可以通过颜色变换和旋转来调整

左旋转

逆时针旋转红黑树的两个节点,使得父节点被自己的有孩子取代,而自己成为自己的左孩子
数据结构与算法学习——红黑树_第4张图片
图中,身为右孩子的x取代了a的位置,而a变成了x的左孩子。此为左旋转

右旋转

顺时针旋转红黑树的两个节点,使得父节点被自己的左孩子取代,而自己成为自己的右孩子
数据结构与算法学习——红黑树_第5张图片
图中,身为左孩子的x取代了a的位置,而a变成x的右孩子

插入操作

接下来,讨论一下插入的情况
设要插入的节点为N,其父节点为P
其祖父节点为G,其父亲的兄弟节点为U(即P和U是同一节点的子节点)

情况一:

新节点N位于树的根,没有父节点
这种情况下,我们直接将红色变换成黑色即可,这样满足性质2
image.png

情况二

新节点的父节点P是黑色
性质4没有失效(新节点是红色的),性质5也没有任何问题
尽管新节点N有两个黑色的叶子节点nil,但是新节点N是红色的,所以通过它的路径中黑色节点的个数依然相同,满足性质5(下图省略了nil)
数据结构与算法学习——红黑树_第6张图片

情况三

P为红色,U也是红色
数据结构与算法学习——红黑树_第7张图片

操作方案:
将P和U变换为黑色,并且将G变换为红色
可能出现的问题
但是N的祖父节点G的父节点也可能是红色,这就违反了性质3,可以递归调整颜色
但是如果递归调整颜色到了根节点,就需要进行旋转了,这个下面遇到了再讲解

情况四

N的叔叔U是黑节点,且N是左孩子。简写:
父红叔黑祖黑 N是左儿子
变换:父黑--祖红--右旋转
数据结构与算法学习——红黑树_第8张图片

情况五

N的叔叔U是黑色节点,且N是右孩子。简写:
父红叔黑祖黑,N是右孩子
变换:
以P为根,左旋转
将P作为新插入的红色节点考虑即可
自己(N)变成黑色
祖变成红色
以祖为根,进行右旋转
数据结构与算法学习——红黑树_第9张图片

实操

下面我们将10,9,8,7,6,5,4,3,2,1依次插入树中形成红黑树。
多图预警。。。。
数据结构与算法学习——红黑树_第10张图片

红黑树的知识就到这里,至于代码实现看上面的图也知道是非常难的,暂时就先不研究代码,先捋清楚逻辑。

你可能感兴趣的:(红黑树,平衡树)