C 释放后将二叉树删除设置为NULL
我正在用c语言执行二叉树删除。我尝试了几种方法,有趣的是,这种奇怪的情况出现了C 释放后将二叉树删除设置为NULL,c,binary-search-tree,pointer-to-pointer,C,Binary Search Tree,Pointer To Pointer,我正在用c语言执行二叉树删除。我尝试了几种方法,有趣的是,这种奇怪的情况出现了 void Delete(){ struct BinaryTree* ptr = root; int element; printf("Enter element to delete : "); scanf("%d",&element); while(ptr){ if(element>ptr->data) ptr = p
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*/
}
}
这两种方法不一样吗?如果没有,有人能解释一下它们有什么不同吗?为什么第一个方法有效而第二个方法无效?struct node{
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);
}
结构节点*l,*r;
int数据;
};
void delnode(结构节点**pp,int数据)
{
结构节点*del,*l,*r;
//在树上散步
而(*pp){
如果((*pp)->datal;continue;}
如果((*pp)->data>data){pp=&(*pp)->r;continue;}
break;//找到了!
}
if(!*pp)返回;//未找到
del=*pp;
l=del->l;
r=del->r;
//如果只有一个孩子,它就会取代德尔的位置。
如果(!r)*pp=l;
如果(!l)*pp=r;
//戴尔有两个孩子。
//选择一个(R)子项,并将另一个(L)子项附加到其(最左侧)肩部
否则{
*pp=r;
对于(pp=&del->r;*pp;pp=&(*pp)->l){;}//在r树中查找最左边的空指针
*pp=l;
}
免费(del);
}
结构节点{
结构节点*l,*r;
int数据;
};
void delnode(结构节点**pp,int数据)
{
结构节点*del,*l,*r;
//在树上散步
而(*pp){
如果((*pp)->datal;continue;}
如果((*pp)->data>data){pp=&(*pp)->r;continue;}
break;//找到了!
}
if(!*pp)返回;//未找到
del=*pp;
l=del->l;
r=del->r;
//如果只有一个孩子,它就会取代德尔的位置。
如果(!r)*pp=l;
如果(!l)*pp=r;
//戴尔有两个孩子。
//选择一个(R)子项,并将另一个(L)子项附加到其(最左侧)肩部
否则{
*pp=r;
对于(pp=&del->r;*pp;pp=&(*pp)->l){;}//在r树中查找最左边的空指针
*pp=l;
}
免费(del);
}
您应该避免在代码中使用全局变量。如果确实要使用globals,则删除的第一个版本应如下所示:
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*/
}
}
void Delete(){
/*在某些时候,您需要更改“真实”根,而不是它的副本*/
结构二进制树**ptr=&root;
int元素;
printf(“输入要删除的元素:”);
scanf(“%d”和元素);
while(*ptr){
如果(元素>(*ptr)->数据)
ptr=&(*ptr)->右;
else if(元素<(*ptr)->数据)
ptr=&(*ptr)->左;
其他的
打破
}
如果((*ptr)->左和(*ptr)->右){
结构二进制树**最小=ptr;
最小=&(*最小)->右侧;
而((*最小)->左){
最小=&(*最小)->左;
}
(*ptr)->数据=(*最小)->数据;
自由(*最小);
*最小=零;
}如果((*ptr)->左{
/*其余案例*/
}
}
在第一个版本中,您将无法删除根。您应该避免在代码中使用全局变量。如果确实要使用globals,则删除的第一个版本应如下所示:
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*/
}
}
void Delete(){
/*在某些时候,您需要更改“真实”根,而不是它的副本*/
结构二进制树**ptr=&root;
int元素;
printf(“输入要删除的元素:”);
scanf(“%d”和元素);
while(*ptr){
如果(元素>(*ptr)->数据)
ptr=&(*ptr)->右;
else if(元素<(*ptr)->数据)
ptr=&(*ptr)->左;
其他的
打破
}
如果((*ptr)->左和(*ptr)->右){
结构二进制树**最小=ptr;
最小=&(*最小)->右侧;
而((*最小)->左){
最小=&(*最小)->左;
}
(*ptr)->数据=(*最小)->数据;
自由(*最小);
*最小=零;
}如果((*ptr)->左{
/*其余案例*/
}
}
在第一个版本中,您将无法删除根。在第二个过程中,它们不是相同的
*refsmall=NULL
,只需将局部变量最小值设置为NULL
。树中的指针保持不变。因此,在第一个指针中,局部变量ptr不是设置为NULL吗?不是原始树对吗?但事实并非如此,如果您打算删除根元素,那么第一个指针也会被破坏,除非“rest cases”在第二个过程中,它们不是相同的,只是将局部变量最小值设置为NULL
。树中的指针保持不变。因此,在第一个指针中,局部变量ptr不是设置为NULL吗?不是原始树吗?但事实并非如此,如果您打算删除根元素,则第一个指针也会被破坏,除非未显示的“rest cases”说明了这一点。