假设我们有以下结构:
A
/ \
B C
/ \
D E
现在,如果要删除C,
A
/
B
/ \
D E
此时,我查看的每个算法都会进行以下检查:
if (Balance-Factor(B)>=0) do **Left** rotation
else do **Left-Right** rotation;
但是,为什么这个条件必须在这里举行?如果我在上面的树上进行左右旋转,似乎我仍然得到一棵平衡的树:
E
/ \
B A
/
D
那么,为什么我们必须在左右旋转时甚至左右为我们提供一个平衡的树?
答案 0 :(得分:0)
只有"离开"需要轮换是因为节点A处的平衡因子是满足重新平衡标准的第一个节点。
将每个子树视为一个刻度上的权重,其中"权重"这些重量是"身高"子树。
删除后,B,E和D均衡。
A的右子树有"权重" 0,左子树有"权重" 2.
这个差异大于1,朝向左子树。由于左子树是平衡的,因此在右子树上只需要在A处旋转一次。
答案 1 :(得分:0)
大多数avl教程中的轮换名称都是出于混淆。
命名:LL,RR,LR,RL
情况:L,R,LL,RR,LR,RL
大多数avl教程排除单个旋转的命名的可能原因是,因为单个旋转可以使用LL和RR代码。基本上,这2个单旋转代码是其相应双打的一部分。
换句话说,如果正确编写了LL和RR代码,它们也可以用于单次旋转。
在您的示例中,情况是单次旋转。
使用LL代码的L旋转。
这就是您不得使用LR代码的原因。
因为这种情况一开始甚至没有两次旋转。
证明:
A
/ \
B G
/ \ \
C E H
/ \
D F
删除H:
A
/ \
B G
/ \
C E
/ \
D F
随着LR旋转:
E
/ \
B A
/ / \
C F G
/
D
Remains UnBalanced
通过LL旋转:
B
/ \
C A
/ / \
D E G
\
F
Is Balanced