红黑树的插入操作

红黑树的插入操作

首先需要明确,在保证满足红黑树5条规则的情况下,新插入的节点必然是红色节点

为了方便说明,规定以下四个节点:新插入节点为N(Node),N的父节点为P(Parent),P的兄弟节点为U(Uncle),U的父节点为G(Grandpa),如下图所示:

正在上传…重新上传取消

image-20200303120344016

3.1.情况1

当插入的新节点N位于树的根上时,没有父节点。

这种情况下,只需要将红色节点变为黑色节点即可满足规则2 。

正在上传…重新上传取消

image-20200303132357511

3.2.情况2

新界点N的父节点P为黑色节点,此时不需要任何变化。

此时既满足规则4也满足规则5。尽管新节点是红色的,但是新节点N有两个黑色节点NIL,所以通向它的路径上黑色节点的个数依然相等,因此满足规则5 。

正在上传…重新上传取消

image-20200303132304098

3.3.情况3

节点P为红色,节点U也为红色,此时节点G必为黑色,即父红叔红祖黑

在这种情况下需要:

  • 先将父节点P变为黑色;
  • 再将叔叔节点U变为黑色;
  • 最后将祖父节点G变为红色;

即变为父黑叔黑祖红,如下图所示:

正在上传…重新上传取消

image-20200303132148128

可能出现的问题:

  • N的祖父节点G的父节点也可能是红色,这就违反了规则4,此时可以通过递归调整节点颜色;
  • 当递归调整到根节点时就需要旋转了,如下图节点A和节点B所示,具体情况后面会介绍;

正在上传…重新上传取消

image-20200303132050765

3.4.情况4

节点P是红色节点,节点U是黑色节点,并且节点N为节点P的左子节点,此时节点G一定是黑色节点,即父红叔黑祖黑

在这种情况下需要:

  • 先变色:将父节点P变为黑色,将祖父节点G变为红色;
  • 后旋转:以祖父节点G为根进行右旋转;

正在上传…重新上传取消

image-20200303131956298

3.5.情况5

节点P是红色节点,节点U是黑色节点,并且节点N为节点P的右子节点,此时节点G一定是黑色节点,即父红叔黑祖黑

在这种情况下需要:

  • 先以节点P为根进行左旋转,旋转后如图b所示;
  • 随后将红色节点P黑色节点B看成一个整体的红色节点N1,将新插入的红色节点N看成红色节点P1 如图c所示。此时整体就转换为了情况4。

正在上传…重新上传取消

image-20200303140225631

接着可以按照情况4进行处理:

  • 先变色:将N1节点的父节点P1变为黑色,将祖父节点G变为红色;

  • 后旋转:以祖父节点G为根进行右旋转,旋转后如图 e 所示;

  • 最后将节点N1和P1变换回来,完成节点N的插入,如图 f 所示;

正在上传…重新上传取消

image-20200303131736316

3.6.案例

在二叉树中依次插入节点:10,9,8,7,6,5,4,3,2,1 。

如果直接采用普通的二叉搜索树,节点全部插入后是这样的:

正在上传…重新上传取消

image-20200303161149709

是一个严重的不平衡树,相当于一个链表,不能体现出二叉搜索树的高效率。而按照红黑树的五条规则插入节点就能最大程度保证搜索二叉树是一棵平衡树。以下为过程详解:为了方便解释省略了部分红黑树的叶子节点(NIL)

插入10

符合情况1

  • 插入节点10;
  • 将节点10的颜色变为黑色;

正在上传…重新上传取消

image-20200303161257010

插入9

符合情况2

  • 不需要任何变化;

正在上传…重新上传取消

image-20200303161919072

插入8

快速判断属于情况3还是情况4的方法:

从新插入的节点N出发,按图示箭头经过的四个节点,若为红红黑红3个红色节点则为情况3,若为红红黑黑两个红色节点则为情况4;

正在上传…重新上传取消

image-20200303162613413

符合情况4

  • 父节点9变成黑,祖父节点10变为红;
  • 以祖父节点为根进行右旋转;

正在上传…重新上传取消

image-20200303163803388

插入7

符合情况3

  • 父节点8和叔节点10变为黑,祖父节点9变为红;
  • 此时会出现问题:不符合规则2,即根节点不为黑,此时可以把以9为根节点的二叉搜索树当作一个整体作为一个新插入的节点N,而此时又符合情况1,只需要把9变回黑色即可。

正在上传…重新上传取消

image-20200303165135028

插入6

符合情况4

  • 父节点7变为黑,祖父节点8变为红;
  • 以祖父节点8为根进行右旋转;

正在上传…重新上传取消

image-20200306170016958

插入5

符合情况3

  • 父节点6和叔节点8变为黑,祖父节点7变为红;

正在上传…重新上传取消

image-20200303170150314

插入4

符合情况4

  • 父节点5变为黑,祖父节点6变为红;
  • 以祖父节点6为根进行右旋转;

正在上传…重新上传取消

image-20200303171028009

插入3

第一次变换:符合情况3

  • 父节点4和叔节点6变为黑,祖父节点5变为红;

变换之后发现5和7为相连的两个红色节点,于是把以5为根的整个子树看成一个新插入的节点N1,再进行第二次变换。

正在上传…重新上传取消

image-20200303171755035

第二次变换:符合情况4

  • 父节点7变为黑,祖父节点9变为红;
  • 以祖父节点9为根进行右旋转;

正在上传…重新上传取消

image-20200303172800302

最后复原N1得到变换后的红黑树:

正在上传…重新上传取消

image-20200303173158141

插入2

符合情况4

  • 父节点3变为黑,祖父节点4变为红;
  • 以祖父节点4为根进行右旋转;

正在上传…重新上传取消

image-20200303174011409

插入1

第一次变换:符合情况3

  • 父节点2和叔节点4变为黑,祖父节点3变为红;

变换之后发现3和5为相连的两个红色节点,于是把以3为根的整个子树看成一个新插入的节点N1,再进行第二次变换。

正在上传…重新上传取消

image-20200303180603741

第二次变换:符合情况3

  • 父节点5和叔节点9变为黑,祖父节点7变为红;即由图 b -> 图 c 。

变换之后发现根节点7为红色不符合规则2,所以把以7为根节点的红黑树看成一个新插入的节点N2,再进行第三次变换。

第三次变换:符合情况1

  • 直接将根节点7变为黑色即可。

正在上传…重新上传取消

image-20200303181133397

由此,完成了1~10节点的插入,虽然没有遇到情况5,不过情况5经过左旋转的操作便可转换为情况4,原理一样。如下图所示,将这棵红黑树的叶子节点NIL补全之后,经检验满足红黑树的五条规则,并且基本属于平衡树,效率较高。

正在上传…重新上传取消

image-20200303182326442

四、红黑树的删除操作

红黑树的删除操作结合了复杂的二叉树的删除操作和复杂的红黑树的插入规则,整体来说难度非常大,篇幅较长,这里暂不进行探讨。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值