平衡二叉树(AVL Tree) | 删除操作

我们在上一篇文章中讨论了 AVL 插入。在这篇文章中,我们将采用类似的方法实现删除操作。

删除步骤:

为了确保给定的树在每次删除后保持 AVL,我们必须增加标准 BST 删除操作以执行一些重新平衡,和插入操作类似我们根据不同的情况进行左旋转或右旋转以平衡二叉树。

设 w 为要删除的节点

对 w 执行标准 的BST删除操作。

从 w 开始,向上移动并找到第一个不平衡节点。令 z 为第一个不平衡节点,y 为 z 的高度较大的子节点,x 为 y 的高度较大的子节点。注意 x 和 y 的定义与之前的插入操作不同。

通过在以 z 为根的子树上执行适当的旋转来重新平衡树。可能有 4 种可能的情况需要处理,因为 x、y 和 z 可以按 4 种方式排列。以下是可能的 4 种安排:

  1. y 是 z 的左子,x 是 y 的左子(Left Left Case)
  2. y 是 z 的左子,x 是 y 的右子(Left Right Case)
  3. y 是 z 的右子,x 是 y 的右子(Right Right Case)
  4. y 是 z 的右子,x 是 y 的左子(Right Left Case)

与插入一样,以下是上述 4 种情况下要执行的操作。请注意,与插入不同,仅平衡节点 z 不会平衡完整的 AVL 树。修复 z 后,我们可能还需要平衡z 的父级节点(证明过程可自行查阅资料并不影响接下来的阅读和理解,因此本文不多赘述)

a) 左左

b) 左右

c) 右右

 d) 右左

与插入不同,在删除中,我们在 z 处执行旋转后,我们可能必须在 z 的父级(祖先)处执行旋转。因此,我们必须继续追踪路径,直到到达根节点。 

AVL树执行删除操作的图例

 

如图所示,删除 32 后,我们向上移动并找到第一个不平衡节点,即 44。我们将其标记为 z,其较高高度的子节点为 y,即 62,y 的较高高度子节点为 x,可能是 78 或 50,因为两者都是相同的高度。我们选择78(也可以选50),现在我们所面临的就是上面提到的y 是 z 的右子,x 是 y 的右子,所以我们进行左旋转。 

算法

以标准的递归 的BST 删除操作作为基础,在递归删除后,我们以自下而上的方式一一获取指向所有祖先的指针。所以我们不需要父指针向上移动。递归代码本身向上传播并访问已删除节点的所有祖先。 

1. 执行正常的 BST 删除。 

2. 当前节点必须是已删除节点的祖先之一。更新当前节点的高度。 

3. 获取当前节点的平衡因子(左子树高度-右子树高度)。 

4. 如果平衡因子大于 1,则当前节点不平衡,我们处于左左情况或左右情况。判断是左左还是左右,获取左子树的平衡因子。如果左子树的平衡因子大于等于0,则为左左,否则为左右。 

5. 如果平衡因子小于-1,则当前节点不平衡,我们处于右右情况或右左情况。判断是右右还是右左,获取右子树的平衡因子。如果右子树的平衡因子小于等于0,则为右右,否则为右左。

推荐阅读:

平衡二叉树(AVL Tree) - 介绍及插入操作_嗅探网的博客-CSDN博客

 完整示例代码下载链接:

(包含各种语言:C语言、Python、Java,C++等均有示例)

免费​资源下载:AVL树下载地址

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值