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 :-)
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.
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.
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.
The answer is simple. We should use the postorder transversal because before deleting the parent node, we should delete its child nodes first.
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With