<p>平衡因子需在插入/删除后沿路径自底向上动态更新:节点结构冗余存储height,回溯时用左右子树新高度直接计算bf = left_height - right_height;bf为±2时触发旋转,仅重设旋转涉及的2~3个节点height和bf,其余不变。</p>

平衡因子怎么在插入/删除时实时更新
平衡因子(balance factor)是左子树高度减右子树高度,必须在每次节点增删后立刻重算——但不能每次都递归求高,否则单次操作退化到 O(n)。正确做法是:在节点结构里额外存 height 字段,用后序方式自底向上更新。
关键点在于:从被修改的叶子一路回溯到根,每层只做一次加法比较:
node->height = 1 + max(left_height, right_height)-
node->bf = left_height - right_height(直接复用刚算出的左右高) - 只有
bf变成 ±2 时才触发旋转,其余情况无需干预
四种旋转场景怎么对应具体 bf 组合
不是看单个节点的 bf,而是结合“失衡节点”和“其子节点的 bf”共同判断。假设 node 失衡(bf == 2 || bf == -2),则:
-
node->bf == 2 && node->left->bf >= 0→right_rotate(node)(LL) -
node->bf == 2 && node->left->bf == -1→ 先left_rotate(node->left),再right_rotate(node)(LR) node->bf == -2 && node->right->bf → <code>left_rotate(node)(RR)-
node->bf == -2 && node->right->bf == 1→ 先right_rotate(node->right),再left_rotate(node)(RL)
注意:== 0 在 LL/RR 中允许,但在 LR/RL 中必须严格区分 1 和 -1,否则旋转后仍可能失衡。
立即学习“C++免费学习笔记(深入)”;
旋转后哪些节点的 height 和 bf 必须重算
旋转只改变局部拓扑,仅涉及的 2~3 个节点需要更新 height 和 bf,其余全都不动。例如 right_rotate(A)(A 原为根,B 为左子):
- 先更新
B->height和A->height(因为子树结构变了) - 再算
B->bf和A->bf(依赖新子树高度) -
B的原右子、A的原左子(即B->right)的高度没变,不重算
漏掉任一节点的 height 更新,后续所有 bf 都会错;但多算无关节点,只会白耗 CPU。
为什么不能在 insert 里边插边调,而要分两步走
常见错误是在递归 insert 过程中,每层都检查并立即旋转。这会导致两个问题:
- 旋转后父指针未及时修正(尤其在递归返回途中),造成链表断裂或野指针
- 某次旋转修复了局部失衡,但上层因高度变化再次失衡,而你已经跳出当前递归,错过处理
正确顺序是:先完成完整插入(含所有 height 初步更新),再单独走一遍回溯路径,对每个节点检查 bf,遇 ±2 就旋转并重新计算涉及节点的 height,然后继续向上——旋转本身可能改变更高层的高度,所以必须沿同一路径走到底。
真正容易被忽略的是:旋转函数内部必须返回新的子树根(比如 right_rotate 后返回 B),且调用处必须用该返回值更新父节点的对应子指针,否则整棵树逻辑断裂。


















