C++ AVL树中的删除

C++ AVL树中的删除,c++,data-structures,binary-search-tree,avl-tree,C++,Data Structures,Binary Search Tree,Avl Tree,正如你们所知道的,删除一个节点后,avl应该如何平衡,我要说到点子上了。首先,我考虑删除一个没有子节点的节点 例如,一棵树: 10 / \ 5 17 / \ / \ 2 9 12 20 \ \ 3 50 假设deletevalue(12) 则删除后的树应为: 10 / \ 5 17 / \

正如你们所知道的,删除一个节点后,avl应该如何平衡,我要说到点子上了。首先,我考虑删除一个没有子节点的节点

例如,一棵树:

        10
      /     \
     5      17
   /  \    /  \ 
   2  9   12  20
    \           \
     3          50
假设deletevalue(12)

则删除后的树应为:

        10
      /     \
     5      17
   /  \       \ 
   2  9       20
    \           \
     3          50
现在,我们看到树在节点17处是平衡的,因为根据公式,它的平衡因子=高度(左子树[左树为空so-1])-高度(右子树)=-2

因此,我们通过检查树的左右格或左右格来平衡树

If BalanceFactor(17's right) = -1
    perform SingleLeftRotation(17);
else if BalanceFactor(17's right) = -1
    perform DoubleRightLeftRotation(17);
如果17的平衡系数为2,即保持较高,则其各自的旋转也类似。 //对于bF(17)=2

平衡后,树应变为:

          10
      /     \
     5      20
   /  \    /  \ 
   2  9   17  50
    \           
     3  
这是我设计的删除。

在main函数中,我调用

bool deletevalue(WA value)
{
    AvLNode<WA> *temp = search(root, value);    //calling search function to find node which has user-specified data & stored its address in temp pointer
    if(temp!=0) //if temp node is not null then
    {
        if(temp->left==0 && temp->right==0) //if temp node don't have any children
        {   deletewithNochild(root, value); }   //call to respective function
        else if( (temp->left!=0 && temp->right==0) || (temp->left==0 && temp->right!=0) )   //if temp node has any 1 child, left or right
        {   deletewithOneChild(temp);   }   //call to respective function
        else if(temp->left!=0 && temp->right!=0)    //if temp node has 2 children
        {   deletewith2Child(temp);     }   //call to respective function

        return true;    //for prompting respective output message
    }
    else
        return false;   //for prompting respective output message
}
bool deletevalue(WA值)
{
AvLNode*temp=search(root,value);//调用search函数查找具有用户指定数据的节点并将其地址存储在temp指针中
if(temp!=0)//如果temp节点不为null,则
{
if(temp->left==0&&temp->right==0)//如果临时节点没有任何子节点
{deletewithNochild(根,值);}//调用相应的函数
else if((temp->left!=0&&temp->right==0)| |(temp->left==0&&temp->right!=0))//如果temp节点有任何一个子节点,左或右
{deletewithOneChild(temp);}//调用相应的函数
else if(temp->left!=0&&temp->right!=0)//如果temp节点有2个子节点
{deletewith2Child(temp);}//调用相应的函数
返回true;//用于提示相应的输出消息
}
其他的
返回false;//用于提示相应的输出消息
}
由于我们所需的节点没有子节点,所以,下面的函数是envoked

void deletewithNochild(AvLNode*temp,WA值)//temp是要删除的节点
{
if(value==root->key)//如果temp是根节点,那么
{
删除根;//释放根节点的内存
root=0;//使root为空
}
else//如果temp是其他节点
{
如果(值key)
{
deletewithNochild(临时->左,值);
}
否则如果(值>临时->键)
{
deletewithNochild(临时->右侧,值);
}
else if(值==temp->key)
{
AvLNode*father=findfather(temp,root);//调用findfather func查找temp节点的父节点并将其地址存储在父节点指针中
if(父->左==temp)//如果temp是其父的左子级
{
delete temp;//释放临时节点的内存
父->左=0;//取消父的左
}
else if(父->右==temp)//如果temp是其父的正确子级
{
delete temp;//释放临时节点的内存
父亲->权利=0;//取消父亲的权利
}
返回;
}
coutleft)==-1)//如果temp的左节点的平衡因子为-1,则
{
DoubleLeftRightRotation(temp);//由于温度不平衡,发送双旋转的temp
}
}
否则如果(平衡因子(temp)=-2)//如果temp正好更高,即temp的平衡因子=-2,则
{
库尔特;
}
内部平衡因子(平均节点*温度)常数
{
返回(节点高度(温度->左)-节点高度(温度->右));
}
我的输出,当我删除12时变为 (广度优先遍历)-->>[10][9][17]

请帮助我解决问题,递归有什么问题吗?我已经干了一遍又一遍,但我无法理解。删除必须通过递归完成,否则平衡树将是一个更大的地狱。 提前感谢您提供的时间。:-

为什么deletewithNochild()调用任何其他delete*方法?如果调用deletewithNochild,您就在要删除的节点上。只需删除它,向上移动到它的父节点,检查父节点的平衡因子,并根据需要进行旋转。对每个节点的父节点重复重新平衡,直到到达根节点


如果有帮助的话,我已经实现了一个,如果你想要一个引用。

我想你还没有详细回顾deletewitnNochild()。它的递归函数。下面是发生的情况。(value=要删除的值)1.如果值在根目录中,则删除根目录并将根目录置零,因为它没有子目录。2.如果值小于根目录,则移动到左子树以查找具有值的节点。3.如果值大于根目录,则移动到右子树以查找具有值的节点。4.找到后,将其删除并返回到上一个调用(已删除节点的父节点)5.检查不平衡并按要求旋转。6.返回到上一次呼叫。7.继续,直到到达根部。
bool deletevalue(WA value)
{
    AvLNode<WA> *temp = search(root, value);    //calling search function to find node which has user-specified data & stored its address in temp pointer
    if(temp!=0) //if temp node is not null then
    {
        if(temp->left==0 && temp->right==0) //if temp node don't have any children
        {   deletewithNochild(root, value); }   //call to respective function
        else if( (temp->left!=0 && temp->right==0) || (temp->left==0 && temp->right!=0) )   //if temp node has any 1 child, left or right
        {   deletewithOneChild(temp);   }   //call to respective function
        else if(temp->left!=0 && temp->right!=0)    //if temp node has 2 children
        {   deletewith2Child(temp);     }   //call to respective function

        return true;    //for prompting respective output message
    }
    else
        return false;   //for prompting respective output message
}
void deletewithNochild(AvLNode<WA> *temp, WA value) //temp is node which is to be deleted
{
    if(value == root->key)  //if temp is root node then
    {
        delete root;    //free memory of root node
        root = 0;   //nullify root
    }
    else    //if temp is some other node 
    {
        if (value < temp->key)
        {
            deletewithNochild(temp->left, value);
        }
        else if (value > temp->key)
        {
            deletewithNochild(temp->right, value);
        }
        else if (value == temp->key)
        {
            AvLNode<WA> *father = findfather(temp, root);   //calling findfather func to find father of temp node & store its address in father node pointer

            if(father->left==temp)  //if temp is left child of its father
            {
                delete temp;    //free memory of temp node
                father->left=0; //nullify father's left
            }
            else if(father->right==temp)    //if temp is right child of its father
            {
                delete temp;    //free memory of temp node
                father->right=0;//nullify father's right
            }
            return;
        }
        cout<<"\nBalancing";
        if ( balancefactor(temp) == 2)  //if temp is left higher, ie. temp's Balance Factor = 2, then
        {
            cout<<"\t2 ";
            if ( balancefactor(temp->left) == 1 ) //if temp's left node has Balance Factor 1 then
            {
                SingleRightRotation(temp);  //send temp node for rotation because temp is unbalance
            }
            else if ( balancefactor(temp->left) == -1 ) //if temp's left node has Balance Factor -1, then
            {
                DoubleLeftRightRotation(temp);  //send temp for double rotation because temp is unbalance
            }
        }
        else if ( balancefactor(temp) == -2 )   //if temp is right higher, ie. temp's Balance Factor = -2, then
        {
            cout<<"\t-2 ";
            if ( balancefactor(temp->right) == -1 ) //if temp's left node has Balance Factor -1 then
            {
                SingleLeftRotation(temp);   //send temp node for rotation because temp is unbalance
            }
            else if ( balancefactor(temp->right) == 1 ) //if temp's right node has Balance Factor 1, then
            {
                DoubleRightLeftRotation(temp);  //send temp for double rotation because temp is unbalance
            }
        }

    }
}
int heightofnode(AvLNode<WA> *temp) const
{
    return temp==NULL ? -1 : temp->height;
}


int balancefactor(AvLNode<WA> *temp) const
{
    return ( heightofnode(temp->left) - heightofnode(temp->right) );
}