当我试图在我的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);
}
编辑:我添加了我使用的所有功能,包括插入和删除。