繁体   English   中英

AVL树无法正确平衡

[英]AVL tree not balancing correctly

我分配了一个自平衡二进制搜索树。 我决定使用AVL树,因为这是我们在课堂上讨论的。 然后,使用给定输入{3,5,61,9,32,7,1,45,26,6},我期望输出为:

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

也就是说,除非我被严重误解并因此错误地计算了AVL树在平衡时应该做的事情。 我得到的输出是完全不同的:

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

再说一次,除非我完全错了,否则那棵树是不平衡的。 我用来建立树的功能定义如下:

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;
}

我用来存储所有数据的结构定义如下:

typedef struct node
{

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

    int data;

    int height;
} node;

函数rotate_left_right和rotate_right_left是基本功能,可旋转第一个后缀的方向,然后旋转第二个后缀的方向,并且它们各自的方向都依赖于rotate_left和rotate_right。 向左旋转的定义如下:

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;
}

rotation_right相似,但针对旋转右数进行了调整。

我想知道这段代码在哪里弄乱了,这样就不会产生想要的输出。

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

我没有一个完整的答案,我不确定您的代码是否可挽救,因为它遗漏了很多内容。 令人惊讶的主要原因是缺少cmpVal的初始化,然后将其与2进行比较。但是,如果n为NULL其UB。

cmpVal是AVL的余额,但具有绝对值。 不幸的是,在重新平衡时,您检查是否存在左孩子或右孩子。 但是,这没有告诉您。 您需要知道天平的符号才能选择旋转方向。 您可以有两个孩子,但仍然需要保持平衡。

您的插入看起来很奇怪,因为在检查节点不为NULL之后,您会检查子节点是否存在相同的事物。 但是,这里递归通过为您执行检查可以完全保存这两个检查。

暂无
暂无

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

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