Alternatively you can use an approach that requires more processing but less memory (than a queue):
The node class itself can provide iterators that will traverse nodes in a breadth first order either top down or bottom up.
class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
@property
def maxLevel(self):
return max(self.left.maxLevel+1 if self.left else 0,
self.right.maxLevel+1 if self.right else 0)
def topDown(self):
for depth in range(self.maxLevel+1):
for node in self.nodesAtLevel(depth): yield node
def bottomUp(self):
for depth in range(self.maxLevel,-1,-1):
for node in self.nodesAtLevel(depth): yield node
def nodesAtLevel(self,depth,level=0):
if level == depth:
yield self # output node when at requested depth
return
for subNode in (self.left,self.right): # reach deeper
if not subNode: continue
for node in subNode.nodesAtLevel(depth,level+1):
yield node
output:
root = Node('A') # level 0
B = root.left = Node('B') # level 1
D = B.left = Node('D') # level 2
E = B.right = Node('E') # level 2
G = D.left = Node('G') # level 3
H = D.right = Node('H') # level 3
K = root.right = Node('K') # level 1
I = K.left = Node('I') # level 2
for node in root.topDown(): print(node.value)
# A B K D E I G H
for node in root.bottomUp(): print(node.value)
# G H D E I B K A
You could also extend the class even more to add other types of traversal iterators:
def leftToRight(self):
if self.left:
for node in self.left.leftToRight(): yield node
yield self
if self.right:
for node in self.right.leftToRight(): yield node
def rightToLeft(self):
if self.right:
for node in self.right.rightToLeft(): yield node
yield self
if self.left:
for node in self.left.rightToLeft(): yield node
To implement your path function using breadth first search, you should use the bottom up function and append parents as you find them (since parents will appear after children in that order):
def BFPath(self,node):
path = [node]
for parent in self.bottomUp():
if path[-1] in [parent.left,parent.right]:
path.append(parent)
return path[::-1]
example use:
print([n.value for n in root.BFPath(H)])
# ['A', 'B', 'D', 'H']