红黑树
目录什么是红黑树(非完全平衡二叉树)?
- 红黑树 是一种自平衡二叉搜索树(二叉查找树)是一种特殊的搜索二叉树,在进行插入和删除时通过特定操作保持二叉树自身的平衡,从而获得较高的查找性能。
红黑树再平衡方法?
- 左旋:以某个节点作为支点左旋,支点的左子节点不变。其右边节点变为其父节点,右节点的左子节点断开成为旋转节点的右子节点,右边节点左子节点是旋转节点 右节点不变。
- 右旋: 以某个节点作为支点右旋,支点的右子节点不变。其左边节点变为其父节点。左节点的右子节点断开成为旋转节点的左子节点。左边的节点右子节点是旋转节点。左节点不变。
- 变色:将节点的颜色由红变黑或由黑变红
左旋和右旋是互相逆转的。
通过再平衡的方法最坏的情况的运行时间得到了优化 可以再O(logN)的时间复度内完成查找,删除 和插入 N是二叉树中的节点数。
二叉树的特点
- 如果二叉树节点的左子树不为空,那么左子树的所有节点度小于此节点。
- 如果二叉树节点的右子树不为空,那么右子树的所有节点都大于此节点。
红黑树的特点
- 节点是红色或者黑色。
- 根节点是黑色。
- 所有叶子节点都是黑色的空节点
- 每个红色节点的叶子节点都是黑色节点(从每个叶子节点到根的所有路径上不能有两个连续的红色节点)
- 从任一节点到其每个叶子节点的所有路径都包含相同数目的黑色节点。
红黑树左旋右旋变色示例:
三、红黑树的左旋和右旋操作
对于一棵红黑树,它满足红黑树的5条特性。插入或删除节点之后,红黑树就发生了变化,很可能不再完全满足红黑树的5条特性了,也就是不再是一棵红黑树了,而是一棵普通的二叉搜索树。这时候,为了使二叉搜索树重新变成红黑树,就需要对二叉搜索树进行操作,使它满足红黑树的5条特性。
通过旋转,可以使二叉搜索树重新满足红黑树的5条特性。旋转分为左旋和右旋。
- 红黑树的左旋
左旋:以某个节点作为支点(旋转节点),其右子节点变为旋转节点的父节点,右子节点的左子节点变为旋转节点的右子节点,旋转节点的左子节点保持不变。右子节点的左子节点相当于从右子节点上“断开”,重新连接到旋转节点上。
为了不失一般性,可以看下图中的例子。左边是左旋前的红黑树局部结构,先不考虑整体,只看局部,左旋前不满足红黑树的特性5。
左旋时,旋转节点为节点50,左旋后,旋转节点的右子节点70变为旋转节点50的父节点,右子节点的左子节点60从右子节点70上“断开”,成为旋转节点50的右子节点。
左旋后,结构如右图,这个局部重新满足了红黑树的特性5,达到目的。
再看另一个左旋的例子,左边是左旋前的局部结构,以节点10作为旋转节点,左旋后,旋转节点的右子节点20成为旋转节点10的父节点,右子节点的左子节点(这里是一个叶子节点NIL)从右子节点上“断开”,成为旋转节点10的右子节点。
- 红黑树的右旋
右旋:以某个节点作为支点(旋转节点),其左子节点变为旋转节点的父节点,左子节点的右子节点变为旋转节点的左子节点,旋转节点的右子节点保持不变。左子节点的右子节点相当于从左子节点上“断开”,重新连接到旋转节点上。
不难看出,左旋和右旋是相反的,可逆的。
下图中的例子仍然是红黑树的局部,左边的结构不满足红黑树的特性5。
右旋时,旋转节点为节点70,右旋后,旋转节点的左子节点50变为旋转节点70的父节点,左子节点的右子节点60从左子节点50上“断开”,成为旋转节点70的左子节点。右旋后(右图),重新满足了红黑树的特性5。
同样再看一个右旋的例子,左边是右旋前的局部结构,以节点30作为旋转节点,右旋后,旋转节点的左子节点20成为旋转节点30的父节点,左子节点的右子节点(这里是一个叶子节点NIL)从左子节点上“断开”,成为旋转节点30的左子节点。
通过对左旋和右旋的介绍和举例,左旋和右旋的目的都是通过旋转节点的方式使二叉搜索树重新满足红黑树的特性,左旋和右旋是互逆的,根据不同的情况使用不同的旋转方式。
四、红黑树的变色操作
当对红黑树进行插入或删除节点之后,如果不再完全满足红黑树的5条特性,除了旋转,变色也可以使二叉搜索树重新满足红黑树的5条特性。
变色:将节点的颜色由红变黑或由黑变红。
向红黑树中插入节点时,新节点的颜色都设置为红色。不管新节点是什么颜色,特性3都不可能被破坏,特性1、2、4都有可能被破坏。如果插入的节点是黑色,则一定会破坏特性5,需要进行调整,如果插入的节点是红色,则一定不会破坏特性5。所以将新节点设置为红色,可以降低破坏红黑树特性的可能性。
- 添加节点
如下的左图是红黑树的一个局部,一开始是满足红黑树的特性的,在其中插入了红色节点10,两个红节点连在一起了,不再满足红黑树的特性4。
通过变色,先将节点20变成黑色,特性4满足了,但又不满足特性5,所以继续将节点30变成红色,节点40变成黑色。
经过3次变色后,从局部看,已经重新满足了红黑树的特性。但是,从整棵树来看,还不一定满足红黑树的特性,如果节点30的父节点也是红色,则还需要继续对这棵树进行调整(上面的左旋和右旋例子中也有这种情况)。
- 删除节点
如下的左图是红黑树的一个局部,一开始是满足红黑树的特性的,将节点90删除后,不再满足红黑树的特性5。
通过变色,先将节点80变成黑色,但仍不满足特性5,继续将节点70变成红色,重新满足了红黑树的特性。
经过两次变色,重新满足了红黑树的特性,对于这个例子,只要局部满足了,整棵树一定是满足红黑树的。
红黑树的旋转和变色综合案例
上文中介绍旋转和变色时,是独立对它们进行分析的。这两种调整方法都可以使被破坏规则的红黑树重新满足红黑树的特性,更多的时候,需要灵活地配合使用,使调整更高效。
下面来看一个简单的例子。使用文章开头的红黑树,结构如下图。
- 在红黑树中插入节点20,插入后不满足红黑树的特性4。
- 将节点18从红色变成黑色,变色后不满足红黑树的特性5。
- 以节点10作为旋转节点,进行左旋,左旋后还是不满红黑树的特性5。
- 将节点10从黑色变成红色,变色后,重新满足了红黑树的5条特性。
经过变色,左旋,变色,三个步骤之后,插入节点后的树重新成为一棵红黑树。