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

时间:2018-11-20 16:50:29

标签: 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 = 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;
}

这两种方法不一样吗?如果没有人可以向我解释它们的不同之处?为什么第一种方法有效而第二种方法无效?

2 个答案:

答案 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);
}