55.平衡二叉树

题目描述

输入一棵二叉树,判断该二叉树是否是平衡二叉树。

class Solution {
public:
    bool IsBalanced_Solution(TreeNode* pRoot) {
        if(!pRoot) return true;
        int C1 = TreeDepth(pRoot->left);
        int C2 = TreeDepth(pRoot->right);
        if(abs(C1-C2)>1)return false;
        bool p1 = IsBalanced_Solution(pRoot->left); 
        bool p2 = IsBalanced_Solution(pRoot->right);
        return p1 && p2;
    }
    int TreeDepth(TreeNode* pRoot)
    {
        if (!pRoot)return 0;
        int pLeft = TreeDepth(pRoot->left);
        int pRight = TreeDepth(pRoot->right);
        return max(TreeDepth(pRoot->left)+1,TreeDepth(pRoot->right)+1);
    }
};

自底向上算法没弄明白

<think>好的,我现在需要解释平衡二叉树的删除操作。首先,我得回忆一下平衡二叉树的基本概念,特别是AVL树,因为平衡二叉树通常指的是AVL树。AVL树在删除节点后可能需要通过旋转来重新平衡树的结构,确保左右子树的高度差不超过1。 用户的问题是关于删除的步骤,所以应该分步骤讲解。首先,可能需要介绍删除的一般步骤,类似于普通二叉搜索树的删除,然后再引入平衡调整的部分。不过,用户可能已经了解二叉搜索树的删除,所以可以简略提一下,重点放在平衡处理上。 删除节点时,需要考虑三种情况:被删除的节点是叶子节点、有一个子节点、或者有两个子节点。这部分可能需要详细说明,尤其是如何处理有两个子节点的情况,通常会用后继节点来替代,然后删除后继节点。 接下来是关键的平衡调整部分。删除节点后,从被删除节点的父节点开始向上回溯,检查每个祖先节点的平衡因子。如果某个节点的平衡因子绝对值超过1,就需要进行旋转操作。旋转的类型包括左旋、右旋、左右旋、右左旋四种情况,需要根据不平衡的情况来选择正确的旋转方式。 这里可能需要分别讨论四种旋转情况,比如当左子树过高时是LL还是LR型,右子树过高时是RR还是RL型。需要明确每种情况对应的旋转方法,并举例说明。例如,如果在某个节点发现左子树比右子树高2,且左子树的左子树更高,那么需要进行右旋(LL型)。如果是左子树的右子树更高,则需要先左旋再右旋(LR型)。 同时,需要注意删除操作可能导致多个祖先节点失衡,因此需要一直向上检查直到根节点。这一点和插入操作不同,插入可能只需要一次调整,而删除可能需要多次调整。 此外,可能还需要解释平衡因子的更新方式,以及旋转过程中如何调整各个节点的平衡因子。这部分比较复杂,可能需要用图示或者具体例子来说明,但因为是文本回答,需要用文字详细描述。 可能遇到的疑问是,如何处理删除后的平衡因子的更新和旋转的具体步骤。例如,当删除一个节点后,其父节点的平衡因子变为2,这时候应该如何旋转。需要具体说明不同情况下的处理方式。 另外,用户可能想知道删除操作的时间复杂度。因为AVL树的高度是O(log n),删除操作需要O(log n)的时间,包括查找节点、删除节点、以及回溯调整平衡的时间。 最后,总结整个删除过程,强调平衡调整的重要性,确保树保持平衡,从而维持高效的查找性能。可能还需要指出与插入操作的不同之处,比如删除可能需要多次旋转,而插入通常只需要一次或两次旋转。 现在需要将这些思路整理成一个结构清晰的回答,分步骤说明删除的过程,重点放在平衡调整的四种情况和对应的旋转方法。同时,使用中文,避免使用Markdown格式,行内公式用$...$,独立公式用$$...$$,并确保LaTeX语法正确。</think>平衡二叉树的删除操作需要兼顾二叉搜索树性质和平衡性维护。以AVL树为例,删除步骤如下: 一、标准BST删除 1. 定位节点:查找待删除节点$N$ 2. 处理子节点: - 无子节点:直接删除 - 单子节点:用子树替换当前节点 - 双子节点:找到后继节点$S$(右子树最左节点),复制$S$的值到$N$,转为删除$S$ 二、平衡调整(回溯路径检查) 从被删除节点的父节点开始向上回溯,对每个祖先节点$P$执行: 1. 更新高度 $$ height(P) = 1 + \max(height(left), height(right)) $$ 2. 计算平衡因子 $$ balance = height(right) - height(left) $$ 3. 处理失衡(四种情况): - 左左失衡(balance ≤ -2且左子树平衡因子 ≤ 0) ``` P(-2) L / \ / \ L C 右旋 A P / \ ===> / \ A B B C ``` - 左右失衡(balance ≤ -2且左子树balance > 0) ``` P(-2) P(-2) B / \ / \ / \ L C 左旋左子树 B C 右旋 L P / \ ===> / \ ===> / \ / \ A B L Br A Bl Br C \ / Br A ``` - 右右失衡(balance ≥ 2且右子树balance ≥ 0) ``` P(2) R \ \ \ R C 左旋 P E \ \ ===> \ B E B ``` - 右左失衡(balance ≥ 2且右子树balance < 0) ``` P(2) P(2) B \ \ \ \ / \ R C 右旋右子树 B C 左旋 P R / ===> \ ===> \ / \ B R Br Bl C \ / Br Br $$ 三、时间复杂度 删除操作时间复杂度为$O(\log n)$,其中: - 查找节点:$O(\log n)$ - 删除操作:$O(1)$ - 平衡调整:最坏$O(\log n)$(需回溯到根节点) 关键特点: 1. 删除可能导致多个祖先节点失衡,需逐层调整 2. 平衡因子更新必须精确,旋转后需重新计算子树高度 3. 与插入操作相比,删除可能需要更多次旋转(最多$\log n$次) 示例:删除节点后触发右左旋转的情况 ``` 原始树结构: 30 / \ 20 40 / \ 35 50 \ 55 删除35后: 30(-2) / \ 20 40(2) \ 50(1) \ 55 调整过程: 1. 40节点失衡(balance=2) 2. 检查右子树50的平衡因子=1(右右情况) 3. 对40执行左旋: 30(-2) / \ 20 50 / \ 40 55 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值