The problem I am tackle with is to find the first occurrence node in its inorder traversal in a BST.
The code I have is given below
def Inorder_search_recursive(node,key):
if not node:
return None
InOrder_search_recursive(node.lChild)
if node.value==key:
return node
InOrder_search_recursive(node.rChild)
This code always return None, what's wrong with it. I think I've return node when I find a node with value k. Why cannot python pass this node???Thanks in advance
When you call yourself recursively, like this:
InOrder_search_recursive(node.lChild)
That's just a normal function call, like any other. It just calls the function and gets back a result. It doesn't automatically return
the value from that function, or do anything else.
So, you do the left-subtree search, ignore the results, then go on to check node.value == key
, and, if that fails, you do the right-subtree search, again ignore the results, and fall off the end of the function, meaning you return None
.
To make this work, you need to return
the value you got back. But, of course, only if it's not None
.
Also, you forgot to pass the key
argument down to the recursive call, so you're just going to get a TypeError
. (I'm guessing your real code doesn't have this problem, but since you didn't show us your real code, or a working example, I can't be sure…)
So:
def Inorder_search_recursive(node, key):
if not node:
return None
result = InOrder_search_recursive(node.lChild, key)
if result is not None:
return result
if node.value==key:
return node
return InOrder_search_recursive(node.rChild, key)
(You don't need the not None
check for the right-side search, because if it returns None
, we have nothing else to try and are just going to return None
anyway.)
My other answer gives the novice-friendly solution, but if you want more powerful and concise answer:
def Inorder_search_recursive_all(node, key):
if not node:
return
yield from InOrder_search_recursive(node.lChild, key)
if node.value==key:
yield node
yield from InOrder_search_recursive(node.rChild, key)
This generates all matches in the tree, in order. And it gives them to you as an iterator, so if you just want the first, you can stop as soon as you find one, with no wasted work:
def Inorder_search_recursive(node, key):
return next(Inorder_search_recursive_all(node, key), None)
The tutorial section on Iterators and the following section on Generators explains most of how this works. The only missing bit is an explanation of yield from
, which is explained in PEP 380.
Since your problem is to find the first occurrence node in its inorder traversal
, you should 1) traverse the tree in-order and 2) stop when you find the first occurrence.
def search(node, key):
if node is None:
return None
# Search the left subtree and return early if key is found
n = search(node.lChild, key)
if n is not None:
return n
# Check middle and return early if key is found
if node.value == key:
return node
# Search right subtree
return search(node.rChild, key)