平衡二叉树之二(删除节点) .

类似于添加操作,从平衡二叉树中删除节点也分为两步,第一步完成节点的删除,第二步找到因为删除而导致不满足平衡二叉树要求的子树并对其进行调整。

一、 删除节点

从平衡二叉树中删除节点更为复杂。首先第一步需要找到要删除的节点x,并分情况进行处理:

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

在找到要删除的节点后下一步就是删除节点,假设要删除的节点为delete,其父节点为parent,显然此时delete要么是一个叶子节点,要么是一个只有一棵子树的节点:

  • 如果delete是一个叶子节点,则直接删除它
  • 如果delete是一个只有一棵子树的节点,则将delete删除,delete节点的子树的根将成为parent的子节点

无论是这两种情形中的哪一种都会导致节点parent的以delete节点为根节点的子树的高度降低,因此下一步就是处理高度降低的影响。假设删除节点导致以节点A为根的子树的高度降低了,并且A的父节点为B则:

  • 如果B为NULL,即A已经为根节点,则删除完成
  • 否则考察B的平衡因子:
    • 平衡因子为0,只需要调整平衡因子即可完成删除
    • 平衡因子表示以A为子树的根的高度较高,则B的新的平衡因子为0,以B为根的子树的高度降低,需要回溯往前继续处理高度降低的影响
    • 平衡因子表示以A为子树的根的高度较矮,则以B为根的子树违背了平衡二叉树的要求,需要对以B为根的子树进行调整,如果调整完后得到的新的子树的高度和原来以B为根的子树的高度相同,则删除完成,否则新得到的子树的高度与原来的以B为根的子树的高度相比必然是减小了,因而还需要继续往前回溯处理高度降低的影响

比如要下从下图中删除节点20

《平衡二叉树之二(删除节点) .》

首先找到替换20被删除的节点15,并将二者内容替换,如下图所示:

《平衡二叉树之二(删除节点) .》

然后删除节点20得到下图:

《平衡二叉树之二(删除节点) .》

在删除节点20后,节点10违反了平衡二叉树的性质,对以10为根节点的子树进行调整(类似于插入时,需要先做一次左旋再做一次右旋)可得下图:

《平衡二叉树之二(删除节点) .》

二、删除中的调整

删除节点时的调整基本上类似于插入时的调整,但是也有些区别,以从节点A的左子树删除节点导致其左子树高度降低而需要调整为例进行分析。并分以下情况:

2.1 A的右子树的平衡因子为-1

该情形如下图所示:

《平衡二叉树之二(删除节点) .》

该情形很简单,只需要做一次左旋即可。

首先分析调整对以A为根的子树的高度的影响,显然调整后子树的高度降低了。

再分析调整对参与调整的节点的平衡因子的变化,此时只需要考虑孩子域被修改的节点,因为只有这种节点的平衡因子才会变化。在这种调整中只有A以及其右子树的根节点的孩子域会发生变化,因而只需要分析它们两个的平衡因子的变化(以上图为例来分析,要分析的两个节点为20,30):

  • 假设以节点20为根的子树的高度为h1,则删除节点前:
    • 由于节点20的平衡因子为-1(否则从左子树删除节点导致其左子树高度降低就不需要进行调整),因此其右子树(以30为根节点的子树)的高度为h1-1,其左子树(以10为根节点的子树)的高度为h1-2
    • 对于节点20的右孩子节点30来说,由于它的平衡因子为-1,因此它的左子树(以25为根节点的子树)的高度为(h1-1)- 2,它的右子树(以40为根节点的子树)的高度为(h1-1)- 1
  • 删除节点后:
    • 节点20的左子树(以10为根节点的子树)的高度变为h1-2 -1
  • 调整后
    • 节点10和节点25分别成为节点20的左右子树,分别以二者为根的子树的高度差为h1 – 2 – 1 – ((h1-1)- 2) = 0
    • 以节点20为根节点的子树的高度为h1-2 -1 + 1
    • 节点20和节点40分别成为节点30的左右子树,分别以二者为根的子树的高度差为(h1-2 -1 + 1) –  ( (h1-1)- 1 ) = 0

因而该种情形的最终结果是子树高度降低,参与调整的节点A以及其右子树的根节点在调整后的平衡因子都为0,其它节点平衡因子不变。

2.2 A的右子树的平衡因子为0

该情形如下图所示:

《平衡二叉树之二(删除节点) .》

类似于上一种情形,该情形只需要做一次左旋即可。

首先分析调整对以A为根的子树的高度的影响,显然调整后子树的高度不变。

再分析调整对参与调整的节点的平衡因子的变化,此时只需要考虑孩子域被修改的节点,因为只有这种节点的平衡因子才会变化。在这种调整中只有A以及其右子树的根节点的孩子域会发生变化,因而只需要分析它们两个的平衡因子的变化(以上图为例来分析,要分析的两个节点为20,30):

  • 假设以节点20为根的子树的高度为h1,则删除节点前:
    • 由于节点20的平衡因子为-1(否则从左子树删除节点导致其左子树高度降低就不需要进行调整),因此其右子树(以30为根节点的子树)的高度为h1-1,其左子树(以10为根节点的子树)的高度为h1-2
    • 对于节点20的右孩子节点30来说,由于它的平衡因子为0,因此它的左右子树(以25为根节点的子树和以40为根节点的子树)的高度都为(h1-1)- 1
  • 删除节点后:
    • 节点20的左子树(以10为根节点的子树)的高度变为h1-2 -1
  • 调整后
    • 节点10和节点25分别成为节点20的左右子树,分别以二者为根的子树的高度差为h1 – 2 – 1 – ((h1-1)- 1) = -1
    • 以节点20为根节点的子树的高度为h1-1 -1 + 1
    • 节点20和节点40分别成为节点30的左右子树,分别以二者为根的子树的高度差为(h1- 1 -1 + 1) –  ( (h1-1)- 1 ) = 1

因而该种情形的最终结果是子树高度不变,参与调整的节点A以及其右子树的根节点在调整后的平衡因子分别为-1,1,其它节点平衡因子不变。

2.3 A的右子树的平衡因子为1

该情形如下图所示:

《平衡二叉树之二(删除节点) .》

和前两种情形不同,该种情形下需要做两次调整,一次右旋、一次左旋。

首先分析调整对以A为根的子树的高度的影响,调整后子树的高度降低。

再分析调整对参与调整的节点的平衡因子的变化,此时只需要考虑孩子域被修改的节点,因为只有这种节点的平衡因子才会变化。在这种调整中只有A,A的右孩子,A的右孩子的左孩子的孩子域会发生变化,因而只需要分析它们的平衡因子的变化(以上图为例来分析,要分析的三个节点为20,30,25):

  • 假设以节点20为根的子树的高度为h1,则删除节点前:
    • 由于节点20的平衡因子为-1(否则从左子树删除节点导致其左子树高度降低就不需要进行调整),因此其右子树(以30为根节点的子树)的高度为h1-1,其左子树(以10为根节点的子树)的高度为h1-2
    • 对于节点20的右孩子节点30来说,由于它的平衡因子为1,因此它的左子树(以25为根节点的子树)的高度为h1-1-1,它的右子树(以40为根节点的子树)的高度为(h1-1)- 2
  • 删除节点后:
    • 节点20的左子树(以10为根节点的子树)的高度变为h1-2 -1
  • 调整后,节点10和节点25的左孩子分别成为节点20的左右子树,节点25的右孩子和节点40分别成为节点30的左右孩子,节点20和节点30分别成为节点25(即新的根)的左右子树。则:
    • 如果节点10不存在,即删除节点后20的左子树消失,则此种情形下,删除完节点后,节点23,25,40都不能存在,调整完后三者平衡因子都为0
    • 如果节点10存在,则节点25的左右子树至少有一个不能为空,此时:
      • 如果删除前节点25的平衡因子为1,则此时
        • 节点20的平衡因子为: “以节点10为根的子树的高度 – 以节点25的左孩子为根的子树的高度”= h1-2 -1 – ((h1 -1 -1) -1)= 0
        • 节点30的平衡因子为: “以节点25的右孩子为根的子树的高度 – 以节点40为根的子树的高度”= ((h1-1-1)- 2)- ((h1 -1) – 2)= -1
        • 节点25的平衡因子为:“以节点20为根的子树的高度 – 以节点30为根的子树的高度”= ((h1-2 -1) + 1)- (((h1 -1) – 2 )+ 1) = 0
      • 如果删除前节点25的平衡因子为0,则此时:
        • 节点20的平衡因子为: “以节点10为根的子树的高度 – 以节点25的左孩子为根的子树的高度”= h1-2 -1 – ((h1 -1 -1) -1)= 0
        • 节点30的平衡因子为: “以节点25的右孩子为根的子树的高度 – 以节点40为根的子树的高度”= ((h1-1-1)- 1)- ((h1 -1) – 2)= 0
        • 节点25的平衡因子为:“以节点20为根的子树的高度 – 以节点30为根的子树的高度”= ((h1-2 -1) + 1)- (((h1 -1) – 2 )+ 1) = 0
      • 如果删除前节点25的平衡因子为-1,则此时:
        • 节点20的平衡因子为: “以节点10为根的子树的高度 – 以节点25的左孩子为根的子树的高度”= h1-2 -1 – ((h1 -1 -1) -2)= 1
        • 节点30的平衡因子为: “以节点25的右孩子为根的子树的高度 – 以节点40为根的子树的高度”= ((h1-1-1)- 1)- ((h1 -1) – 2)= 0 
        • 节点25的平衡因子为:“以节点20为根的子树的高度 – 以节点30为根的子树的高度”= ((h1-2 -1) + 1)- (((h1 -1) – 2 )+ 1) = 0

因而该种情形的最终结果是子树高度降低,假设被调整的子树的根节点为A,其右孩子为B,B的左孩子为C,则调整后A,B,C的平衡因子分别为:

  • C的平衡因子为0
  • 如果删除前C的平衡因子为0,则A和B的平衡因子为0
  • 如果删除前C的平衡因子为1,则A的平衡因子为0,B的平衡因子为-1
  • 如果删除前C的平衡因子为-1,则A的平衡因子为1,B的平衡因子为0

从右子树删除和从左子树是对称的。

从上述分析可以看出从平衡二叉树中删除节点的时间复杂度和添加相同也是O(logn)

 

 

http://blog.csdn.net/goodluckwhh/article/details/11786079

    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/lanyanjiayu/article/details/17584209
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