I am trying to create a module in python for iterating over a binary tree using the 4 standard tree traversals (inorder, preorder, postorder and levelorder) without using conditionals and only using polymorphic method dispatch or iterators. The following examples should work.
for e in t.preorder():
print(e)
for e in t.postorder():
print(e)
for e in t.inorder():
print(e)
for e in t.levelorder():
print(e)
So far I have come up with the following
def build_tree(preord, inord):
tree = BinaryTree()
tree.root = buildTreeHelper(preord, inord)
return tree
def buildTreeHelper(preorder, inorder):
if len(inorder) == 0:
return None
elem = preorder[0]
elemInorderIndex = inorder.find(elem)
if elemInorderIndex > -1:
leftPreorder = preorder[1:elemInorderIndex + 1]
rightPreorder = preorder[elemInorderIndex + 1:]
leftInorder = inorder[0:elemInorderIndex]
rightInorder = inorder[elemInorderIndex + 1:]
left = buildTreeHelper(leftPreorder, leftInorder)
right = buildTreeHelper(rightPreorder, rightInorder)
return BinaryTreeNode(elem, left, right)
else:
return "No valid tree for the given args"
class BinaryTree:
def __init__(self):
self.root = None
def preorder(self):
return self.root.preorder()
def inorder(self):
return self.root.inorder()
def postoder(self):
return self.root.postorder()
class BinaryTreeNode:
def __init__(self, element, left=None, right=None):
self.element = element
self.left = left
self.right = right
def preorder(self):
yield self.element
for e in self.left.preorder():
yield e
for e in self.right.preorder():
yield e
def inorder(self):
for e in self.left.inorder():
yield e
yield self.element
for e in self.right.inorder():
yield e
def postorder(sel开发者_如何学编程f):
for e in self.left.postorder():
yield e
for e in self.right.postorder():
yield e
yield self.element
if __name__ == "__main__":
t = build_tree("BAC", "ABC")
for e in t.inorder():
print(e)
When I try to run one of the iterators like at the bottom of the code I get an AttributeError: 'NoneType' object has no attribute 'inorder' error message. I think this is because I never raise StopIteration. Any ideas on how to fix this and start implementing levelorder?
You said you wanted to use polymorphism, but you don't actually seem to have done so. Replace all occurrences of 'None' in your code with a special object that supports your methods but returns an empty sequence and it will all work.
Also you should take more care of the indentation when posting Python questions. The code you posted won't run as is.
def build_tree(preord, inord):
tree = BinaryTree()
tree.root = buildTreeHelper(preord, inord)
return tree
def buildTreeHelper(preorder, inorder):
if len(inorder) == 0:
return empty
elem = preorder[0]
elemInorderIndex = inorder.find(elem)
if elemInorderIndex > -1:
leftPreorder = preorder[1:elemInorderIndex + 1]
rightPreorder = preorder[elemInorderIndex + 1:]
leftInorder = inorder[0:elemInorderIndex]
rightInorder = inorder[elemInorderIndex + 1:]
left = buildTreeHelper(leftPreorder, leftInorder)
right = buildTreeHelper(rightPreorder, rightInorder)
return BinaryTreeNode(elem, left, right)
else:
return "No valid tree for the given args"
class BinaryTree:
def __init__(self):
self.root = empty
def preorder(self):
return self.root.preorder()
def inorder(self):
return self.root.inorder()
def postorder(self):
return self.root.postorder()
class EmptyNode:
def preorder(self):
return ()
inorder = postorder = preorder
empty = EmptyNode()
class BinaryTreeNode:
def __init__(self, element, left=empty, right=empty):
self.element = element
self.left = left
self.right = right
def preorder(self):
yield self.element
for e in self.left.preorder():
yield e
for e in self.right.preorder():
yield e
def inorder(self):
for e in self.left.inorder():
yield e
yield self.element
for e in self.right.inorder():
yield e
def postorder(self):
for e in self.left.postorder():
yield e
for e in self.right.postorder():
yield e
yield self.element
if __name__ == "__main__":
t = build_tree("BAC", "ABC")
for e in t.inorder():
print(e)
精彩评论