news 2026/4/1 16:41:12

在平衡二叉树(AVL 树)中,双旋转和删除操作是维持树结构平衡的关键机制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
在平衡二叉树(AVL 树)中,双旋转和删除操作是维持树结构平衡的关键机制

在平衡二叉树(AVL 树)中,双旋转和删除操作是维持树结构平衡的关键机制。当插入或删除节点导致树失衡时,需根据具体失衡类型进行相应的旋转调整。

1. 双旋转平衡处理

先左后右双旋转(LR 型)
  • 场景:节点 A 的平衡因子为 1(左子树高),在其左子树的右子树中插入新节点,使 A 的平衡因子变为 2,树失衡。
  • 操作步骤
    1. 对 A 的左子节点 B 的右子树进行左旋(即以 B 的右子树根节点 C 为轴向左旋转),将插入点“上提”,转化为 LL 型;
    2. 再对节点 A 进行右旋,恢复整体平衡。
  • 本质:通过两次旋转将插入引发的“折线型”不平衡转变为直线型并修复。
先右后左双旋转(RL 型)
  • 场景:节点 A 的平衡因子为 -1(右子树高),在其右子树的左子树中插入新节点,使 A 的平衡因子变为 -2。
  • 操作步骤
    1. 对 A 的右子节点 D 的左子树进行右旋(以 E 为轴向右旋转);
    2. 再对 A 进行左旋,恢复平衡。
  • 目的:消除“折线型”失衡,转化为 RR 型后再处理。

2. 平衡二叉树的删除操作

  • 核心逻辑

    • 若被删节点有两个子树,则用其左子树中序遍历的最后一个节点(即左子树的最大值)或右子树中序遍历的第一个节点(即右子树的最小值)替代之,从而将问题转化为删除只有一个子树的节点。
    • 删除后,从被删节点位置沿路径向上回溯至根节点,逐层更新各节点的平衡因子
    • 若某节点的平衡因子变为 ±2,则判断其失衡类型(LL、RR、LR、RL),执行对应单旋或双旋操作重新平衡。
    • 旋转后可能缩短子树高度,需继续检查祖先节点是否仍平衡,直至整条路径处理完毕。
  • 时间复杂度:每次插入/删除最多引发 O(log n) 次旋转(实际通常仅需常数次),整体仍保持 O(log n)。


补充说明

AVL 树通过严格的平衡条件确保查找效率最优,但频繁的旋转增加了插入删除开销,适用于查询远多于修改的场景。后续如红黑树等结构在平衡性与维护成本之间做了折中。

# 示例:模拟 LR 型双旋转(简化示意)defrotate_LR(A):B=A.left C=B.right# 左旋 B 的右子树B.right=C.left C.left=B A.left=C# 右旋 Areturnrotate_right(A)defrotate_right(A):B=A.left A.left=B.right B.right=AreturnB

判断一个节点属于 LL、RR、LR 或 RL 失衡类型,关键在于分析失衡节点的平衡因子以及其子树中导致失衡的插入(或删除)位置。以下是具体判断方法:


1. 前提条件

  • 某节点 A 的平衡因子变为+2 或 -2,说明以 A 为根的子树失衡。
  • 需根据 A 的子树结构进一步判断是哪种类型。

2. 判断规则

(1)LL 型(Left-Left)
  • 表现:A 的平衡因子为+2,且其左子节点 B 的平衡因子为+1
  • 原因:新节点插入在 A 的左子树的左子树
  • 形态
A (+2) / B (+1) / C
  • 处理方式:对 A 执行右旋(单旋)

(2)RR 型(Right-Right)
  • 表现:A 的平衡因子为-2,且其右子节点 D 的平衡因子为-1
  • 原因:新节点插入在 A 的右子树的右子树
  • 形态
A (-2) \ D (-1) \ E
  • 处理方式:对 A 执行左旋(单旋)

(3)LR 型(Left-Right)
  • 表现:A 的平衡因子为+2,但其左子节点 B 的平衡因子为-1
  • 原因:新节点插入在 A 的左子树的右子树
  • 形态
