平衡二叉树的删除

 

网上关于平衡二叉树的删除操作,实在太少了,找到了一遍好文章,特转载到CSDN,当做笔记
平衡二叉树原文

平衡二叉树的删除

平衡二叉树是最优的二叉排序树,因此删除操作,也和二叉排序树的删除差不多,只是在删除完节点后,要重新判断左右孩子的深度,如果失衡,就要调整

 

平衡二叉树删除节点的三种情况

① 被删除的节点为叶子节点,就找到了要删除的节点

② 被删除的节点有左子树或者右子树

③ 被删除的节点既有左子树,又有右子树

我们需要知道这么一点,左子树上节点的删除相当于我们在右子树上插入了一个新节点,右子树上节点的删除相当于在左子树上插入了一个新节点,根据这一点,我们进行判断并采取对应的平衡调整操作。

 

删除叶子节点

我们来看例子1:
在这里插入图片描述
我们删除14节点,递归返回
返回到双亲节点10,判断节点的10的左右深度,发现节点10的平衡因子是1,因此不用做调整,递归返回
返回到根结点20,判断节点20的左右深度,发现节点20的平衡因子是-1,因此不用做调整
所以,调整后,不用做任何调整,得到平衡二叉树:
在这里插入图片描述
 
我们来看例子2:
在这里插入图片描述
我们删除节点7,可以发现是个叶子节点,直接删除,得到下面这棵二叉树:
在这里插入图片描述
可以发现,原本节点7的父节点8的平衡因子为0,达到平衡。故继续向上查找,发现节点8的父节点20的左子树高度与右子树高度差值为2,也就是该节点20失衡。需要进行调整。这个地方要进行何种调整呢?我们说过,在左子树上删除节点其实就相当于在右子树上插入节点。我们找到节点20的右子树上的子节点30,发现节点30的左子树高度比右子树高,这就相当于在节点20的右子树节点30的左子树下插入了一个新的节点。这就需要进行RL型调整。先进行右旋调整,将节点30绕节点25顺时针旋转,得到下图。

图5

接下来进行左旋,得到下图,这就是调整后的树的形状。

图6

我们来看例子3:

在这里插入图片描述

我们将上图中节点8删除,得到下图:

在这里插入图片描述

可以观察到该树处于失衡状态。节点20处于平衡状态,节点25的左右子树高度差为2,需要进行调整。刚我们说过,在左子树上删除节点其实就相当于在右子树上插入节点。但要如何调整还取决于该失衡节点的右孩子的左右子树的高度差。我们找到节点20的右子树上的子节点30,发现节点30的左右子树高度一样,因此我们只需进行RR型调整,也就是左旋一次,根据节点30进行逆时针旋转。调整后的树如下:

在这里插入图片描述

故删除叶子节点的几个步骤如下:

① 将该结点直接从树中删除;
② 其父节点的子树高度的变化将导致父结点平衡因子的变化,通过向上检索并推算其父结点是否失衡;
③ 如果其父结点未失衡,则继续向上检索推算其父结点的父结点是否失衡…如此反复②的判断,直到根结点;如果向上推算过程中发现了失衡的现象,则进行④的处理;
④ 如果其父结点失衡,则判断是哪种失衡类型[LL、LR、RR、RL],并对其进行相应的平衡化处理。如果平衡化处理结束后,发现与原来以父节点为根结点的树的高度发生变化,则继续进行②的检索推算;如果与原来以父结点为根结点的高度一致时,则可说明父结点的父结点及祖先结点的平衡因子将不会有变化,因此可以退出处理。
 
 

被删的结点只有左子树或只有右子树

我们来看看例子1
在这里插入图片描述

在该平衡树中,我们要删除的节点是值为29的节点。我们用该节点的左子树替换该节点,然后删除值为29这个节点。得到树的形状如下:

在这里插入图片描述
可以看到该树已经处于平衡状态。不需要进行处理。
 

我们来看看例子2
如果我们将值为40的节点删除,先用其右子树与之替换,然后删除该节点,可以得到如下的形状:

在这里插入图片描述

接下来的操作其实也就是删除叶节点的操作。

可以发现该树失衡,删除右子树的节点相当于在左子树上插入新的节点。我们找到值为50的节点,找到其父节点,节点值为30。然后找到其左孩子,节点值为25。发现该节点的右子树比左子树高度高,也就是相当于在左子树的右子树上插入节点。因此我们这里要进行LR型调整。先进行左旋,也就是绕值为29的节点进行逆时针旋转,得到下图:

在这里插入图片描述

接下来进行右旋,得到下图。

在这里插入图片描述

因此删除节点有左子树或右子树的处理步骤如下:
① 将左子树(右子树)替代原有删除结点的位置;
② 结点C被删除后,则以C的父结点B为起始推算点,依此向上检索推算各结点(父、祖先)是否失衡;
③ 如果其父结点未失衡,则继续向上检索推算其父结点的父结点是否失衡…如此反复②的判断,直到根结点;如果向上推算过程中发现了失衡的现象,则进行④的处理;
④ 如果其父结点失衡,则判断是哪种失衡类型[LL、LR、RR、RL],并对其进行相应的平衡化处理。如果平衡化处理结束后,发现与原来以父节点为根结点的树的高度发生变化,则继续进行②的检索推算;如果与原来以父结点为根结点的高度一致时,则可说明父结点的父结点及祖先结点的平衡因子将不会有变化,因此可以退出处理

被删的结点既有左子树又有右子树

处理最初的步骤如下:

① 如果该节点的平衡因子为0或者1,则找到其左子树中具有最大值的节点max(我们只讨论有序平衡二叉树,并且有序平衡二叉树中任意一个节点的左子树上的所有节点的值小于该节点的值,右子树上所有节点的值大于该节点的值),将max的内容与x的内容交换(只替换保存的真正的数据,不替换指针,平衡因子等用于管理目的的信息),并且max即为新的要删除的节点。由于树是有序的,因而这样找到的节点要么是一个叶子节点,要么是一个没有右子树的节点。

② 如果该节点的平衡因子为-1,则找到其右节点中具有最小值的节点min,将min的内容与x的内容交换,并且min即为新的要删除的节点。由于树是有序的,因而这样找到的节点要么是一个叶子节点,要么是一个没有左子树的节点

通过上面的操作后,我们需要对值替换后的节点进行删除,根据树的性质,我们可以得到我们要输出的节点只有两种情况,叶子节点或者是只有一棵子树的节点。删除后的调整操作按照我们前面已经讲的两种方法去调整。

来看一个简单的例子:

在这里插入图片描述

我们从该平衡树中删除节点20,我们分析得到节点20的平衡因子为1,因此我们从节点20的左子树中找到最大值,最大值为节点15。我们对两个节点的值进行替换。得到的树的形状如下所示:

在这里插入图片描述

接下来删除节点20,得到下图。

在这里插入图片描述

观察,发现原先删除的节点20的父节点10的平衡因子BF=2,处于失衡状态。因此需要对以10为根节点的子树进行调整【这个地方进行删除操作时,相当于在以10为根节点的左子树的右子树上进行插入操作】,也就是进行LR调整。要先进行一次左旋操作,得到下图

再进行一次右旋操作。最后得到的树的形状如下:

在这里插入图片描述

再进行一次右旋操作。最后得到的树的形状如下:

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值