【问题标题】:C++ AVL tree recalculate heightC++ AVL 树重新计算高度
【发布时间】:2013-04-09 09:13:53
【问题描述】:

我正在研究 AVL 树的实现,但我的重新计算高度函数有问题。当我调用它时,我传入了树的根和一个值为 1 的变量。我单步执行了它,发现一旦它到达 while 循环,它就会按预期执行,但之后它会返回一个。你能看看它,看看我做错了什么。如果需要,我会发布更多代码,但我认为该功能将为您提供足够的信息。谢谢

void BinaryTree::recalculate(Node *leaf, int count)
{
    if(leaf == NULL)//if we are at the root
    {
        return;//exit the function
    }

     if((leaf->getLeft() != NULL))//if we are not at the end of the subtree
    {
        recalculate(leaf->getLeft(), count);//advance to the next node and re-enter the function

    }

     if(leaf->getRight() != NULL)//if we are not at the end of the right subtree
    {
        recalculate(leaf->getRight(), count);//advance to the next node and re-enter the program
    }

    else
    {
        while(leaf->getParent() != NULL)//calculate each subtree until we are at the root
        {
            leaf = leaf->getParent();//get the parent node
                count++;//increment the height          

            if(leaf->getLeft() != NULL)//if there is an item in the left
            {

                leaf->getLeft()->setHeight(count-1);//sets the hight of the left child
            }

             if(leaf->getRight() != NULL)//if there is an item in the right
            {
             leaf->getRight()->setHeight(count -1);//sets the height of the right child

            }
        }

        return;//exit the function
    }
}

【问题讨论】:

    标签: c++ treenode avl-tree


    【解决方案1】:

    您的函数应该计算二叉树的每个子树的高度,并将该值保存在该子树的根节点中。您选择遵循一种递归方法,这是标准方法。在这种方法中,必须先计算左右子树的高度,然后将两者中的最高者作为当前节点。

    在您的实现中,您使用一个名为count 的值传递给递归调用的参数。考虑到我们需要从子节点检索计数,而不是向它们传递一个计数,该值的目的是什么?

    如果你:

    • recalculate 参数中删除该值
    • 如果适用,让 recalculate 方法首先在两个孩子上调用自己
    • 使recalculate从每个子节点高度更新当前节点高度

    你应该让它工作。以下是基于该算法的可能实现:

    void BinaryTree::recalculate(Node *leaf) {
         int count = 0;
        if (leaf == NULL)  {
            return;
        }
        if (leaf->getLeft() == NULL && leaf->getRight() == NULL) {
            // no child, the height is 0
            setHeight(0);
            return;
        }
        if (leaf->getLeft() != NULL) {
            recalculate(leaf->getLeft());
            count = leaf->getLeft()->getHeight();
        }
        if (leaf->getRight() != NULL){
            recalculate(leaf->getRight());
            count = max(count, leaf->getRight()->getHeight());
        }
        // include leaf in the height
        setHeight(count+1);
    }
    

    如果无法使用getHeight 方法,您可以通过让recalculate 返回它计算的高度来替换它。

    【讨论】:

    • count 变量是我用来计算每个节点的高度的,我希望能够找到每个子树中的最低节点,然后从那里开始。但它似乎没有工作。
    • 我不希望它重新计算节点的当前高度,从那里已经存储的高度。在我必须旋转树的情况下,节点的位置会发生变化,并且会与这种做事方式混淆。我想改变它并改用循环。
    • 在树旋转中大部分时间整棵树围绕一个节点移动,所以是的,我正在尝试计算树中每个节点的高度。
    • 啊,所以我一开始是对的?尝试我的算法来更新树中的所有节点高度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    • 2018-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多