【问题标题】:LeftRotate failing in AVL Tree at the last point when entering numbers from 1 - 10输入 1 - 10 的数字时,左旋转在最后一点在 AVL 树中失败
【发布时间】:2019-03-28 16:19:46
【问题描述】:

我正在尝试在节点采用(键,值)的 AVL 树中添加数字。在 for 循环中输入 (0,0) 到 (10,10) 的数字时,代码在尝试输入数字 (10,10) 时会失败。

以下是在树中插入节点的代码:

int insert_in_tree_q5(struct AVLTreeNode **node, int key, int value){

    //AVLTreeNode *newNode = newAVLTreeNode(key, value);
    // if the tree is empty
    if(*node == NULL){
        *node = newAVLTreeNode(key, value);
    }
    if(key != (*node)->key){
        // insert on left if the data in the key is less than the data in the node.
        if (key<(*node)->key){
            insert_in_tree_q5(&(*node)->left, key,value);
        }
        // insert on right if the data in the key is greater than the data in the node.
        else if(key>(*node)->key)
        {
            insert_in_tree_q5(&(*node)->right, key,value);
        }
        // Update height of the ancestor node
        (*node)->height = 1 + max(height((*node)->left), height((*node)->right));
        // check balance to see if this node became unbalanced
        int balance = getBalance(*node);

        //First case to balance the unbalanced node
        // Left Left case
        if(balance>1 && key<(*node)->left->key){
            *node = rightRotate(*node);
        }
        // Right Right Case
        if (balance < -1 && key > (*node)->right->key)
            *node = leftRotate(*node);

        // Left Right Case
        if (balance > 1 && key > (*node)->left->key)
        {
            (*node)->left =  leftRotate((*node)->left);
            *node = rightRotate(*node);
        }

        // Right Left Case
        if (balance < -1 && key < (*node)->right->key)
        {
            (*node)->right = rightRotate((*node)->right);
            *node = leftRotate(*node);
        }
    }
    else if(key == (*node)->key){
        if (value<(*node)->value){
            insert_in_tree_q5(&(*node)->left, key,value);
        }
        // insert on right if the data in the key is greater than the data in the node.
        else if(value>(*node)->value)
        {
            insert_in_tree_q5(&(*node)->right, key,value);
        }
        // Update height of the ancestor node
        (*node)->height = 1 + max(height((*node)->left), height((*node)->right));
        // check balance to see if this node became unbalanced
        int balance = getBalance(*node);

        //First case to balance the unbalanced node
        // Left Left case
        if(balance>1 && value<(*node)->left->value){
            *node =rightRotate(*node);
        }
        // Right Right Case
        if (balance < -1 && value > (*node)->right->value)
            *node =leftRotate(*node);

        // Left Right Case
        if (balance > 1 && value > (*node)->left->value)
        {
            (*node)->left =  leftRotate((*node)->left);
            *node =rightRotate(*node);
        }

        // Right Left Case
        if (balance < -1 && value < (*node)->right->value)
        {
            (*node)->right = rightRotate((*node)->right);
            *node =leftRotate(*node);
        }
    }else if(key == (*node)->key && value == (*node)->value){
        return 0;
    }
    return 1;

}

左旋转的代码是:

struct AVLTreeNode* leftRotate(struct AVLTreeNode *x){
    struct AVLTreeNode *y = x->right;
    struct AVLTreeNode *T2 = y->left;

    // Perform rotation
    y->left = x;
    x->right = T2;

    //  Update heights
    x->height = max(height(x->left), height(x->right))+1;
    y->height = max(height(y->left), height(y->right))+1;

    // Return new root
    return y;
}

我在树中输入值的方式是:

int InsertNode(AVLTree *T, int k, int v)
{
    //put your code here
    int returnedValue = insert_in_tree_q5(&T->root, k, v);
    if(returnedValue==0){
        return 0;
    }
    return 1;
}
tree4=newAVLTree();
    j=InsertNode(tree4, 10, 10);
    for (i=0; i<15; i++)
    {
        j=InsertNode(tree4, i, i);
        if (j==0) printf("(%d, %d) already exists\n", i, i);
    }

AVLTreeNode 和 AVLTree 的签名是:

typedef struct AVLTreeNode {
    int key; //key of this item
    int  value;  //value (int) of this item
    int height; //height of the subtree rooted at this node
    struct AVLTreeNode *parent; //pointer to parent
    struct AVLTreeNode *left; //pointer to left child
    struct AVLTreeNode *right; //pointer to right child
} AVLTreeNode;

AVLTree *newAVLTree()
{
    AVLTree *T;
    T = malloc(sizeof (AVLTree));
    assert (T != NULL);
    T->size = 0;
    T->root = NULL;
    return T;
}

PS:如果项目 (k,v) 已经存在,它应该返回 0 否则将它添加到树并返回 1。 关于为什么它接受所有值直到 (9,9) 但在 (10,10) 失败并出现错误“线程 1:EXC_BAD_ACCESS (code=1, address=0x18)”的任何想法

【问题讨论】:

  • 您在insert_in_tree_q5 的测试中有问题或逻辑,请参阅我的回答

标签: c avl-tree


【解决方案1】:

如果项目 (k,v) 已经存在,它应该返回 0 否则将它添加到树并返回 1

insert_in_tree_q5 你这样做:

if(*node == NULL){
    *node = newAVLTreeNode(key, value);
}
if(key != (*node)->key){
  ...CASE A
}
else if(key == (*node)->key){
    ...CASE B
} else if(key == (*node)->key && value == (*node)->value){
    return 0;
}
return 1;

else if(key == (*node)-&gt;key &amp;&amp; value == (*node)-&gt;value) 的情况永远不会到达,因为在您执行 else if(key == (*node)-&gt;key) 之前,您需要颠倒它们的顺序。

对我来说(*node == NULL)你也不必继续了

注意你已经知道if(key != (*node)-&gt;key) 是假的,所以在接下来的两个测试中测试相等性是没有用的

最后你的代码必须是:

if(*node == NULL){
    *node = newAVLTreeNode(key, value);
}
else if(key != (*node)->key){
  ...CASE A
}
else if( value == (*node)->value){
    return 0;
}
else {
    ...CASE B
} 
return 1;

int InsertNode(AVLTree *T, int k, int v)
{
    //put your code here
    int returnedValue = insert_in_tree_q5(&T->root, k, v);
    if(returnedValue==0){
        return 0;
    }
    return 1;
}

因为insert_in_tree_q5只返回0或1 InsertNode可以简化为just

int InsertNode(AVLTree *T, int k, int v)
{
    return insert_in_tree_q5(&T->root, k, v);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    相关资源
    最近更新 更多