Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 释放后将二叉树删除设置为NULL_C_Binary Search Tree_Pointer To Pointer - Fatal编程技术网

C 释放后将二叉树删除设置为NULL

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

我正在用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*/
    }

}
这两种方法不一样吗?如果没有,有人能解释一下它们有什么不同吗?为什么第一个方法有效而第二个方法无效?

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”说明了这一点。