我正在用c执行二叉树删除。有趣的是,我尝试了几种方法来解决这种奇怪的情况。
void Delete(){
struct BinaryTree* ptr = root;
int element;
printf("Enter element to delete : ");
scanf("%d",&element);
while(ptr){
if(element>ptr->data)
ptr = ptr->right;
else if(element<ptr->data)
ptr = ptr->left;
else
break;
}
if(ptr->left && ptr->right){
struct BinaryTree **smallest = &(ptr);
smallest = &((*smallest)->right);
while((*smallest)->left){
smallest = &((*smallest)->left);
}
ptr->data = (*smallest)->data;
free(*smallest);
*smallest = NULL;
} else if(ptr->left){
/*rest cases*/
}
}
上面的代码有效,并将NODE设置为NULL。
但是当我以这种方式执行此过程时,它不会设置为NULL。
if(ptr->left && ptr->right){
struct BinaryTree *smallest = ptr;
smallest = smallest->right;
while(smallest->left){
smallest = smallest->left;
}
ptr->data = smallest->data;
struct BinaryTree **refsmall = &smallest;
free(*refsmall);
*refsmall = NULL;
}
这两种方法不一样吗?如果没有人可以向我解释它们的不同之处?为什么第一种方法有效而第二种方法无效?
答案 0 :(得分:3)
您应该避免在代码中使用全局变量。如果您确实要使用全局变量,则删除的第一个版本应如下所示:
void Delete(){
/* at some point you will need to change the 'real' root, not the copy of it */
struct BinaryTree **ptr = &root;
int element;
printf("Enter element to delete : ");
scanf("%d",&element);
while(*ptr){
if(element > (*ptr)->data)
ptr = &(*ptr)->right;
else if(element < (*ptr)->data)
ptr = &(*ptr)->left;
else
break;
}
if((*ptr)->left && (*ptr)->right){
struct BinaryTree **smallest = ptr;
smallest = &(*smallest)->right;
while((*smallest)->left){
smallest = &(*smallest)->left;
}
(*ptr)->data = (*smallest)->data;
free(*smallest);
*smallest = NULL;
} else if((*ptr)->left){
/*rest cases*/
}
}
在第一个版本中,您将无法删除根。
答案 1 :(得分:1)
struct node {
struct node *l,*r;
int data;
};
void delnode(struct node **pp, int data)
{
struct node *del, *l,*r;
// Walk the tree
while(*pp) {
if ((*pp)->data < data) {pp = &(*pp)->l; continue;}
if ((*pp)->data > data) {pp = &(*pp)->r; continue;}
break; // found it!
}
if (!*pp) return; // not found
del = *pp;
l = del->l;
r = del->r;
// If only one child it wil take del's place.
if (!r) *pp = l;
else if (!l) *pp = r;
// del has two children.
// pick one (R) child, and append the (L) other onto its (Leftmost) shoulder
else {
*pp = r;
for (pp= &del->r; *pp; pp=&(*pp)->l) {;} // find Leftmost NULL pointer in the R tree
*pp = l;
}
free(del);
}