使用生成器的二叉树中序遍历
Binary tree inorder traversal using generator
描述
我希望我的二叉树是可迭代的,这样我就可以遍历它以访问每个节点一次。此外,inorder
是一个生成器函数,它 returns 和 Iterator
因此满足 Iterable
契约。但是我下面的代码不是生成每个节点,而是生成根节点,在这种情况下是 A
。我做错了什么?
代码
from collections import namedtuple
Node = namedtuple('Node', 'data, left, right')
root = Node('A',
Node('B', Node('D', None, None), Node('E', None, None)),
Node('C', None, Node('F', None, None)))
class BinaryTree(object):
def __init__(self, root=None):
self.root = root
def __iter__(self):
return self.inorder(self.root)
def inorder(self, node):
if node is None:
return
if node.left is not None:
self.inorder(node.left)
yield node
if node.right is not None:
self.inorder(node.right)
bt = BinaryTree(root)
for node in bt:
print node.data
参考
问题是你调用了self.inorder(node.left)
,但是没有对结果做任何事情,结果只是简单的执行了代码(well executed lazily,意思是不执行),然后运行时环境继续下一行。
您需要通过传播(即重新产生)通过调用 inorder
:
生成的元素来解决它
def inorder(self, node):
if node is None:
return
if node.left is not None:
for x in self.inorder(node.left) :
# you need to *re-yield* the elements of the left and right child
yield x
yield node
if node.right is not None:
for x in self.inorder(node.right) :
yield x
描述
我希望我的二叉树是可迭代的,这样我就可以遍历它以访问每个节点一次。此外,inorder
是一个生成器函数,它 returns 和 Iterator
因此满足 Iterable
契约。但是我下面的代码不是生成每个节点,而是生成根节点,在这种情况下是 A
。我做错了什么?
代码
from collections import namedtuple
Node = namedtuple('Node', 'data, left, right')
root = Node('A',
Node('B', Node('D', None, None), Node('E', None, None)),
Node('C', None, Node('F', None, None)))
class BinaryTree(object):
def __init__(self, root=None):
self.root = root
def __iter__(self):
return self.inorder(self.root)
def inorder(self, node):
if node is None:
return
if node.left is not None:
self.inorder(node.left)
yield node
if node.right is not None:
self.inorder(node.right)
bt = BinaryTree(root)
for node in bt:
print node.data
参考
问题是你调用了self.inorder(node.left)
,但是没有对结果做任何事情,结果只是简单的执行了代码(well executed lazily,意思是不执行),然后运行时环境继续下一行。
您需要通过传播(即重新产生)通过调用 inorder
:
def inorder(self, node):
if node is None:
return
if node.left is not None:
for x in self.inorder(node.left) :
# you need to *re-yield* the elements of the left and right child
yield x
yield node
if node.right is not None:
for x in self.inorder(node.right) :
yield x