【问题标题】:Inorder Binary Tree Traversal (using Python)中序二叉树遍历(使用 Python)
【发布时间】:2017-05-28 02:11:35
【问题描述】:

我正在尝试对树进行中序遍历。代码本身感觉不错,只是它不能正常工作。我有一种感觉,它要么与 if 条件、append 在 python 中的工作方式有关,要么与 return 相关。我认为,如果我使用 print 而不是 return,这可以正常工作,但我希望能够使用 return 并且仍然得到正确的答案。例如,对于树 [1,None,2,3],我的代码返回 [1],这显然是不正确的。

另外,是否可以使用列表理解来解决这个问题?如果是这样,任何示例代码将不胜感激。

这是我的代码:

    class Solution(object):
        def inorderTraversal(self, root):
            res = []
            if root:
                self.inorderTraversal(root.left)
                res.append(root.val)
                self.inorderTraversal(root.right)
            return res

此外,在将其标记为重复之前,我知道在 Stackoverflow 上已按顺序询问了遍历(很多次),但它们都没有帮助我理解为什么我的理解是错误的。如果有人帮助我学习如何纠正我的方法,而不是简单地发布另一个链接而没有解释,我将非常感激。非常感谢!

【问题讨论】:

  • 树的结构如何?
  • 它是一棵二叉树(不一定是二叉搜索)。例如,传递给 root 的列表的格式为 root, left tree, right tree....[1,None,2,3] 的根为 1,没有左孩子,右孩子为 2(它有3) 的左孩子。
  • 我问的原因是因为您似乎正在为root 传递一个列表,但列表没有leftright 属性

标签: python list binary-tree inorder


【解决方案1】:

这不起作用的原因是res 仅具有您为其附加的第一个节点的值;每次递归调用该函数时,它只会生成一个新的 res。这是一个简单的修复方法,如下所示:

class Solution(object):
    def inorderTraversal(self, root):
        res = []
        if root:
            res = self.inorderTraversal(root.left) 
            res.append(root.val)
            res = res + self.inorderTraversal(root.right)
        return res

在此,它返回左分支、值,然后返回右分支。这可以更简单地完成如下:

class Solution(object):
    def inorderTraversal(self, root):
        return (self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)) if root else []

【讨论】:

  • 非常感谢!这很有意义。
  • 不是每次调用 inorderTraversal 都会将您的结果列表重置为空字符串,因为这是您在函数中执行的第一件事吗?
  • @NicholasJohnson 没有;对inorderTraversal 的每次调用都包含其自己独立的res 实例,这是该调用所独有的。
【解决方案2】:

改用这个,一个简单的递归::

class Node:
    def __init__(self,key):
        self.left = None
        self.right = None
        self.val = key

def printInorder(root):
    if root:
        printInorder(root.left)
        print(root.val)
        printInorder(root.right)

def printPostorder(root):
    if root:
        printPostorder(root.left)
        printPostorder(root.right)
        print(root.val)

def printPreorder(root):
    if root:
        print(root.val)
        printPreorder(root.left)
        printPreorder(root.right)

# Driver code
root = Node(1)
root.left      = Node(2)
root.right     = Node(3)
root.left.left  = Node(4)
root.left.right  = Node(5)
print "Preorder traversal of binary tree is"
printPreorder(root)

print "\nInorder traversal of binary tree is"
printInorder(root)

print "\nPostorder traversal of binary tree is"
printPostorder(root)

来源 :: here

【讨论】:

    【解决方案3】:

    @Benedict Randall Shaw 的回答已经很完美了。我只是想以 Pythonic 的方式为其添加一些乐趣。尽管doc 不建议使用可变对象作为默认参数,但这将通过将默认可变list 视为python 函数的类成员来简化代码。

    区别只是+==替换,因为在函数对象被垃圾回收之前,res在函数内部总是相同的list对象。

    def inorderTraversal(root, res=[]):
        if root:
            res = inorderTraversal(root.left)
            res.append(root.val)
            res = inorderTraversal(root.right)
    return res
    

    【讨论】:

    • 这种方法的问题是列表“res”在函数“inorderTraversal()”的整个生命周期中都被维护。对该函数的多次调用将继续附加到“res”列表中。
    【解决方案4】:

    另一种输出列表的方法,优点是您只需将值添加到单个列表:

    def inorder(root):
        return_list = []
        def innerInOrder(root):
            if root == None:
              return
            innnerInOrder(root.left)
            return_list.append(root.data)
            innerInOrder(root.right)
        innerInOrder(root)
        return return_list
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-08
      • 2020-01-15
      • 1970-01-01
      • 1970-01-01
      • 2016-01-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多