C 插入到AVL树中

C 插入到AVL树中,c,tree,binary-tree,avl-tree,C,Tree,Binary Tree,Avl Tree,我目前正在尝试用c构建一个AVL树,其中每个节点都包含一个名称和一个值。树应该按值排序。目前,输入: 6 Franklin 4 David 1 Anna 2 Bob 3 Cora 5 Ella 7 Griffin 这棵树最后看起来像 David / \ Anna Franklin \ / \ Bob Ella Griffin \ Cora

我目前正在尝试用c构建一个AVL树,其中每个节点都包含一个名称和一个值。树应该按值排序。目前,输入:

6 Franklin
4 David
1 Anna 
2 Bob
3 Cora
5 Ella
7 Griffin
这棵树最后看起来像

         David
     /           \
   Anna        Franklin
      \        /    \
      Bob    Ella  Griffin
        \ 
       Cora
应该是什么时候

          David
      /          \
    Bob       Franklin
  /    \      /      \
Anna  Cora  Ella  Griffin
这似乎是it中断的阈值大小,输入由较少的节点组成。 相关代码:

#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;
}
定义最大值(X,Y)((X)<(Y)?(Y):(X)) 整数高度(结构树节点*n){ 如果(n->right&&n->left)返回MAX(n->right->height,n->left->height)+1; 如果(n->left&&!n->right)返回n->left->height+1; 如果(n->right&&!n->left)返回n->right->height+1; 返回0; } 整数平衡(结构树节点*n){ 如果(n->left&&n->right)返回n->left->height-n->right->height; 如果(n->left&&!n->right)返回n->left->height; 如果(!n->left&&n->right)返回n->right->height; 返回0; } 结构树节点*向左旋转(结构树节点*n){ 结构树_节点*p; 结构树节点*tp; p=n; tp=p->左; p->左=tp->右; tp->right=p; 返回tp; } 结构树节点*向右旋转(结构树节点*n){ 结构树_节点*p; 结构树节点*tp; p=n; tp=p->右; p->right=tp->left; tp->left=p; 返回tp; } 结构树节点*左右旋转(结构树节点*n){ 结构树_节点*p; 结构树节点*tp; 结构树节点*tp2; p=n; tp=p->右; tp2=p->右->左; p->右=tp2->左; tp->左=tp2->右; tp2->左=p; tp2->right=tp; 返回tp2; } 结构树节点*左右旋转(结构树节点*n){ 结构树_节点*p; 结构树节点*tp; 结构树节点*tp2; p=n; tp=p->左; tp2=p->左->右; p->左=tp2->右; tp->右=tp2->左; tp2->右=p; tp2->left=tp; 返回tp2; } 结构树节点*插入叶(结构树节点*根,结构树节点*新){ 如果(!root){ 根=新的; 根->左=空; root->right=NULL; 根->高度=0; 返回根; } 否则{ 如果(新建->值<根->值)根->左=插入_叶(根->左,新); else root->right=插入_叶(root->right,新建); } 根->高度=高度(根); 如果(平衡(根)>1&&new->valueleft->value)根=向左旋转(根); 否则,如果(平衡(根)<-1&&new->value>root->right->value)根=向右旋转(根); 否则,如果(平衡(根)<-1&&new->valueright->value)根=旋转\右\左(根); 否则,如果(平衡(根)>1&&new->value->root->left->value)root=rotate\u left\u right(根); 返回根; }
存在以下问题:

  • 叶节点的高度为1,而不是0。因此,
    height
    函数中的最后一个
    返回值应为:

    return 1;
    
    insert_leaf
    函数中,从
    if
    块中删除这两行:

    root->height = 0;
    return root;
    
    这样,执行将继续调用
    height
    ,将该值正确设置为1

  • 旋转函数将更改作为返回节点后代的节点的高度,因此必须更新其高度。因此,在单旋转函数中,添加以下行:

    p->height = height(p);
    
    在双旋转函数中,添加:

    p->height = height(p);
    tp->height = height(tp);
    
  • 您使用
    n->left->height-n->right->height
    将右重树的平衡定义为负值,但当
    n->left
    NULL
    n->right
    不为空时,将其设为正值。在这种情况下,它应该是负的。因此,添加否定运算符,如下所示:

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

通过这些更改,将为您的测试用例构建预期的树。

重新思考
如果(!n->left&&n->right)返回n->right->height
余额中
。编辑问题以提供解决方案。即使问题仅仅是我在上面指出的问题,MRE也可以让我很容易地测试这一原因——您报告的结果,确认这是唯一的原因,或者探索代码的行为。请求调试帮助时,应始终提供MRE。