Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a recursive method to find the smallest element in a subtree given the root: what am I doing wrong here?

So I have a homework question where I'm supposed to use a recursive method to "find the minimum element within a subtree rooted at the specified node"

And then I'm given this as my starting point:

   public TreeNode
{
    int data;
    TreeNode left;
    TreeNode right;
}

and

/**
Finds the minimum value for the subtree that is 
rooted at a given node
@param n The root of the subtree
@return The minimum value 
PRECONDITION: n is not null.
*/
int min(TreeNode n)
{
  // COMPLETE THE BODY OF THIS METHOD
}

Now, I've got a very basic driver program written to insert nodes into the tree and I've written my recursive method, but it seems to be counting up instead of down, here's my method:

int min(TreeNode n){      
if(n.left != null) {
  n = n.left;
  min(n);
  System.out.println("N is now " + n.value);
 }
    return n.value;
   }

Output of my code:

Building tree with rootvalue 25
  =================================
  Inserted 11 to left of node 25
  Inserted 15 to right of node 11
  Inserted 16 to right of node 15
  Inserted 23 to right of node 16
  Inserted 79 to right of node 25
  Inserted 5 to left of node 11
  Inserted 4 to left of node 5
  Inserted 2 to left of node 4
    Root is 25
    N is now 2
    N is now 4
    N is now 5
    N is now 11
    The minimum integer in the given nodes subtree is: 11

Can someone please explain to me why this doesn't work?

like image 276
Kyle Avatar asked Dec 28 '22 03:12

Kyle


2 Answers

Note: this is all assuming you're in a Binary Search Tree, so returning the minimum element means returning the left-most element.

This means your recursive call is quite simple:

min(node):
  if this node has a left node:
    return min(node.left)
  if this node does not have a left node:
    return this node's value

The logic is that if we don't have another left node then we are the left-most node, so we are the minimum value.

Now, in Java:

int min(TreeNode n){
  if (n.left == null)
    return n.value;
  return min(n.left); // n.left cannot be null here
}

Now to explain your results, consider how this method works. It calls the method on the next node (min(n.left)) before continuing. In your case you had a println after this recursive call. Therefore the println inside the recursive call went first. So your prints started at the bottom of the tree and worked their way back up. This explains the "reverse order" printing.
Your method then returned 11 as your result because (as another answer has explained) your n = n.left didn't affect any of your recursive sub-calls, only the one in the current function call. This means you returned the left node of the root, rather than the furthest left child.

I hope this makes sense. If you need clarification on anything leave a comment or something. Recursion can be quite tricky to get your head around at first.

like image 129
mange Avatar answered Dec 29 '22 18:12

mange


The issue is that Java is call-by-value, not by reference -- although references are passed by value. But what that really means in this case is that the call to min(n) does not change what the variable n refers to -- it doesn't do anything at all. What you should probably be doing is return min(n).

like image 43
Louis Wasserman Avatar answered Dec 29 '22 18:12

Louis Wasserman