Удаление в дереве AVL

Поскольку вы знаете, как avl должен быть сбалансирован после удаления узла, я перейду к пункту. Для начала я рассматриваю удаление узла без дочерних элементов.

Например, дерево:

        10
/     \
5      17
/  \    /  \
2  9   12  20
\           \
3          50

Скажем deletevalue (12);

Тогда дерево должно быть после удаления:

        10
/     \
5      17
/  \       \
2  9       20
\           \
3          50

Теперь мы видим, что дерево сбалансировано в узле 17, потому что по формуле его Коэффициент Баланса = высота (левое поддерево [левое дерево равно нулю, поэтому -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

If BalanceFactor(17's left) = 1
perform SingleLeftRotation(17);
else if BalanceFactor(17's left) = -1
perform DoubleLeftRightRotation(17);

После балансировки дерево должно стать таким:

          10
/     \
5      20
/  \    /  \
2  9   17  50
\
3

Это удаление, которое я разработал.

Из основной функции я звоню

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) );
}

Мой вывод, когда я удаляю 12 становится
(Первый шаг в ширину) — >> [10] [9] [17]

Пожалуйста, помогите мне, есть ли проблемы с рекурсией? Я снова пробежал & еще раз, но не могу понять. Удаление должно быть выполнено посредством рекурсии, иначе балансирующее дерево было бы большим адом.
Заранее спасибо за уделенное время. 🙂

5

Решение

Почему deletewithNochild () вызывает любые другие методы delete *? Если вызывается deletewithNochild, вы находитесь на узле для удаления. Просто удалите его, перейдите к его родителю, проверьте коэффициент баланса родителей и поверните при необходимости. Повторяйте балансировку для каждого родительского узла, пока не доберетесь до корня.

Если это поможет, я реализовал AVL дерево в Java, если вы хотите ссылку.

1

Другие решения

Других решений пока нет …