A (+2) / B (-1) \ C
  • 处理方式:先对 B 做左旋,再对 A 做右旋(双旋转)

(4)RL 型(Right-Left)
  • 表现:A 的平衡因子为-2,但其右子节点 D 的平衡因子为+1
  • 原因:新节点插入在 A 的右子树的左子树
  • 形态
A (-2) \ D (+1) / C
  • 处理方式:先对 D 做右旋,再对 A 做左旋(双旋转)

总结口诀(便于记忆):

类型平衡因子(根)子节点平衡因子插入路径旋转方式
LL+2+1左 → 左右旋(单)
RR-2-1右 → 右左旋(单)
LR+2-1左 → 右先左后右(双)
RL-2+1右 → 左先右后左(双)

⚠️ 注意:删除操作也可能引发上述失衡,判断方式相同,但可能需要沿路径持续调整多个祖先节点。

# 判断失衡类型的伪代码示意defget_balance_type(node):bf=get_balance_factor(node)ifbf==2:left_bf=get_balance_factor(node.left)ifleft_bf==1:return"LL"elifleft_bf==-1:return"LR"elifbf==-2:right_bf=get_balance_factor(node.right)ifright_bf==-1:return"RR"elifright_bf==1:return"RL"return"Balanced"

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/30 23:09:28

哈希表是一种基于映射关系的存储结构,其核心是哈希函数 $ H(key) $,它将任意关键字转换为地址空间内的索引值,从而实现快速存取

B-树的插入与删除操作需严格维护其结构平衡性。在插入时,首先将关键字插入到合适的叶节点中,若该节点关键字数量超过上限 $ m-1 $,则进行“分裂”:取中间关键字上移至父节点,原节点以中间关键字为界拆分为两个子节点。…

作者头像 李华
网站建设 2026/3/30 23:41:32

C++网络模块设计实战(兼容性增强秘籍)

第一章:C网络模块设计的核心挑战在构建高性能、高可靠性的C网络应用时,网络模块的设计面临诸多底层技术挑战。这些挑战不仅涉及并发模型的选择,还包括资源管理、错误处理和跨平台兼容性等多个方面。异步I/O与事件驱动架构 现代网络服务需同时…

作者头像 李华
网站建设 2026/3/27 20:36:51

组件化设计 vs 继承体系,哪种更适合C++游戏引擎的长期扩展?

第一章:C游戏引擎扩展性的核心挑战在现代游戏开发中,C 依然是构建高性能游戏引擎的首选语言。然而,随着项目规模的增长,如何保持引擎的可扩展性成为开发者面临的核心难题。一个优秀的游戏引擎不仅要满足当前功能需求,还…

作者头像 李华
网站建设 2026/3/27 6:32:52

深入LLVM后端优化(Clang 17性能调优全解析)

第一章:深入LLVM后端优化(Clang 17性能调优全解析)在现代C开发中,Clang 17结合LLVM后端提供了强大的编译时优化能力。通过精细控制代码生成与优化策略,开发者能够在不修改源码的前提下显著提升程序性能。LLVM的模块化设…

作者头像 李华
网站建设 2026/3/31 18:20:07

谷歌镜像网站访问困难?这里提供HunyuanOCR替代下载通道

腾讯HunyuanOCR:轻量级端到端OCR的国产化新选择 在企业数字化转型加速推进的今天,文档信息提取早已不再是“能不能识别文字”的问题,而是“能否快速、准确、安全地完成结构化解析”的挑战。尤其是在跨境办公、政务处理和金融合规等场景中&am…

作者头像 李华
网站建设 2026/3/30 8:25:55

PHP网站添加OCR功能?HunyuanOCR为传统系统赋能

PHP网站添加OCR功能?HunyuanOCR为传统系统赋能 在企业数字化转型的浪潮中,许多基于PHP构建的传统Web系统——比如老旧的内容管理系统、表单提交平台或内部管理后台——正面临一个尴尬的现实:它们每天处理大量扫描件、发票截图、身份证照片甚至…

作者头像 李华