【问题标题】:Binary tree inorder traversal using generator使用生成器的二叉树中序遍历
【发布时间】:2015-10-23 11:48:51
【问题描述】:

说明

我希望我的二叉树是可迭代的,这样我就可以循环访问每个节点一次。此外,inorder 是一个生成器函数,它返回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

参考

https://stackoverflow.com/a/6916433/4260745

【问题讨论】:

    标签: python algorithm data-structures generator


    【解决方案1】:

    问题是你调用了self.inorder(node.left),但是没有对结果做任何事情,结果代码只是简单的执行了(懒惰执行好,意思是没有执行),运行环境继续下一行。

    您需要通过传播(即重新生成)调用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
    

    【讨论】:

    • 如果self.inorder(node.left) 将被调用,那么在函数定义中我正在做yield node 无论如何,即对于左右子树的每次调用,我们无论如何都会产生该子树的根。可能是我被一些错误的模型困住了。
    • @CodeYogi:不,您必须了解 yield 会将您的方法变成生成器。所以self.inorder(node.left) 返回一个生成器。由于您不对(惰性)生成器执行任何操作,因此会立即处理延续。
    • 因此,生成器的递归无法按预期工作。如果有print 代替yield 那么我认为它的行为会正确。
    • @CodeYogi:确实是的,但是在函数中打印东西(旨在计算事物)被认为是糟糕的设计。只有旨在与用户交互的功能才应该这样做。
    猜你喜欢
    • 2021-10-10
    • 2013-01-26
    • 2017-05-28
    • 1970-01-01
    • 2020-03-17
    • 2021-03-08
    • 2020-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多