在AVL树中删除时出现分段错误?

时间:2015-04-06 19:54:50

标签: c tree avl-tree

当我试图在我的AVL Tree持有字符串的实现中删除时,我似乎得到了一个奇怪的分段错误。问题在于我在删除叶节点时似乎只会出现分段错误。这是删除的代码,有没有可能产生问题的地方?根据GDB,错误是函数deleteBalance。

struct node{
    char *word;
    int balance;
    struct node *children[2];
};

struct tree{
    struct node *root;
    int numElements;
};

struct tree *treeCreate(void){
    struct tree *s = malloc(sizeof(struct tree));
    s->root = NULL;
    s->numElements = 0;
    return s;
}

char *stringDuplicate (const char *s) {
    char *d = malloc (strlen (s) + 1);  
    if (d == NULL) return NULL;          
    strcpy (d,s);                        
    return d;                         
}

size_t treeSize(const struct tree *s){
    return s->numElements;
}

struct node *make_node(char *word){
    struct node *temp = malloc(sizeof(*temp));

    if(temp != NULL){
        temp->word = word;
        temp->children[0] = temp->children[1] = NULL;
        temp->balance = 0;
    }

    return temp;
}

void adjustBalance(struct node *root, int direction, int temp_bal){
    struct node *temp1 = root->children[direction];
    struct node *temp2 = temp1->children[!direction];

    if(temp2->balance == 0){
        root->balance = temp1->balance = 0;
    }else if(temp2->balance == temp_bal){
        root->balance = -temp_bal;
        temp1->balance = 0;
    }else{
        root->balance = 0;
        temp1->balance = temp_bal;
    }

    temp2->balance = 0;
}

struct node *singleRotation(struct node *root, int direction){
    struct node *temp = root->children[!direction];

    root->children[!direction] = temp->children[direction];
    temp->children[direction] = root;

    return temp;
}

struct node *doubleRotation(struct node *root, int direction){
    struct node *temp = root->children[!direction]->children[direction];

    root->children[!direction]->children[direction] = temp->children[!direction];
    temp->children[!direction] = root->children[!direction];
    root->children[!direction] = temp;

    temp = root->children[!direction];
    root->children[!direction] = temp->children[direction];
    temp->children[direction] = root;

    return temp;
}


struct node *insertBalance(struct node *root, int direction){
    struct node *temp = root->children[direction];
    int temp_bal;

    if(direction == 0){
        temp_bal = -1; 
    }else{
        temp_bal = 1;
    }

    if(temp->balance == temp_bal){
        root->balance = temp->balance = 0;
        root = singleRotation(root, !direction);
    }else{
        adjustBalance(root, direction, temp_bal);
        root = doubleRotation(root, !direction);
    }

    return root;
}

struct node *insertRecursive(struct node *root, char *word, int *done){
    if(root == NULL){
        root = make_node(word);
    }
    else{
        int direction = strcmp(word, root->word);
        if(direction > 0){
            direction = 1;
        }else if(direction < 0){
            direction = 0;
        }

        root->children[direction] = insertRecursive(root->children[direction], word, done);

        if(!*done){
            if(direction == 0){
                root->balance += -1;
            }else{
                root->balance += 1;
            }

            if(root->balance == 0){
                *done = 1;
            }else if(abs(root->balance) > 1){
                root = insertBalance(root, direction);
                *done = 1;
            }
        }
    }

    return root;
}

void treeInsert(struct tree *tree, const char *word){
    int done = 0;
    char *newWord = stringDuplicate(word);
    tree->root = insertRecursive(tree->root, newWord, &done);
}

struct node *deleteBalance(struct node *root, int direction, int *done){
    struct node *temp = root->children[!direction];
    int temp_bal;
    if(direction == 0){
        temp_bal = -1;
    }else{
        temp_bal = 1;
    }
    if(temp->balance == -temp_bal){ //ERROR OCCURRING HERE
        root->balance = temp->balance = 0;
        root = singleRotation(root, direction);
    }else if(temp->balance == temp_bal){
        adjustBalance(root, !direction, -temp_bal);
        root = doubleRotation(root, direction);
    }else{
        root->balance = -temp_bal;
        temp->balance = temp_bal;
        root = singleRotation(root, direction);
        *done = 1;
    }

    return root;
}

struct node *deleteRecursion(struct node *root, char *word, int *done){
    if(root != NULL){
        int direction;

        if(strcmp(word, root->word) == 0){
            if(root->children[0] == NULL || root->children[1] == NULL){
                struct node *temp;
                if(root->children[0] == NULL){
                    direction = 1;
                }else{
                    direction = 0;
                }

                temp = root->children[direction];
                free(root);

                return temp;
            }
            else{
                struct node *heir = root->children[0];

                while(heir->children[1] != NULL){
                    heir = heir->children[1];
                }

                root->word = heir->word;
                word = heir->word;
            }
        }

        direction = strcmp(word, root->word);
        if(direction > 0){
            direction = 1;
        }else if(direction < 0){
            direction = 0;
        }

        root->children[direction] = deleteRecursion(root->children[direction], word, done);
        if(!*done){
            if(direction == 0){
                root->balance += -1;
            }else{
                root->balance += 1;
            }

            if(abs(root->balance) == 1){
                *done = 1;
            }else if(abs(root->balance) > 1){
                root = deleteBalance(root, direction, done);
            }
        }
    }

    return root;
}

void treeDelete(struct tree *tree, const char *word){
    int done  = 0;
    char *newWord = stringDuplicate(word);
    tree->root = deleteRecursion(tree->root, newWord, &done);
}

编辑:我添加了我使用的所有功能,包括插入和删除。

0 个答案:

没有答案