Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

recursive delete on a binary tree

I am trying to understand how the recursive method of deletion of a binary search tree works. The code that I came across in many places looks as follows:

void destroy_tree(struct node *leaf)
{
  if( leaf != 0 )
  {
      destroy_tree(leaf->left);
      destroy_tree(leaf->right);
      free( leaf );
  }
}

I can't understand however a) how does it work if there are no returns in the routine? b) when free() gets to be called? I think about, e.g., such a tree:

                           10
                         /    \
                        6      14
                       / \    /  \
                      5   8  11  18

So my understanding is that I traverse 10->6->5, and then I call destroy_tree(5->left). Therefore, leaf inside if is NULL, and what is if-dependent is not executed, hence 5 is not being deleted. Where do I make mistake in this reasoning? How does winding and unwinding work here? Any help kindly appreciated :-)

like image 762
Simon Righley Avatar asked Jun 18 '13 20:06

Simon Righley


People also ask

How do you delete data from a binary tree?

Starting at the root, find the deepest and rightmost node in the binary tree and the node which we want to delete. Replace the deepest rightmost node's data with the node to be deleted. Then delete the deepest rightmost node.

How is a binary tree recursive?

A binary tree is a recursive data structure where each node can have 2 children at most. A common type of binary tree is a binary search tree, in which every node has a value that is greater than or equal to the node values in the left sub-tree, and less than or equal to the node values in the right sub-tree.

How do you delete an element from a binary search tree?

1) Node to be deleted is the leaf: Simply remove from the tree. 3) Node to be deleted has two children: Find inorder successor of the node. Copy contents of the inorder successor to the node and delete the inorder successor.

Which recursive tree traversal should be used to delete a tree?

The answer is simple. We should use the postorder transversal because before deleting the parent node, we should delete its child nodes first.


1 Answers

It looks like this at that point:

void destroy_tree(struct node *leaf_5)
{
  if( leaf_5 != 0 )  // it's not
  {
      destroy_tree(leaf_5->left); // it's NULL so the call does nothing
      destroy_tree(leaf_5->right); // it's NULL so the call does nothing
      free( leaf_5 );  // free here
  }
}

Nothing is required to return... the "history" of the steps is on the call stack, which looks something like this at that point:

destroy_tree(leaf_10)
  destroy_tree(leaf_10->left, which is leaf_6)
    destroy_tree(leaf_6->left, which is leaf_5)

So after leaf_5 is gone, it goes back up the stack and does destroy_tree(leaf_6->right, which is leaf_8)... etc...

like image 72
mark Avatar answered Sep 21 '22 18:09

mark