Michael's answer explains the way you were probably supposed to approach the problem, but he didn't explain what was wrong with your current attempt. As I understand it, your strategy was to examine each node, and keep track of the lowest value as you go, using recursion to find all the nodes. Once you've examined all the nodes, you know the result is the minimum for the entire tree. This is a perfectly valid approach, and it would have worked except that arguments don't quite work the way you seem to expect.
Python passes arguments by value, not by reference. When you assign a value to min_t using "min_t = root.key", it only takes effect inside of the function. The caller of the function does not see the new value.
You can test this with some simpler code:
def add_one_to(x):
x = x + 1
print "add_one_to", x
x = 2
add_one_to(x)
print x
You can see when you run the code that x was incremented inside the function but not in the top level.
This also applies when a function calls itself. Each call has its own set of local variables, and assigning to a local variable inside the function does not affect the instance that called it.
Note that some languages do allow you to pass arguments by reference. If you pass an argument by reference, then assigning that argument inside the function will also affect the caller. If Python were one of those languages, you could make min_t a reference argument, and your function would work correctly.
While Python doesn't support reference arguments directly, you can also think of a reference argument as a value that goes into the function when it is called and also is passed back to the caller when the function completes. You can do both of these things separately. To pass a value back to the caller, return that value. The caller can then assign that function to its local, and you have basically passed an argument by reference.
Here's how you could apply that to the example above:
def add_one_to(x):
x = x + 1
print "add_one_to", x
return x
x = 2
x = add_one_to(x)
print x
Just add a return value and assignment, and it works as it should.
You could also apply this to your original function:
def min(root, min_t): # min_t is the initially the value of root
if not root:
return min_t
if root.key < min_t:
min_t = root.key
min_t = min(root.left, min_t)
min_t = min(root.right, min_t)
return min_t
All I did was add "min_t = " before each call to min() and change your return statement to return min_t at the end. (I think you probably meant to return min_t anyway. min is the name of your function, so that wouldn't have made much sense.) I believe that version will work.
Edit: The reason your min_tree function works, in spite of all this, is that n is a list, and lists are mutable objects. When I'm was talking about "values" above, what I really meant was "object". Each variable name in python maps to a specific object. If you have code like this:
def replace_list(x):
x = [1, 2, 3]
x = [2]
replace_list(x)
print x
The result is [2]. So, if you assign a new value to x with "x =", the caller won't see it. However, if you do this:
def replace_list(x):
x.append(1)
x = [2]
replace_list(x)
print x
The result is [2, 1]. This is because you haven't changed the value of x; x still points to the same list. However, that list now contains an additional value. Unfortunately, the "+=" operator is confusing in this respect. You might think that "x += y" is the same as "x = x + y", but in Python that is not always the case. If "x" is a kind of object that supports "+=" specifically, then that operation will modify the object in place. Otherwise, it will be the same as "x = x + 1". Lists know what to do with "+=", so using += with a list will modify it in place, but using it with a number will not.
You can actually test this without doing any function calls:
x = [1, 2]
y = x
y += [3]
print x # [1, 2, 3]
print y # [1, 2, 3]
print x is y # True, x and y are the same object, which was modified in place
x = [1, 2]
y = x
y = y + [3]
print x # [1, 2]
print y # [1, 2, 3]
print x is y # False, y is a new object equal to x + [3]
x = 1
y = x
y += 2
print x # 1
print y # 3
print x is y # False, y is a new object equal to x + 2