I'm trying to run the classic algorithms for tree traversing. I've created an example tree and tested whether the preorder, inorder and postorder algorithms worked correctly. But after that tests I get incorrect results. When I run the preorder algorithm starting on node A, I get this sequence {A,C,H,D,G}
, when I should be getting {A,C,D,H,G}
.
I don't think I'm missing something in the traversing part of the code, but maybe I am in the tree definition. I can't see the error myself.
class Node:
id = 0
def __init__(self,value):
self.id = id
Node.id += 1
self.value = value
self.left_child = None
self.right_child = None
def insert_left_child(self, new_node):
if self.is_leaf():
self.insert_left_child(new_node);
else:
# As there is already a left child, the pointers must be
# redistributed to include the new child.
current_left_child = self.left_subtree()
self.insert_left_child(new_node)
new_node.insert_left_child(current_left_child)
def insert_right_child(self, new_node):
if self.is_leaf():
self.insert_right_child(new_node);
else:
# As there is already a right child, the pointers must be
# redistributed to include the new child.
current_right_child = self.right_subtree()
self.insert_right_child(new_node)
new_node.insert_right_child(current_right_child)
def left_subtree(self):
return self.left_child
def right_subtree(self):
return self.right_child
def insert_left_child(self,child_node):
self.left_child = child_node
def has_left_children(self):
return self.left_child != None
def insert_right_child(self,child_node):
self.right_child = child_node
def has_right_children(self):
return self.right_child != None
def is_leaf(self):
return (not self.has_left_children()) & (not self.has_right_children())
class BinaryTree:
def __init__(self):
self.root = Node('root')
def preorder(self,current_node = None):
if current_node is None:
current_node = self.root
print current_node.value
if current_node.has_left_children():
self.inorder(current_node.left_subtree())
if current_node.has_right_children():
self.inorder(current_node.right_subtree())
def inorder(self,current_node = None):
if current_node is None:
current_node = self.root
if current_node.has_left_children():
self.inorder(current_node.left_subtree())
print current_node.value
if current_node.has_right_children():
self.inorder(current_node.right_subtree())
def postorder(self,current_node = None):
if current_node is None:
current_node = self.root
if current_node.has_left_children():
self.inorder(current_node.left_subtree())
if current_node.has_right_children():
self.inorder(current_node.right_subtree())
print current_node.value
# Main routine
# root
# A B
# C D E F
# H G
tree = BinaryTree()
A = Node('A')
B = Node('B')
C = Node('C')
D = Node('D')
E = Node('E')
F = Node('F')
G = Node('G')
H = Node('H')
tree.root.insert_left_child(A)
tree.root.insert_right_child(B)
A.insert_left_child(C)
A.insert_right_child(D)
B.insert_left_child(E)
B.insert_right_child(F)
D.insert_left_child(H)
D.insert_right_child(G)
tree.preorder(A)
You call inorder
methods from preorder
method. So you change the algorithm when getting deeper in the tree:
if current_node.has_left_children():
self.inorder(current_node.left_subtree())
if current_node.has_right_children():
self.inorder(current_node.right_subtree())
should be:
if current_node.has_left_children():
self.preorder(current_node.left_subtree())
if current_node.has_right_children():
self.preorder(current_node.right_subtree())