简体   繁体   中英

Insertion into AVL tree

I am currently trying to construct a AVL tree in c where each node contains a name and a value. The tree should be sorted by value. Currently, with the input:

6 Franklin
4 David
1 Anna 
2 Bob
3 Cora
5 Ella
7 Griffin

the tree ends up looking like

         David
     /           \
   Anna        Franklin
      \        /    \
      Bob    Ella  Griffin
        \ 
       Cora

when it should look like

          David
      /          \
    Bob       Franklin
  /    \      /      \
Anna  Cora  Ella  Griffin

this seems to be the threshold size for it breaking, with input consisting of less nodes working. relevant code:

#define MAX(X, Y) ((X) < (Y) ? (Y) : (X))

int height(struct Tree_Node *n) {

    if (n->right && n->left) return MAX(n->right->height, n->left->height) + 1;
    if (n->left && !n->right) return n->left->height + 1;
    if (n->right && !n->left) return n->right->height + 1;

    return 0;
}

int balance(struct Tree_Node *n) {

    if (n->left && n->right) return n->left->height - n->right->height;
    if (n->left && !n->right) return n->left->height;
    if (!n->left && n->right) return n->right->height;
    return 0;
}

struct Tree_Node *rotate_left(struct Tree_Node *n){

    struct Tree_Node *p;
    struct Tree_Node *tp;
    p = n;
    tp = p->left;

    p->left = tp->right;
    tp->right = p;

    return tp; 
}


struct Tree_Node *rotate_right(struct Tree_Node *n){

    struct Tree_Node *p;
    struct Tree_Node *tp;
    p = n;
    tp = p->right;

    p->right = tp->left;
    tp->left = p;

    return tp; 
}

struct Tree_Node *rotate_right_left(struct Tree_Node *n) {

    struct Tree_Node *p;
    struct Tree_Node *tp;
    struct Tree_Node *tp2;
    p = n;
    tp = p->right;
    tp2 =p->right->left;

    p -> right = tp2->left;
    tp ->left = tp2->right;
    tp2 ->left = p;
    tp2->right = tp; 
     
    return tp2; 
}

struct Tree_Node *rotate_left_right(struct Tree_Node *n) {

    struct Tree_Node *p;
    struct Tree_Node *tp;
    struct Tree_Node *tp2;
    p = n;
    tp = p->left;
    tp2 =p->left->right;

    p -> left = tp2->right;
    tp ->right = tp2->left;
    tp2 ->right = p;
    tp2->left = tp; 
     
    return tp2; 
}

struct Tree_Node *insert_leaf(struct Tree_Node *root, struct Tree_Node *new) {

    if (!root) {
        root = new;
        root->left = NULL;
        root->right = NULL;
        root->height = 0;
        return root;
    }
    else {
        if (new->value < root->value) root->left = insert_leaf(root->left, new);
        else root->right = insert_leaf(root->right, new);
    }
    root->height = height(root);
    
    if (balance(root) > 1 && new->value < root->left->value) root = rotate_left(root);
    else if (balance(root) < -1 && new->value > root->right->value) root = rotate_right(root);
    else if (balance(root) < -1 && new->value < root->right->value) root = rotate_right_left(root);
    else if (balance(root) > 1 && new->value > root->left->value) root = rotate_left_right(root);

    return root;
}

There are the following issues:

  • The height of a leaf node is 1, not 0. So the last return in the height function should be:

     return 1;

    And in the insert_leaf function, remove these two lines from the if block:

     root->height = 0; return root;

    That way the execution will continue with a call to height to set this value correctly to 1.

  • The rotation functions will change the height of node(s) that are descendant(s) of the returned node, so you must update their height(s). In the single rotation functions, add therefore this line:

     p->height = height(p);

    And in the double rotation functions, add:

     p->height = height(p); tp->height = height(tp);
  • You define the balance for a right-heavy tree as negative with n->left->height - n->right->height , but then make it positive when n->left is NULL and n->right is not. It should be negative in that case. So add the negation operator like this:

     if (;n->left && n->right) return -n->right->height;

With these changes the expected tree will be built for your test case.

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