简体   繁体   中英

AVL tree not balancing correctly

I have an assignment to write a self balancing binary search tree. I decided to use an AVL tree as it is what we have discussed in class. Then with the given input of { 3, 5, 61, 9, 32, 7, 1, 45, 26, 6} I'm expecting an output of:

               7
         6-----|-----32
    3----|      9----|----45
1---|           |---26    |---61

That is, unless I have grossly misunderstood and thus miscalculated what an AVL tree is supposed to do when it balances itself. The output I'm getting is quite different:

              5
        3-----|-----61
   1----|      9----|
           7---|---32
        6--|    26--|--45

Again, unless I am completely wrong, that tree is not balanced. The function I'm using to set up the tree is defined as such:

node* insertKeyAVL(node* n, int e)
{
    int cmpVal;

    if (n == NULL){
            n = create_node();
            n->data = e;
    } else if (e < n->data) {
            if (n->left == NULL){
                    n->left = create_node();
                    n->left->data = e;
                    n->left->parent = n;
            } else {
                    n->left = insertKeyAVL(n->left, e);
            }

            cmpVal = height(n->left) - height(n->right);


    } else {
            if (n->right == NULL){
                    n->right = create_node();
                    n->right->data = e;
                    n->right->parent = n;
            } else {
                    n->right = insertKeyAVL(n->right, e);
            }

            cmpVal = height(n->right) - height(n->left);
    }

    if (cmpVal > 2){
            if (n->left){
                    if (e < n->left->data)
                            n = rotate_left(n);
                    else
                            n = rotate_right_left(n);
            } else if (n->right){
                    if (e > n->right->data)
                            n = rotate_right(n);
                    else
                            n = rotate_left_right(n);
            }
    }

    n->height = max(height(n->left), height(n->right)) + 1;

    return n;
}

The structure I'm using to store all the data is defined as such:

typedef struct node
{

    struct node *parent;
    struct node*  left;
    struct node*  right;

    int data;

    int height;
} node;

The functions rotate_left_right and rotate_right_left are basic functions that rotate the direction of the first post-fix then the second post-fix, and are both reliant on rotate_left and rotate_right for their respective direction. rotate left is defined as such:

node* rotate_left(node* n)
{
    node* tmp = n->left;
    n->left = tmp->right;
    tmp->right = n;

    tmp->parent = n->parent;
    n->parent = tmp;

    n->height = max(height(n->left), height(n->right)) + 1;
    tmp->height = max(height(tmp->left), n->height) + 1;

    return tmp;
}

rotate_right is similar but adjusted for a rotation right.

I'm wondering where this code messes up so that it doesn't produce the desired output.

当在预期结果中将26加5的cmpval变为2时,这是无效的,这就是代码重新执行并给出结果的原因。

I don't have a full answer and I'm not sure your code is salvageable, since it misses a lot of pieces. Main source of surprise is the missing initialization of cmpVal which is then compared to 2. But if n is NULL its UB.

cmpVal is the balance of AVL but with an absolute value. Unfortunately when rebalancing you check the existence of a left child or of a right child. But this tells you nothing. You need to know the sign of the balance in order to choose the rotation direction. You can have both children and still need to balance.

Your insertion looks strange because after checking that the node is not NULL you check the children for the same thing. But recursion here would have saved the two checks entirely by performing the check for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM