【问题标题】:C++ tree AVL balanceC++ 树 AVL 平衡
【发布时间】:2012-06-05 03:38:01
【问题描述】:

我的树的平衡部分遇到了问题。我在递归插入后调用了 checkBal。如果我尝试添加 5、2 和 4,它会检查 2 的平衡并继续回到 5,然后进入右旋转的 rotateLeft 部分,这是正确的。但是第二行的rotateLeft函数出错了。

这个实现有什么问题?我到处搜索,并将我所做的与人们谈论它是如何完成的方式进行比较。我终于让一切正常了。最后我忘记将 N 设置为 K。

//==============================================================================
//===== Set Balance ============================================================
sNode<T>* checkBal(sNode<T> *locRoot)
{
    // Make sure to check the children are balanced as well.
    if (locRoot->left != NULL)
        locRoot->left = checkBal(locRoot->left);
    if (locRoot->right != NULL)
        locRoot->right = checkBal(locRoot->right);

    if(getHeight(locRoot->left) - getHeight(locRoot->right) > 1)
    {
        if(getHeight(locRoot->left->right) > getHeight(locRoot->left->left))
            locRoot->left = rotateRight(locRoot->left);
        locRoot = rotateLeft(locRoot);
    }
    else if(getHeight(locRoot->right) - getHeight(locRoot->left) > 1)
    {
        if(getHeight(locRoot->right->left) > getHeight(locRoot->right->right))
            locRoot->right = rotateLeft(locRoot->right);
        locRoot = rotateRight(locRoot);
    }
    updateHeights(locRoot);
    return locRoot;
}
    /*
        Extream cases of balancing a tree requires a double rotation
            A
             \
              D
             /
            B

        'A' is the current root
        If right->left (grandchild) is larger then the right->right (grandchild)
        First Right rotate the child then left rotate the parent


        left > right by 2 or more
            left.left < left.right  (Double Right Rotation)
            left.left >= left.right (Single Right Rotation)
        right > left by 2 or more
            right.right < right.left (Double Left Rotation)
            right.right >= right.left (Single Left Rotation)
    */

sNode<T>* rotateRight(sNode<T> *N) const
{
/*
      N           K
     / \         / \
   (a)  K  =>   N  (c)
       / \     / \
     (b) (c) (a) (b)
*/
    // K is going to be our new Parent
    // Move (c) from K->right to N->left
    // Set K->right to be N
    // Return the new parent node to update the one above.
    sNode<T> *K = N->right;
    N->right = K->left;        
    K->left = N;
    return N = K;
}

【问题讨论】:

    标签: c++ avl-tree tree-balancing


    【解决方案1】:
    rotateRight(locRoot->left);
    

    应该是,

    rotateRight(locRoot->right);
    

    但这仍然是一个错误的实现。 =p

    您应该对根的左侧和右侧有不同的实现。
    试试看wikipedia animation

    【讨论】:

    • 你的意思是我应该对根的左右两侧有不同的实现?双右只是意味着将左子向左旋转,然后将父向右旋转。谢谢,即使在我的测试用例中不会调用该副本/错字,我也没有注意到。
    • 我不知道您所说的“双右只是意味着将左子向左旋转然后父权向右旋转”是什么意思。右右大小写(查看维基百科图片),4 will be poited by a *root3 will be pointed by a *t,然后是 t-&gt;right = root-&gt;left root-&gt;left = t 完成。
    【解决方案2】:

    我在搞砸了一段时间后让它工作了。我的解决方案如下。

    //==============================================================================
    //===== AVL Balance ============================================================
    sNode<T>* checkBal(sNode<T> *locRoot)
    {
        // Go all the way down to the leaf nodes.
        if (locRoot->left != NULL)
            locRoot->left = checkBal(locRoot->left);
        if (locRoot->right != NULL)
            locRoot->right = checkBal(locRoot->right);
    
        // Before we do anything lets update the parent/child heights
        updateHeights(locRoot);
    
        if(getHeight(locRoot->left) - getHeight(locRoot->right) > 1)
        {
            // If it needs a double left rotate first rotate the left child right
            if(getHeight(locRoot->left->right) > getHeight(locRoot->left->left))
                locRoot->left = rotateRight(locRoot->left);
            locRoot = rotateLeft(locRoot);
        }
        else if(getHeight(locRoot->right) - getHeight(locRoot->left) > 1)
        {
            // If it needs a double right rotate first rotate the right child left
            if(getHeight(locRoot->right->left) > getHeight(locRoot->right->right))
                locRoot->right = rotateLeft(locRoot->right);
            locRoot = rotateRight(locRoot);
        }
        // Update the new heights
        updateHeights(locRoot);
        return locRoot;
    }
        /*
            Extream cases of balancing a tree requires a double rotation
                A
                 \
                  D
                 /
                B
    
            'A' is the current root
            If right->left (grandchild) is larger then the right->right (grandchild)
            First Right rotate the child then left rotate the parent
    
    
            left > right by 2 or more
                left.left < left.right  (Double Right Rotation)
                left.left >= left.right (Single Right Rotation)
            right > left by 2 or more
                right.right < right.left (Double Left Rotation)
                right.right >= right.left (Single Left Rotation)
        */
    
    sNode<T>* rotateRight(sNode<T> *N) const
    {
    /*
          N           K
         / \         / \
       (a)  K  =>   N  (c)
           / \     / \
         (b) (c) (a) (b)
    */
        // K is going to be our new Parent
        // Move (c) from K->right to N->left
        // Set K->right to be N
        // Return the new parent node to update the one above.
        sNode<T> *K = N->right;
        N->right = K->left;        
        K->left = N;
        return N = K;
    }
    
    sNode<T>* rotateLeft(sNode<T> *N) const
    {
    /*
             N            K
        / \          / \
           K  (a)  =>  (b)  N
          / \              / \
        (b) (c)          (c) (a)
    */
        sNode<T> *K = N->left;
        N->left = K->right;        
        K->right = N;
        return N = K;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-14
      • 1970-01-01
      • 1970-01-01
      • 2010-09-13
      • 2014-01-29
      相关资源
      最近更新 更多