简体   繁体   English

插入 AVL 树

[英]Insertion into AVL tree

I am currently trying to construct a AVL tree in c where each node contains a name and a value.我目前正在尝试在 c 中构建一个 AVL 树,其中每个节点都包含一个名称和一个值。 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:叶节点的高度是 1,而不是 0。所以height function 中的最后一个return应该是:

     return 1;

    And in the insert_leaf function, remove these two lines from the if block:insert_leaf function 中,从if块中删除这两行:

     root->height = 0; return root;

    That way the execution will continue with a call to height to set this value correctly to 1.这样,执行将继续调用height以将此值正确设置为 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.您使用n->left->height - n->right->height将右重树的平衡定义为,但是当n->leftNULLn->right不是时将其设为正。 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.通过这些更改,将为您的测试用例构建预期的树。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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