Member 10743491 Ответов: 1

Вставка и балансировка дерева AVL


Я пытаюсь выполнить вставку в одной функции, а затем сбалансировать дерево, если это необходимо, в другой.

Вот мой код...
node* create_bst(node* tree,node* curr)
{
    if (tree==NULL)
        {
            return curr;
        }
    if(tree!=curr)
    {
    if(tree->key>=curr->key)
        {
            tree->left=create_bst(tree->left,curr);
        }
        else
            {   
                tree->right=create_bst(tree->right,curr);
            }
    }
    tree->bal_f=height(tree->left)-height(tree->right);
}

create_bst(tree,curr) добавляет узел curr (содержащий ключ) в дерево - простая вставка двоичного дерева с последующим обновлением коэффициента баланса каждого узла построенного дерева. Затем я вызываю функцию баланса, которая уравновешивает дерево.
node* balance(node* tree,node* curr)
{
if(tree->bal_f==2 or tree->bal_f==-2)
            {
if(tree->key>=curr->key)
    {
        balance(tree->left,curr);
        node* a=tree;
        node* b=new node;
        b=a->left;
        if(curr->key<b->key)
        {
            tree=LL_rotation(b,a);
        }   
        if(curr->key>b->key)
        {
            node* c=new node; 
            c=b->right;
            tree=LR_rotation(c,b,a);
        }   
    }
else
    {
        balance(tree->right,curr);
        node* a=tree;
        node* b=new node;
        b=a->right;
        if(curr->key>b->key)
        {
            tree=RR_rotation(b,a); 
        }
        if(curr->key<b->key)
        {
            node* c=new node; 
            c=b->left;
            tree=RL_rotation(c,b,a);  
        }   
    }
}   

curr-это тот же узел, который был добавлен в функцию create_bst.

LL_rotation= выполняет поворот влево и возвращает измененный корневой узел. LL означает, что узел curr был добавлен к левой стороне левого дочернего узла с коэффициентом баланса 2 или -2. вращения выполняются соответственно. То же самое происходит и с остальными. LR_rotation= выполнить поворот влево с последующим поворотом вправо и возвращает измененный корневой узел.

RR_rotation= выполняет поворот вправо и возвращает измененный корневой узел.

RL_rotation= выполняет поворот вправо, за которым следует поворот влево, и возвращает измененный корневой узел.

Проблема, с которой я сталкиваюсь, заключается в том, что при вращении, хотя корневой узел изменяется при вращении, в моем случае он остается прежним. Например: если мой вход - (2,0,-1) при вращении LL он становится 0,2,-1 (предварительный заказ), но я получаю только 2, что было моим начальным корнем. Любая помощь будет высоко оценена. :)

1 Ответов

Рейтинг:
6

Steve44

Я думаю, что проблема заключается в том, что вы пропускаете последнее утверждение в функции баланса:

    ...
    return tree;
}


Операторы, которые присваиваются дереву, не имеют никакого эффекта, видимого от вызывающего объекта:
(Комментарии относятся к вашему примеру вставки (2,0,-1), а функция balance() вызывается после вставки конечного узла -1.)
            // This changes the variable tree visible INSIDE the function, 
            // the callers pointer to tree remains unchanged to the 2 node as you
            // mentioned.
            tree=RL_rotation(c,b,a);  
        }   
    }
    // This now returns the pointer to the 0 node that has become the new root of the
    // balanced  tree.
    return tree;
}