简体   繁体   中英

Deleting a binary tree using inorder traversal

I was learning how to delete a binary tree using Postorder traversal. I understand that to delete a node, first we need to delete its child node and then the node itself, so Postorder traversal is the best fit to delete a binary tree. I thought of doing the same using Inorder traversal, everything works fine but I don't understand how the below code works?

#include<stdio.h>
#include<malloc.h>

struct b_tree{
    int data;
    struct b_tree *left,*right;
};

typedef struct b_tree tree;

tree* create_node(int data)
{
    struct b_tree* new_node=(tree*)malloc(sizeof(tree));
    new_node->data=data;
    new_node->left=NULL;
    new_node->right=NULL;
    return new_node;
}

void delete_tree(tree *root)
{
    if(root==NULL)
        return;
    delete_tree(root->left);
    printf("Deleting %d node.\n",root->data);
    free(root);
    delete_tree(root->right);
}

int main()
{
    tree *root=NULL;
    root=create_node(1);
    root->left=create_node(2);
    root->right=create_node(3);
    root->left->left=create_node(4);
    root->left->right=create_node(5);
    root->left->right->left=create_node(6);
    root->left->right->right=create_node(7);
    root->right->right=create_node(8);
    root->right->right->left=create_node(9);
    delete_tree(root);
    root=NULL;
    return 0;
}

树
According to Inorder traversal first node to be deleted is 4 and after that 2 , but once we freed 2 it should loose all it's data, means it should not retain the pointer to right node as well which is 5 , but even after 2 is freed its left child 5 is still traversed but it should not happen because node 2 is already freed.

The output of the above code is:
产量

I was expecting the output to be in the following order of nodes: 4 2 1 .

I don't understand how all this is working. Please correct me if I'm wrong.

The output it shows is correct , because in inorder it first traverse left sub-tree then root and then right sub-tree .

You won't get 4 2 1 because 4 is left sub-tree then it goes to root that is 2 and then to right sub-tree of 2 .

When it goes too right sub-tree root becomes 5 and its left sub-tree is 6 .Then 5 and then to right sub-tree of 5 that is 7 .

1 is the root so without traversing left sub-tree it won't go to 1 .

To traverse a binary tree in Inorder, following operations are carried-out

(i) Traverse the left most subtree starting at the left external node, 
(ii) Visit the root, and 
(iii) Traverse the right subtree starting at the left external node.

Now to delete the nodes,

(i) Traverse the left most subtree starting at the left external node,
(ii) delete the root, and 
(iii) Traverse the right subtree starting at the left external node.
void delete_tree(tree *root)
{
    if(root==NULL)
        return;
    delete_tree(root->left);
    printf("Deleting %d node.\n",root->data);
    free(root);
    delete_tree(root->right);
}

It is an inorder traversal where pointer will first point to left most node, then root and then right most node. Since 4 is the left most node so it has been printed then it traverse to 2 . After which the right most node which is 5. Since 5 has two nodes attached to it. It will again iterate to left most node which is 6. So it printed as 4,2,6,5,7,3,9,8

I originally posted this as a comment but it seems the guy asking the question was happy with my answer so I will post it in a bit more detail here.

When calling free it is important to note EXACTLY what free actually does otherwise things like this can happen.

The C library function void free(void *ptr) deallocates the memory previously allocated by a call to calloc, malloc, or realloc.

Note that the free function does NOT change the value of the pointer it simply gives the memory back to OS so that it can be allocated to another program. As such it is typical for people to "clear" the pointer after calling free to avoid accessing memory that another program has changed.

root = VOID;

The code above does not clear the root node after freeing it as such the memory is still all there. As such the C code is able to go to that memory location (which the OS has already received) and modify it. This is EXTREMELY dangerous behaviour because the OS can give this memory to another program and then your program could change causing obviously unexpected behaviour. The simple fix for this would be to remove the right node before freeing the root node.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM