【问题标题】:Avl tree left rotation & left-right rotation usage confusionAvl树左旋转&左右旋转使用混淆
【发布时间】:2015-12-22 12:31:00
【问题描述】:

假设我们有以下结构:

        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

那么,为什么在这种情况下,即使是左右旋转也能提供平衡的树,但我们只需要进行左旋转呢?

【问题讨论】:

  • 没有发生单一的左旋转。这没有意义,因为树需要在右侧重新平衡
  • 你说的右转,我说的就是左转。
  • 好的。顺时针=右。逆时针 = 左。我就是这样学的,因为那是节点移动的方向

标签: algorithm binary-search-tree avl-tree


【解决方案1】:

混淆源于他们在大多数 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 

【讨论】:

    【解决方案2】:

    只需要“左”旋转的原因是因为节点 A 的平衡因子是第一个满足再平衡标准的节点。

    将每个子树视为一个尺度上的权重,其中这些权重的“权重”就是子树的“高度”。

    删除后,B、E、D 平衡。

    A 的右子树的“权重”为 0,左子树的“权重”为 2。

    这个差值大于 1,朝向左子树。由于左子树是平衡的,因此只需要在 A 处向右子树进行一次旋转。

    【讨论】:

    • 那么,我们选择 L 而不是 LR 的唯一原因是因为 LR 涉及 2 个旋转,而 L 只涉及一个?
    • 不一定。只需要一次旋转的原因是因为与旋转方向相反的子树是平衡的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-23
    • 1970-01-01
    相关资源
    最近更新 更多