平衡二叉树

来源:互联网 发布:python取随机数 编辑:程序博客网 时间:2024/06/04 01:19

若向平衡二叉树中插入一个新结点后破坏了平衡二叉树的平衡性。首先要找出插入新结点后失去平衡的最小子树根结点的指针。然后再调整这个子树中有关结点之间的链接关系,使之成为新的平衡子树。当失去平衡的最小子树被调整为平衡子树后,原有其他所有不平衡子树无需调整,整个二叉排序树就又成为一棵平衡二叉树。

失去平衡的最小子树是指以离插入结点最近,且平衡因子绝对值大于 1 的结点作为根的子树。假设用 A 表示失去平衡的最小子树的根结点,则调整该子树的操作可归纳为下列四种情况。

1 LL 型平衡旋转法

由于在 A 的左孩子 B 的左子树上插入结点 F ,使 A 的平衡因子由 1 增至 2 而失去平衡。故需进行一次顺时针旋转操作。 即将 A 的左孩子 B 右上旋转代替A作为根结点, A 右下旋转成为B的右子树的根结点。而原来 B 的右子树则变成 A 的左子树。

2 RR 型平衡旋转法

由于在 A 的右孩子 的右子树上插入结点 F ,使A的平衡因子由 -1 减至 -2而失去平衡。故需进行一次逆时针旋转操作。即将A的右孩子 C 左上旋转代替A作为根结点, A 左下旋转成为C的左子树的根结点。而原来 C 的左子树则变成 A 的右子树。

3 LR 型平衡旋转法

由于在 A 的左孩子 B 的右子数上插入结点 F ,使 A 的平衡因子由 1 增至 2 而失去平衡。故需进行两次旋转操作(先逆时针,后顺时针)。即先将 A结点的左孩子B 的右子树的根结点 D 左上旋转提升到B结点的位置,然后再把该 D 结点向右上旋转提升到A结点的位置。即先使之成为 LL型,再按LL 型处理

如图中所示,即先将圆圈部分先调整为平衡树,然后将其以根结点接到 A 的左子树上,此时成为 LL 型,再按 LL型处理成平衡型。

4 RL 型平衡旋转法

由于在 A 的右孩子 C 的左子树上插入结点 F ,使 A 的平衡因子由 -1 减至 -2 而失去平衡。故需进行两次旋转操作(先顺时针,后逆时针),即先将 A结点的右孩子C 的左子树的根结点 D 右上旋转提升到C结点的位置,然后再把该 D 结点向左上旋转提升到A结点的位置。即先使之成为 RR型,再按RR 型处理。

如图中所示,即先将圆圈部分先调整为平衡树,然后将其以根结点接到A的左子树上,此时成为 RR 型,再按 RR型处理成平衡型。

平衡化靠的是旋转。参与旋转的是3 个节点(其中一个可能是外部节点 NULL),旋转就是把这3 个节点转个位置。注意的是,左旋的时候 p->right一定不为空,右旋的时候p->left 一定不为空,这是显而易见的。

如果从空树开始建立,并时刻保持平衡,那么不平衡只会发生在插入删除操作上,而不平衡的标志就是出现bf == 2或者  bf == -2 的节点。