平衡AVL树

时间:2013-01-19 21:42:23

标签: data-structures tree rotation binary-search-tree avl-tree

我在平衡AVL树时遇到了麻烦。我已经搜索了高低不同的步骤,以便如何平衡它们,我只是无法获得任何有用的东西。

我知道有4种:

  • 单左旋转
  • 单右旋转
  • 双左右旋转
  • 双左右旋转

但我无法如何选择中的哪一个将哪个节点应用于

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

这是java实现,您将在那里了解算法:

private Node<T> rotate(Node<T> n) {
    if(n.getBf() < -1){
            if(n.getRight().getBf() <= 0){
                return left(n);         
            }
            if(n.getRight().getBf() > 0){
                return rightLeft(n);
            }
    }   
    if(n.getBf() > 1){
            if(n.getLeft().getBf() >= 0){
                return right(n);
            }
            if(n.getLeft().getBf() <  0){
                return leftRight(n);
            }
    }
    return n;
}

4轮的单独方法如下:

/**
 * Performs a left rotation on a node
 * 
 * @param n The node to have the left rotation performed on
 * @return The new root of the subtree that is now balanced due to the rotation
 */
private Node<T> left(Node<T> n) {
    if(n != null){
        Node<T> temp = n.getRight();
        n.setRight(temp.getLeft());
        temp.setLeft(n);
        return temp;
    }
    return n;   
}

/**
 * Performs a right rotation on a node
 * 
 * @param n The node to have the right rotation performed on
 * @return The new root of the subtree that is now balanced due to the rotation
 */
private Node<T> right(Node<T> n) {
    if(n != null){
        Node<T> temp = n.getLeft();
        n.setLeft(temp.getRight());
        temp.setRight(n);
        return temp;
    }
    return n;
}

/**
 * Performs a left right rotation on a node
 * 
 * @param n The node to have the left right rotation performed on
 * @return The new root of the subtree that is now balanced due to the rotation
 */
private Node<T> leftRight(Node<T> n) {
    n.setLeft(left(n.getLeft()));
    Node<T> temp = right(n);
    return temp;
}

/**
 * Performs a right left rotation on a node
 * 
 * @param n The node to have the right left rotation performed on
 * @return The new root of the subtree that is now balanced due to the rotation
 */
private Node<T> rightLeft(Node<T> n) {
    n.setRight(right(n.getRight()));
    Node<T> temp = left(n);
    return temp;
}

答案 1 :(得分:0)

AVL树中的键不变量是每个节点的平衡因子是-1,0或+1。这里,“平衡因子”是左右子树之间的高度差。 +1表示左子树比右子树高1,-1表示左子树比右子树短1,0表示子树大小相同。此信息通常缓存在每个节点中。

当您获得平衡系数为-2或+2的节点时,您需要进行旋转。这是一个可能需要轮换的设置:

          u (-2)
         / \
        A   v (-1)
           / \
          B   C

如果我们填写这些树的高度,我们得到

          u h + 2
         / \
    h-1 A   v h + 1
           / \
      h-1 B   C h

如果发生这种情况,执行一次正确的轮换会产生

         v h+1
        / \ 
     h u   C h
      / \
 h-1 A   B h-1

嘿!树是平衡的。这棵树的镜像也可以通过一次左旋转来固定。

所有AVL树旋转都可以简单地通过列举小范围内的可能平衡因子然后确定应在每个步骤应用哪些旋转来确定。我会将此作为练习留给读者。 :-)如果你只是想查找答案,Wikipedia article on AVL trees有一个很好的图片,总结了可能需要应用的所有轮换。

希望这有帮助!