红黑树及相关操作解析

由于面试被问到红黑树,特意查阅资料,并做此笔记。

1、前言

谈到红黑树,首先需要了解二叉搜索树,其特点主要有:
1、有序的,或排序的,二叉树;
2、节点可以有2个子树;
3、左子树的值比较小;
4、右子树的值比较大
下面是一个二叉搜索树的例子:
在这里插入图片描述
当一个搜索二叉树变成下面这样,有会怎样呢
在这里插入图片描述
可想而知,如果想搜索值为1 的节点,需要遍历所有的节点。他的时间复杂度也就是O(n)。解决这个问题就需要用到平衡搜索树,他的时间复杂度是O(log n),红黑树是特殊的一种平衡二叉树,其性质有:

1、其节点是红色或黑色。
2、根节点和叶子节点都是黑色(叶子是NIL节点)。
3、每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
4、从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

额外注释
1、节点需要一个存储位来跟踪颜色。
2、最长路径(从根到最远的零)不超过最短路径长度的两倍(从根到最近的零)。
-最短路径:所有黑色节点
-最长路径:红黑相间
下面是一个红黑树方便理解:
在这里插入图片描述

2、红黑树的操作

操作及时间复杂度
1、查询 O(log n)
2、插入 O(log n)
3、删除 O(log n)
空间复杂度为O(n)
其中插入和删除一个节点有可能改变树的结构,可能会违背了红黑树的性质,为了防止出现这一问题,我们需要用到旋转。

2.1 旋转

1、通过重新排列子树来改变树的结构
2、目标是降低树的高度。
- 红黑树:最大高度 O(log n)
- 较大的子树向上,较小的子树向下
3、不影响元素的顺序(较小的节点仍在左边,较大的节点仍在右边)

先不把树分为黑白两色,这样容易理解如何旋转
1、左旋:
向左旋转值为 5 的节点:
5 变成左孩子节点;10 变成父节点;8 变成 5 的右孩子节点;依次画出新的红黑树。下图为旋转之后的样子:
在这里插入图片描述
2、右旋:
向右旋转值为 10 的节点:
10 的左孩子 5 变成其父节点;10 变成 5 的右孩子节点;8 变成 10 的左孩子节点;依次画出新的红黑树,如下图:
在这里插入图片描述
可以发现:旋转之后的红黑树依旧保持其属性,值较小的节点在左边,值较大的节点在右边。

2.2 插入

前面我们已经发现,红黑树是一种自平横的二叉树,当我们插入时也必须保证新树保持平衡。
步骤:
1、插入 Z 节点并将其涂成红色
2、重新着色和旋转节点以修复冲突(维持红黑树的性质)
*对于第二步,又分为四种情况:
case 1:Z 为根节点
case 2:Z 的叔叔节点为红色
case 3:Z 的叔叔节点为黑色(triangle)
case 4:Z 的叔叔节点为黑色(line)
case 1:Z 为根节点
只有一个点,直接将节点颜色变为黑色。如下图:
在这里插入图片描述

case 2:Z 的叔叔节点为红色
当 Z 父节点的兄弟节点为红色这种情况下,需要改变 Z 节点的父节点、叔叔节点以及 Z 节点的祖父节点的颜色,如下图:
在这里插入图片描述
case 3:Z 的叔叔节点为黑色(triangle)
如下图,插入 Z 时,Z 节点的叔叔节点为黑色,且 Z节点与 Z 的父节点及Z 的祖父节点的连线为三角形:
在这里插入图片描述
在这种情况下,需要旋转A节点和Z节点,如下图:
在这里插入图片描述
case 4:Z 的叔叔节点为黑色(line)
如下图,插入 Z 时,Z 节点的叔叔节点为黑色,且 Z节点与 Z 的父节点及Z 的祖父节点的连线为直线型:
在这里插入图片描述
这种情况下,首先需要旋转B和A,用A替换掉B作为新的根节点,B变成A的左子树,依次建立新的红黑树,如下图:
在这里插入图片描述
然后改变颜色,如下图:
在这里插入图片描述

总结:
1、Z 为根节点 => 直接变为黑色
2、Z 的叔叔节点为红色 => 改变相应节点的颜色
3、Z 的叔叔节点为黑色(三角型) => 旋转Z与Z的父节点
4、Z 的叔叔节点为黑色(l直线型) => 旋转Z的祖父节点与Z的父节点;并改变相应节点的颜色。

例子

在这里插入图片描述
如上图,有一棵红黑树(为了方便,叶子结点没有画出),现将要插入值为10的节点,具体操作如下所述:
1、10节点需要插在9的右子树上,这时需要旋转红黑树,Z为值为10的节点,uncle为值为13的节点,这时即为上述case 2,改变Z父节点、叔叔节点及祖父节点的颜色,如下图:
在这里插入图片描述
2、继而发现,12与15节点的颜色同时为红色,违背了红黑树的性质,则将12看做新插入的Z节点,继续修改,容易发现现在便是case 3 [Z 的叔叔节点为黑色(三角型)],根据上述改变规则,将12旋转为15的父节点,15旋转为12的右子树根节点,依次建立新的红黑树,如下图:
在这里插入图片描述
此时,可以发现,12与15两个节点同时为红色,即为case 4 [Z 的叔叔节点为黑色(line)],根据上述改变规则,将12旋转为8的父节点,8旋转为12 的左子树根节点,并依次建立新的红黑树,如下图:
在这里插入图片描述
最后重新着色:
在这里插入图片描述
完毕。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值