【发布时间】:2017-07-15 20:00:53
【问题描述】:
我有一个二叉搜索树。我想从中删除一个节点:
void deleteANode(struct node *head, int value) {
//let us find the node
struct node *temp = head;
struct node *parent = NULL;
//let us find the node
while (temp != NULL) {
if (value > temp->data) {
parent = temp;
temp = temp->right;
} else
if (value < temp->data) {
parent = temp;
temp = temp->left;
} else {
//let us check for child nodes
//
if (temp->left == NULL && temp->right == NULL) {
printf("Deleting a leaf.\n");
temp = NULL;
printf("Set temp null.\n");
free(temp);
break;
} else
if (temp->left == NULL || temp->right == NULL) {
printf("Deleting a one child.\n");
//one of the child is null
if (temp->left != NULL) {
parent->left = temp->left;
} else {
parent->right = temp->right;
}
free(temp);
} else {
printf("Deleting two child parent.\n");
//both of them are not NULL
//need to find the pre-order successor
struct node *temp2 = temp->right;
while (temp2->left != NULL) {
temp2 = temp2->left;
}
//found the successor.
temp->data = temp2->data;
free(temp);
}
break;
}
}
}
我正在尝试删除此块中的叶节点:
if (temp->left == NULL && temp->right == NULL) {
printf("Deleting a leaf.\n");
temp->data = NULL;
printf("Set temp null.\n");
free(temp);
break;
}
但是上面的代码不起作用。
我在调用上面的方法:
deleteANode(head, 3);
前序遍历前后一致:
5 4 3 10 7 20 删除叶子。将临时设置为空。 =============== 5 4 3 10 7 20
我做错了什么。
根据@pstrjds cmets 更新:
if (temp->left == NULL && temp->right == NULL ) {
printf("Deleting a leaf.\n");
parent->left = NULL;
parent->right = NULL;
free(temp);
temp = NULL;
printf("Set temp null.\n");
break;
}
叶子节点工作正常。需要为有两个孩子的节点工作。
【问题讨论】:
-
好吧,一方面,您在调用 free 之前将
temp设置为 NULL。您可能应该首先释放它(这是在检查叶子的 if 块中) -
You should probably free it first.?应该还是必须?我认为免费首先意味着它不再存在。虽然这样做并不能解决我的问题,但它会为已删除的密钥提供0而不是3。 -
我应该更清楚,抱歉,您应该在将 temp 设置为
null之前调用free(temp),否则您不会释放节点,只是在 null 上调用 free。您还需要确保父节点不再指向它。 -
做了同样的事情,但得到了输出:
5 4 3 10 7 20 Deleting a leaf. Set temp null. =============== 5 4 0 10 7 20。好的,我需要另一个节点作为父节点才能使其工作吗? -
你能用你更新的代码更新问题吗 - 从新的输出来看,在我看来你没有修复叶节点的父节点,所以父节点指向一个空节点或那种性质的东西。
标签: c data-structures tree