数据结构之红黑树简介

目录

一、红黑树定义

二、红黑树特征

三、变色、左旋、右旋

四、总结


一、红黑树定义

红黑树是二叉查找树,二叉查找树这一数据结构并不难,而红黑树之所以难是难在它是自平衡的二叉查找树,在进行插入和删除等可能会破坏树的平衡的操作时,需要重新自处理达到平衡状态。

红黑树是一种含有红色和黑色节点并能自平衡的二叉查找树,红黑树和其他二叉查找树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的性质,从而获得较高的查找性能。它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的:它可以在 O(log n) 时间内做查找,插入和删除,这里的 n 是树中元素的数目。

二、红黑树特征

红黑树就是一种平衡的二叉查找树,说他平衡的意思是他不会变成“瘸子”,左腿特别长或者右腿特别长。红黑树是每个节点都带有颜色属性的二叉查找树,颜色或红色或黑色。在二叉查找树强制一般要求以外,对于任何有效的红黑树我们增加了如下的额外要求:

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

三、变色、左旋、右旋

下面为一颗标准的红黑树:

试想一下,如果我们在红黑树中插入或者删除节点后,可能会导致红黑树平衡性被破坏。举个例子:

往上面如图的红黑树中插入值为12的节点:

根据红黑树特性插入后如图:

如上图,还是满足红黑树上面的五个特性的,但是当我们插入值为21,插入之后如下图:

很明显,这违反了【红黑树中父子节点不能同时为红色节点】特性。不过红黑树提供了变色以及旋转(包括左旋和右旋)来保证红黑树一直都满足上面的五大特性。

【a】变色

为了符合红黑树的规则,会把节点【红变黑】或者【黑变红】。因为21和23都为红色,不符合红黑树中父子节点不能同时为红色节点的特性,所以把23红变黑,如图:

但是,23变色之后还是不满足【从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点】这个特性了,所以需要把24黑变红,看下图:

可以看到,24和30节点都为红色,又不满足【红黑树中父子节点不能同时为红色节点】特性,所以这里需要将红节点30变为黑色,如下图:

当然,这里只是局部树的变色,很明显可以看到,17和24节点也都为红色,但是,通过变色已经无法调整为满足红黑树特性了,这样就只能借助旋转来实现,旋转分为左旋和右旋两种。

【b】左旋

左旋转示意图如下:

  • 左旋中的“左”,意味着“被旋转的节点将变成一个左节点”。
  • 不会影响旋转结点的父结点,父结点以上的结构还是保持不变的。
  • 左旋只影响旋转结点和其右子树的结构,把右子树的结点往左子树挪了。

根据以上左旋特性,将之前变色完成的红黑树根据【节点13】进行左旋,左旋后的红黑树如下图所示:

说明:对照左旋满足以下三点特性:

  • 1. 原先右子(17号节点)变成新爹
  • 2. 原先老爹(13号节点)变成新爹左子
  • 3. 原先老爹右子的左子(15号节点)变成老爹右子。

左旋之后,由于【根节点必须为黑色】,所以又需要变色,如下图:

经过左旋和变色之后,红黑树其实还有一个特性没满足:【从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点】,很明显:

17 > 13 > 9 > 1 > 6 > N经过了四个黑色节点,其他情况如:

17 > 13 > 15 > N和17 > 24 > 23 > 21 > N等等都是经过了三个黑色节点,这时候就需要借助右旋操作。

【c】右旋

右旋示意图如下:

  • 右旋中的“右”,意味着“被旋转的节点将变成一个右节点”。

接下来,对上边经过左旋转之后的红黑树对【13】节点进行右旋转,如下图:

说明:对照右旋满足以下三点特性:

  • 1. 原先左子(9号节点)变成新爹
  • 2. 原先老爹(13号节点)变成新爹右子
  • 3. 原先老爹左子的右子(11号节点)变成老爹左子

最后,经过右旋转后的红黑树还有一个条件不满足【从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点】,那么我们又需要进行变色操作,如下图:

至此,一个满足红黑树所有特性的红黑树就转换完成,整个过程还是挺复杂的。由于红黑树也是二叉查找树,它们当中每一个节点的比较值都必须大于或等于在它的左子树中的所有节点,并且小于或等于在它的右子树中的所有节点,这确保红黑树运作时能够快速的在树中查找给定的值。

四、总结

前面讲到红黑树能自平衡,它靠的是什么?三种操作:左旋、右旋和变色。

  • 左旋:以某个结点作为支点(旋转结点),其右子结点变为旋转结点的父结点,右子结点的左子结点变为旋转结点的右子结点,左子结点保持不变。
  • 右旋:以某个结点作为支点(旋转结点),其左子结点变为旋转结点的父结点,左子结点的右子结点变为旋转结点的左子结点,右子结点保持不变。
  • 变色:结点的颜色由红变黑或由黑变红。

本篇主要总结了红黑树的概念、特征以及红黑树自平衡涉及的三种操作:变色、左旋、右旋。红黑树结构整体来说还是挺复杂的,需要多看几遍才行。由于笔者水平有限,文中可能存在考虑不周到的地方,还望大家指正,一起学习,一起进步!

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付 19.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值