为什么我的AVL平衡功能会丢失数据?

时间:2019-06-23 19:01:45

标签: c binary-search-tree avl-tree

每当AVL中的节点数超过8个并且算法尝试重新平衡时,在插入第9个节点时,树中的大多数节点都会丢失

我在c中实现了一个AVL树,插入函数在每次插入后检查树的平衡。检查平衡功能会在调用树时尝试对其进行重新平衡(如有必要),并且它会通过旋转(这是AVL树的标准设置)来实现此平衡,或者通过向左旋转或向右旋转或两者结合来实现。但是,只要节点数超过8(尽管这可能是任意的),就会丢失某些节点。每次旋转后,将找到子树的上一个根节点的父节点,并相应地更改其左指针或右指针,例如:如果我有一棵像

的树
        97                                        97                 
       /                                          /
     96                                         95
    /          Right                           /  \
   95          ====>                         94    96
  /            Rotate on 96
 94    

96是子树的上一个父级,但旋转后为95,因此97s的“左”指针必须从96变为95。

因此,插入过程为:          位置值=>检查余额=>旋转(如有必要)

位置值函数:

void place_value(node_t* root, node_t* in) {
    if(root->val > in->val) {
        if(root->left == NULL)
            root->left = in;
        else
            place_value(root->left, in);
    }
    else if(root->val < in->val) {
        if(root->right == NULL)
            root->right = in;
        else
            place_value(root->right, in);
    } else {
        /*kill the node*/
    }
    if(check_balance(root) == 1) {
        fflush(stdout);
    }
}

支票余额功能:

int check_balance(node_t* root) {
    int flag = 0;

    if((height(root->left, 0)- height(root->right, 0))>1) {
        if((height(root->left->left, 0)- height(root->left->right, 0))>0) {
            right_rotate(root);
            flag = 1;
        } else {
            left_right(root);
            flag = 1;
        }
    }

    if((height(root->left, 0)- height(root->right, 0))<-1) {
        if((height(root->right->left, 0)- height(root->right->right, 0))<0)    {
            left_rotate(root);
            flag = 1;
        } else {
            right_left(root);
            flag = 1;
        }
    }

    return flag;

}

左右旋转或多或少遵循相同的模板:

void left_rotate(node_t* root) {
    if(root == NULL || root->right == NULL)
        return;
    node_t* parent = find_parent(root->val, root->bst_l->Head);
    node_t* right_node = root->right;
    root->right = right_node->left;
    right_node->left = root;
    if(parent == NULL) {
        root->bst_l->Head = right_node;
        return;
    }
    if(root->val > parent->val)
        parent->right = right_node;
    else
        parent->left = right_node;
}

组合旋转的示例:

void left_right(node_t* root) {
    left_rotate(root->left);
    right_rotate(root);
}

所以我在每次插入后都对BST进行了预遍历,这就是树的样子:

100 
100 99  
99  98  100 
98  97  99  100 
98  97  96  99  100 
98  96  95  97  99  100 
96  95  94  99  98  97  100 
98  96  94  93  95  97  99  100 
94  96  97  

插入92打破了树,丢失了一些数据

在数据丢失之前,预遍历显示树看起来像这样:

                         98
                        /  \
                      96    99
                     /  \    \
                   94    97  100
                  /  \
                93    95

这是平衡的。插入92后,我希望树看起来像这样:

                         ---98---
                        /        \
                      95         99
                     /  \          \
                   93    96        100
                  /  \     \
                92    94    97

但是它看起来像:

                         94
                           \
                            96
                              \
                              97

起初我虽然是因为操作系统正在任意清理内存,但并未使用它,但这没有意义,因为拥有内存的进程仍在运行。造成中断的其他可能原因是:

查找父函数:

node_t* find_parent(int value, node_t* start) {
    int val = value;
    if(start == NULL)
        return NULL;

    if(val == start->val)
        return NULL;

    if(val < start->val) {
        if(start->left == NULL)
            return NULL;
        else if(start->left->val == val)
            return start;
        else
            find_parent(value, start->left);
    } else if(val > start->val){
        if(start->right == NULL)
            return NULL;
        else if(start->right->val == val)
            return start;
        else
            find_parent(value, start->right);
    } else {  }

    return NULL;
}

我试图单步执行代码,但无法确切指出导致问题的原因,尽管我确实发现当算法在这种状态下使用BST在96上进行左右旋转时,BST中断了:< / p>

                         98
                        /  \
                      96    99
                     /  \    \
                   94    97  100
                  /  \
                93    95

输入92时。

0 个答案:

没有答案