【问题标题】:Traverse Non-Binary Tree [closed]遍历非二叉树
【发布时间】:2014-12-23 17:32:32
【问题描述】:

我正在尝试遍历非二叉树。树的字符串表示形式,如list,是:

['TOP', ['S', ['NP', ['PRP', 'I']], ['VP', ['VBP', '需要'], ['NP', ['NP', ['DT', 'a'], ['NN', 'flight']], ['PP', ['IN', 'from'], ['NP', ['NNP', '亚特兰大']]], ['PP', ['TO', 'to'], ['NP', ['NP', ['NNP', '夏洛特']], ['NP', ['NNP', 'North'], ['NNP', 'Carolina']]]], ['NP', ['JJ', '下一个'], ['NNP', '星期一']]]]]]

这是来自Penn Treebank。最终,我想把它变成一棵二叉树,但首先我需要一种按原样遍历树的方法。

【问题讨论】:

    标签: python tree


    【解决方案1】:
    def traverse(tree_of_lists):
        for item in tree_of_lists:
            if isinstance(item, list):
                for x in traverse(item):
                    yield x
            else:
                yield item
    

    这是“基本”解决方案——可以在 Python 2.7 中运行,并为您提供一个可以简单循环的可迭代对象。 (在最近的 Python 3.* 版本中,您将使用 yield from item 而不是内部的 for 循环)。

    isinstance 测试令人不快,但根据您的具体问题,它可能是区分“标量项”和“子树”的唯一方法。可能有更好的,但你没有给我们足够的信息来告诉我们。例如,如果所有“叶子”(标量)都是字符串,您可能更愿意检查它(仍然是 isinstance 检查,唉!)。

    【讨论】:

    • “标量项”是什么意思?
    • @Adam_G 单个值,而不是列表。
    • 也称为“一片叶子”,在你对树的表观表示中,除了“子树”之外的任何东西(看起来你所有的子树都是列表,你所有的叶子/scalars 是字符串,但这只是从那个例子中推断出来的,因此有点脆弱,缺少明确声明的规范)。
    • 你是对的。由于这是一个句子的表示,因此最低级别将是一个单词。
    • @Adam_G,当然——例如for x in traverse(tree): print(x)——还有很多很多其他人。
    【解决方案2】:

    有很多方法可以遍历一棵树。选项包括:

    • 前序遍历 - 发出当前节点,然后递归遍历其子节点
    • 后序遍历——递归遍历当前节点,然后发出当前节点
    • 按顺序遍历 - 递归遍历左孩子。然后发出当前节点。最后,遍历右孩子。表示二叉树,但如果您有办法将孩子分成“左”和“右”组,它可以适应一般树。

    您可以通过将节点附加到累积列表来“发出”节点,但更好的方法是使用生成器和yield 节点。

    您可以在Wikipedia page on tree traversal 上找到这些选项和其他选项。选择一个满足您的需求。

    【讨论】:

    • 嗯,这是一个非常基本的问题,快速的 Google 可以轻松找到。此外,遍历树的方法有很多种,而这个问题并没有说明需要哪种方法。
    猜你喜欢
    • 2021-01-12
    • 1970-01-01
    • 2012-01-01
    • 2022-11-11
    • 2021-11-20
    • 1970-01-01
    • 2021-03-08
    • 2020-01-15
    相关资源
    最近更新 更多