AVL树插入-实现

AVL Tree Insertion - Implementation

本文关键字:实现 插入 AVL      更新时间:2023-10-16

感谢你们这些年来对我的帮助。这里又来了一个问题,和往常一样,欢迎并感谢任何解释、建议或更正!

我正在C++中为一个AVL树进行赋值,目前我正在进行插入,但也需要实现删除,所以即使这篇文章将大量涉及插入代码,任何关于如何实现删除的指针——用我的代码最容易理解的方法——都将是很棒的!

好的,所以我有以下功能来帮助我平衡/插入:

 int AVL :: returnBalance(Node* nodeme)
{
   return (whatisHeight(nodeme->leftbaby) - whatisHeight(nodeme->rightbaby));
}
int AVL :: whatisHeight(Node* localroot)
{
if(localroot == NULL)
{
    return 0;
}else
    return localroot->getHeight();
}
void AVL :: adjustHeight(Node* localroot)
{
if(localroot != NULL)
{
    localroot->height = 1 + max(whatisHeight(localroot->leftbaby), whatisHeight(localroot->rightbaby));
}
}
bool AVL :: contains(Node* nodeme ,int data)
{
if(!nodeme)
{
    return false;
}else
    if(data == nodeme->value)
    {
        return true;
    }
if(data < nodeme->value)
{
    return contains(nodeme->leftbaby,data);
}else
{
    return contains(nodeme->rightbaby,data);
}
}
// Rotation
void AVL :: rotateLeft(Node* localroot)
{
Node * temp = localroot->rightbaby;
localroot->rightbaby = temp->leftbaby;
temp->leftbaby = localroot;
localroot = temp;
adjustHeight(localroot);
adjustHeight(localroot->rightbaby);
adjustHeight(temp);
}
void AVL :: rotateRight(Node* localroot)
{
Node * temp = localroot->leftbaby;
localroot->leftbaby = temp->rightbaby;
temp->rightbaby = localroot;
adjustHeight(localroot);
adjustHeight(localroot->leftbaby);
adjustHeight(temp);
localroot = temp;

}

我的插入和插入递归函数写如下

bool AVL :: add(int data)
{
if(!contains(root, data))
{
    insertRecursive(root,data);
    return true;
}else
{
    return false;
}
}

Node * AVL :: insertRecursive(Node * nodeme, int data)
{
// getting a number ready to print
int num1 = data;
string out1;
   ostringstream convert1;
  convert1 << num1;
  out1 = convert1.str();
 cout << "running recursive insert -- value: " << out1 << endl;
if(root == NULL)
{
    cout << "adding root node" << endl;
    Node * temporary = new Node(data);
    temporary->height = 0;
    root = temporary;
    return root;
}else
    if(nodeme == NULL)
    {
        cout << "adding at local" << endl;
        nodeme = new Node(data);
        nodeme->height = 0;
        return nodeme;
    }else
        if(data < nodeme->value)
        {
            nodeme->leftbaby = insertRecursive(nodeme->leftbaby,data);
            // balancing and stuff
            adjustHeight(nodeme);
            if ((returnBalance(nodeme) == -2 )&& (returnBalance(nodeme->leftbaby) == -1))
            {
                cout << "rotating right" << endl;
                rotateRight(nodeme);
            }else
            if((returnBalance(nodeme) == -2) && (returnBalance(nodeme->leftbaby) == 1))
            {
                cout << "rotating left ---- 1" << endl;
                rotateLeft(nodeme->leftbaby);
                cout << "rotating right" << endl;
                rotateRight(nodeme);
            }else
                if((returnBalance(nodeme) == 2) && (returnBalance(nodeme->leftbaby) == 1))
                {
                    cout << "rotating left" << endl;
                    rotateLeft(nodeme);
                }
            else
                if((returnBalance(nodeme) == 2) && (returnBalance(nodeme->leftbaby) == -1))
                {
                    cout << "rotating right --- 2" << endl;
                    rotateRight(nodeme->leftbaby);
                    cout << "rotating left" << endl;
                    rotateLeft(nodeme);
                }
            adjustHeight(nodeme);
            //
            return nodeme;
        }
        else
        {
            nodeme->rightbaby = insertRecursive(nodeme->rightbaby,data);

            // balancing and stuff
            adjustHeight(nodeme);
            if ((returnBalance(nodeme) == -2 )&& (returnBalance(nodeme->leftbaby) == -1))
            {
                cout << "rotating right" << endl;
                rotateRight(nodeme);
            }else
                if((returnBalance(nodeme) == -2) && (returnBalance(nodeme->leftbaby) == 1))
                {
                    cout << "rotating left --- 3" << endl;
                    rotateLeft(nodeme->leftbaby);
                    cout << "rotating right" << endl;
                    rotateRight(nodeme);
                }else
                    if((returnBalance(nodeme) == 2) && (returnBalance(nodeme->leftbaby) == 1))
                    {
                        cout << "rotating left" << endl;
                        rotateLeft(nodeme);
                    }
                    else
                        if((returnBalance(nodeme) == 2) && (returnBalance(nodeme-    >leftbaby) == -1))
                        {
                            cout << "rotating right --- 4" << endl;
                            rotateRight(nodeme->leftbaby);
                            cout << "rotating left" << endl;
                            rotateLeft(nodeme);
                        }
            cout << "adjust height" << endl;
            adjustHeight(nodeme);
            //

            return nodeme;
        }
}

cout只是用于测试,我的类使用了给定的测试驱动程序,事实证明,当将0,1,2,3添加到9时,我的树与它应该匹配的不匹配。添加2时失败。请注意,此树中不允许重复值,因此包含函数。

现在,在我的脑海中,我正在添加到一棵树上,更新高度,检查平衡,然后在继续之前旋转,所以在我的头脑中,我在前进的过程中保持我的树的平衡。显然,这并没有正确实现,所以我需要一些指导!

预期的树是:

0 10 012

我要退回

0 01 111 2

我很抱歉浏览了这么多代码,我相信没有多少人真的想通读一遍,但只要看一眼,你可能会想吐,可以提供一个很好的解释。

非常感谢!-MJ

旋转:

localroot = temp;

您应该通过引用传递参数。否则,实际参数将无法更改,并且会导致内存泄漏。


AVL::insertRecursive中的nodeme也是如此。