The reason this doesn't work is that res only has the value of the first node you give it appended to it; each time you recursively recall the function, it just makes a new res. It is a simple fix though, as follows:
class Solution(object):
def inorderTraversal(self, root):
res = []
if root:
res = self.inorderTraversal(root.left)
res.append(root.val)
res = res + self.inorderTraversal(root.right)
return res
In this, it returns the left branch, the value, and then the right. This can be done much more briefly as follows:
class Solution(object):
def inorderTraversal(self, root):
return (self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)) if root else []
Use this instead , a simple recursion ::
class Node:
def __init__(self,key):
self.left = None
self.right = None
self.val = key
def printInorder(root):
if root:
printInorder(root.left)
print(root.val)
printInorder(root.right)
def printPostorder(root):
if root:
printPostorder(root.left)
printPostorder(root.right)
print(root.val)
def printPreorder(root):
if root:
print(root.val)
printPreorder(root.left)
printPreorder(root.right)
# Driver code
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
print "Preorder traversal of binary tree is"
printPreorder(root)
print "\nInorder traversal of binary tree is"
printInorder(root)
print "\nPostorder traversal of binary tree is"
printPostorder(root)
Source :: here
One useful tool for understanding the path that an algorithm takes is to add logging to it.
def inorder_print(self, start, traversal, indent=""):
"""Left -> root -> right"""
if start:
print(f"{indent} {start.data} <- '{traversal}'")
traversal = self.inorder_print(start.left, traversal, indent+" ")
traversal += (str(start.data) + "-")
print(f"{indent} {start.data} -- '{traversal}'")
traversal = self.inorder_print(start.right, traversal, indent+" ")
print(f"{indent} {start.data} -> '{traversal}'")
return traversal
allows us to visualize the tree and the order in which each node is added to the traversal:
1 <- ''
2 <- ''
4 <- ''
4 -- '4-'
4 -> '4-'
2 -- '4-2-'
5 <- '4-2-'
5 -- '4-2-5-'
5 -> '4-2-5-'
2 -> '4-2-5-'
1 -- '4-2-5-1-'
3 <- '4-2-5-1-'
6 <- '4-2-5-1-'
6 -- '4-2-5-1-6-'
6 -> '4-2-5-1-6-'
3 -- '4-2-5-1-6-3-'
7 <- '4-2-5-1-6-3-'
7 -- '4-2-5-1-6-3-7-'
8 <- '4-2-5-1-6-3-7-'
8 -- '4-2-5-1-6-3-7-8-'
8 -> '4-2-5-1-6-3-7-8-'
7 -> '4-2-5-1-6-3-7-8-'
3 -> '4-2-5-1-6-3-7-8-'
1 -> '4-2-5-1-6-3-7-8-'
The indentation shows the depth of the stack. Each individual recursive call has three parts -- the left child, self.data, and the right child.
The code "knows" that 2 goes after 4 because 4 happens at the start of 2's call, and the string '2-' is appended immediately afterward:
2 <- '' # start of 2's call. 2 starts by calling 4
4 <- '' # start of 4's call
4 -- '4-' # 4 appends self.data
4 -> '4-' # end of 4's call, returning to 2
2 -- '4-2-' # 2 appends self.data to what it got from 4, and calls 5
5 <- '4-2-' # start of 5's call
5 -- '4-2-5-' # 5 appends self.data
5 -> '4-2-5-' # end of 5's call, returning to 2
2 -> '4-2-5-' # end of 2's call
Ok, sat with it a little longer and figured it out. Thought id post my thoughts so that this question can be marked as answered.
- inorder func is called with root and empty string.
- start has value of tree.root, while start has value it keeps recursing at traversal = self.inorder_print(start.left, traversal)
- it is to be noted, that each time a recursion happens you go further into the tree. start.data = 1. recursion, start.data = 2 recursion, start.data = 4. due to the fact that 4 does not have a left child. the function can finally return. start.data now = 4 and the next line traveral += str(start.data) + "-") can run, adding to the string. However remember that the function is still 2 recurrsions deep. our start.data is back to 2. as that function has finished executing, 2 gets added to traversal via line traveral += str(start.data) + "-")/ #recursion happens with start.right. start.data now =5 start.right has no value, so the function can return 5. this process continues for the whole tree, until all of the functions that have been executed have been completed. the trick to undertanding (at least for me) is that the when you return to a higher level in recursion, the function starts off where it left and doenst start the function from the beginning.