红黑树的优点
红黑树介于二叉查找树与平衡二叉树之间。二叉查找树能够提升数据的查找效率,但是在某些情况下它的查找效率等同于链表。为了解决这个“某些情况”,改进成为了平衡二叉树。平衡二叉树的优点顾名思义在于平衡,任意一个中间结点的左右孩子到叶子结点的深度的差的绝对值≤1。 但是为了维护整棵平衡二叉树的平衡性,插入了新的结点之后,需要自下而上遍历各个结点的深度,需要调整的时候进行调整,如果遍历到根节点还不需要调整,那就是一棵正确的平衡二叉树。但是这样不断比较遍历的维护需要比较大的代价,因此平衡二叉树适合插入少而查找多的情况。为了改进平衡二叉树的缺点而延续二叉查找树插入方便的优点,引入了红黑树这个介于两者之间的结构。
红黑树的基本性质
- 结点是红色或黑色
- 根结点是黑色
- 叶子结点为黑色且null
- 红色结点的两个孩子为黑色(没有两个相邻的红色结点)
- 从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点
此外,红黑树新插入的结点颜色默认为红色,因为红黑树要求其中的任意一个结点到以该结点为根结点的子树上所有的叶子结点的路径上的黑色结点数目相同(有点小拗口)。反过来,如果是一棵正常的红黑树,突然被插入了一个黑色节点,性质5一定会被打破。
红黑树的插入
关于插入的位置
新的结点的插入位置与平衡二叉树一样,需要先搜索一边确定。
关于插入后的维护(以插入某棵子树为例)
1.没有结点(树为空)
这个时候插入的红色结点就是根结点了,直接变红且增加两个为空的黑色叶子结点。
2.插入结点的父结点为黑
由于插入的是红色结点,此时对整棵红黑树并没有违反了性质的情况,直接插入就好了。
3.插入结点的父亲结点与叔叔结点都为“红色”
叔叔结点:父结点的兄弟结点
D为需要插入的结点,此时D作为左孩子还是右孩子情况都是一样的。
D作为新插入的结点默认为红色,D的父节点也是红色,所以需要调整。如果直接将父结点变黑,整棵树将不满足性质5,所以还要把D的叔叔结点也变黑。此时对于这棵子树而言,已经调整结束了,这个时候这棵子树的根结点A是黑色,如果A刚好又是整棵树的根结点,那就不用继续调整了。但是如果A不是整个树的根结点,那另外一侧的黑色节点数会少于这一侧的黑色节点数,那么A需要变红色。如果A变红后不进行调整,而A的父结点也是红色(因为A本来就是黑色的),违背了性质4,那就需要对上看匹配的情况进行调整。
4.插入结点的父亲结点为“红色”,叔叔结点为“黑色”(或无叔叔结点),且插入结点是其父亲结点的左孩子
D作为新插入的结点默认为红色,此时先绕着A结点进行左旋,B成为了新的根结点,再把B变黑,A变红即可
5…插入结点的父亲结点为“红色”,叔叔结点为“黑色”(或无叔叔结点),且插入结点是其父亲结点的左孩子
D作为新插入的结点默认为红色,此时先绕着B结点进行一次右旋,D变成了B的父结点,现在的情况等同于情况4,再相应调整即可
以上都是左侧插入的情况,右侧只需要将情况反转一下即可。
以下是伪代码:
孩子第一次做Blog笔记,大佬轻喷(磕头)