Binary Tree deletion setting to NULL after freeing












0















I'm performing binary tree deletion in c.I was trying out few methods interestingly this weird situation came.



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*/
}

}


The above code works and it sets the the NODE to NULL.



But when i do this procedure in this way it doesn't set to 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;
}


Aren't these two methods are same? If not can someone explain me how they are different?Why the first method work and second didn't?










share|improve this question


















  • 2





    They're not the same *refsmall = NULL in the second procedure just sets the value of the local variable smallest to NULL. The pointer in the tree that got you there remains unchanged.

    – WhozCraig
    Nov 20 '18 at 16:52













  • So in the first one doesn't local variable ptr is set to NULL not the original tree right?But it wasn't like that

    – Sreyas
    Nov 20 '18 at 16:55






  • 3





    Actually, the first is broken too if you're intent is ever to delete the root element unless the "rest cases" not shown accounts for that.

    – WhozCraig
    Nov 20 '18 at 16:58


















0















I'm performing binary tree deletion in c.I was trying out few methods interestingly this weird situation came.



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*/
}

}


The above code works and it sets the the NODE to NULL.



But when i do this procedure in this way it doesn't set to 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;
}


Aren't these two methods are same? If not can someone explain me how they are different?Why the first method work and second didn't?










share|improve this question


















  • 2





    They're not the same *refsmall = NULL in the second procedure just sets the value of the local variable smallest to NULL. The pointer in the tree that got you there remains unchanged.

    – WhozCraig
    Nov 20 '18 at 16:52













  • So in the first one doesn't local variable ptr is set to NULL not the original tree right?But it wasn't like that

    – Sreyas
    Nov 20 '18 at 16:55






  • 3





    Actually, the first is broken too if you're intent is ever to delete the root element unless the "rest cases" not shown accounts for that.

    – WhozCraig
    Nov 20 '18 at 16:58
















0












0








0








I'm performing binary tree deletion in c.I was trying out few methods interestingly this weird situation came.



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*/
}

}


The above code works and it sets the the NODE to NULL.



But when i do this procedure in this way it doesn't set to 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;
}


Aren't these two methods are same? If not can someone explain me how they are different?Why the first method work and second didn't?










share|improve this question














I'm performing binary tree deletion in c.I was trying out few methods interestingly this weird situation came.



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*/
}

}


The above code works and it sets the the NODE to NULL.



But when i do this procedure in this way it doesn't set to 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;
}


Aren't these two methods are same? If not can someone explain me how they are different?Why the first method work and second didn't?







c binary-search-tree pointer-to-pointer






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 20 '18 at 16:50









SreyasSreyas

11310




11310








  • 2





    They're not the same *refsmall = NULL in the second procedure just sets the value of the local variable smallest to NULL. The pointer in the tree that got you there remains unchanged.

    – WhozCraig
    Nov 20 '18 at 16:52













  • So in the first one doesn't local variable ptr is set to NULL not the original tree right?But it wasn't like that

    – Sreyas
    Nov 20 '18 at 16:55






  • 3





    Actually, the first is broken too if you're intent is ever to delete the root element unless the "rest cases" not shown accounts for that.

    – WhozCraig
    Nov 20 '18 at 16:58
















  • 2





    They're not the same *refsmall = NULL in the second procedure just sets the value of the local variable smallest to NULL. The pointer in the tree that got you there remains unchanged.

    – WhozCraig
    Nov 20 '18 at 16:52













  • So in the first one doesn't local variable ptr is set to NULL not the original tree right?But it wasn't like that

    – Sreyas
    Nov 20 '18 at 16:55






  • 3





    Actually, the first is broken too if you're intent is ever to delete the root element unless the "rest cases" not shown accounts for that.

    – WhozCraig
    Nov 20 '18 at 16:58










2




2





They're not the same *refsmall = NULL in the second procedure just sets the value of the local variable smallest to NULL. The pointer in the tree that got you there remains unchanged.

– WhozCraig
Nov 20 '18 at 16:52







They're not the same *refsmall = NULL in the second procedure just sets the value of the local variable smallest to NULL. The pointer in the tree that got you there remains unchanged.

– WhozCraig
Nov 20 '18 at 16:52















So in the first one doesn't local variable ptr is set to NULL not the original tree right?But it wasn't like that

– Sreyas
Nov 20 '18 at 16:55





So in the first one doesn't local variable ptr is set to NULL not the original tree right?But it wasn't like that

– Sreyas
Nov 20 '18 at 16:55




3




3





Actually, the first is broken too if you're intent is ever to delete the root element unless the "rest cases" not shown accounts for that.

– WhozCraig
Nov 20 '18 at 16:58







Actually, the first is broken too if you're intent is ever to delete the root element unless the "rest cases" not shown accounts for that.

– WhozCraig
Nov 20 '18 at 16:58














2 Answers
2






active

oldest

votes


















3














You should avoid using global variables in your code. If you really want to use globals the first version of delete should look like this:



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*/
}
}


In the first version you would not be able to delete the root.






share|improve this answer





















  • 1





    thanks for such a really nice explanation :)

    – Sreyas
    Nov 30 '18 at 5:27



















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





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53397772%2fbinary-tree-deletion-setting-to-null-after-freeing%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    You should avoid using global variables in your code. If you really want to use globals the first version of delete should look like this:



    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*/
    }
    }


    In the first version you would not be able to delete the root.






    share|improve this answer





















    • 1





      thanks for such a really nice explanation :)

      – Sreyas
      Nov 30 '18 at 5:27
















    3














    You should avoid using global variables in your code. If you really want to use globals the first version of delete should look like this:



    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*/
    }
    }


    In the first version you would not be able to delete the root.






    share|improve this answer





















    • 1





      thanks for such a really nice explanation :)

      – Sreyas
      Nov 30 '18 at 5:27














    3












    3








    3







    You should avoid using global variables in your code. If you really want to use globals the first version of delete should look like this:



    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*/
    }
    }


    In the first version you would not be able to delete the root.






    share|improve this answer















    You should avoid using global variables in your code. If you really want to use globals the first version of delete should look like this:



    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*/
    }
    }


    In the first version you would not be able to delete the root.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 20 '18 at 18:11

























    answered Nov 20 '18 at 18:06









    sstefansstefan

    336311




    336311








    • 1





      thanks for such a really nice explanation :)

      – Sreyas
      Nov 30 '18 at 5:27














    • 1





      thanks for such a really nice explanation :)

      – Sreyas
      Nov 30 '18 at 5:27








    1




    1





    thanks for such a really nice explanation :)

    – Sreyas
    Nov 30 '18 at 5:27





    thanks for such a really nice explanation :)

    – Sreyas
    Nov 30 '18 at 5:27













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





    share|improve this answer




























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





      share|improve this answer


























        1












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





        share|improve this answer













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






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 20 '18 at 18:05









        joopjoop

        3,2781818




        3,2781818






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53397772%2fbinary-tree-deletion-setting-to-null-after-freeing%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

            ComboBox Display Member on multiple fields

            Is it possible to collect Nectar points via Trainline?