【问题标题】:Tree traversals python树遍历python
【发布时间】:2016-02-11 21:05:47
【问题描述】:

我必须定义三个函数:preorder(t):postorder(t):inorder(t):

每个函数都将二叉树作为输入并返回一个列表。然后应该以与在相应遍历中访问树元素相同的方式对列表进行排序(后序、前序或中序)

我已经为它们中的每一个编写了代码,但是当我调用另一个函数 (flat_list()) 时,我不断收到错误,我收到了一个由引发的索引错误

if not x or len(x) < 1 or  n > len(x) or x[n] == None:
    IndexError: list index out of range

我的遍历方法代码如下:

def postorder(t):
    pass
    if t != None:
        postorder(t.get_left())
        postorder(t.get_right())
    print(t.get_data())

def pre_order(t):
    if t != None:
        print(t.get_data())
        pre_order(t.get_left())
        pre_order(t.get_right())

def in_order(t):
    pass
    if t != None:
        in_order(t.get_left())
        print(t.get_data())
        in_order(t.get_right())

def flat_list2(x,n):
  if not x or len(x) < 1 or  n > len(x) or x[n] == None:
    return None

   bt = BinaryTree( x[n] )
   bt.set_left( flat_list2(x, 2*n))
   bt.set_right(flat_list2(x, 2*n + 1))
 return bt

这就是我调用 flat_list2 的方式

flat_node_list = [None, 55, 24, 72, 8, 51, None, 78, None, None, 25]
bst = create_tree_from_flat_list2(flat_node_list,1)

    pre_order_nodes = pre_order(bst)

    in_order_nodes = in_order(bst)

    post_order_nodes = post_order(bst)

    print( pre_order_nodes)

    print( in_order_nodes)

    print( post_order_nodes)

【问题讨论】:

    标签: python-3.x binary-tree inorder preorder postorder


    【解决方案1】:

    您实际上应该编写三个返回迭代器的函数。让调用者决定是否需要列表。使用生成器功能最容易做到这一点。在 3.4+ 中,可以使用 'yield from' 代替 for 循环。

    def in_order(t):
        if t != None:
            yield from in_order(t.get_left())
            yield t.get_data()
            yield from in_order(t.get_right())
    

    移动其他两个版本的 yield 语句。

    【讨论】:

    • 如果不是 x 或 len(x) len(x) 或 x[n] == None: IndexError: list index out of range
    • 我认为您需要将n &gt; len(x) 更改为n &gt;= len(x)。因为python序列是从0开始的,对于一个长度为k的序列,最大的合法索引是k-1,而不是k。
    【解决方案2】:

    首先,我注意到您提供的代码块中的缩进不一致(已在修订中修复)。 关键确保你的缩进在Python 中是一致的,否则东西会很快变南。另外,在下面的代码中,我假设您希望您的t.get_data() 仍属于您的postorder(t) 中的if t != None,因此我在下面进行了缩进。最后,我注意到您的方法名称与您在问题中列出的规范不匹配,因此我更新了下面的方法名称以符合您的规范(命名中没有 _)。

    要获取列表,您需要做的就是让您的遍历方法返回一个列表,然后extend 您的列表在每个遍历级别与其他遍历的值。这样做是为了代替打印数据。

    def postorder(t):
        lst = []
        if t != None:
            lst.extend(postorder(t.get_left()))
            lst.extend(postorder(t.get_right()))
            lst.append(t.get_data())
        return lst
    
    def preorder(t):
        lst = []
        if t != None:
            lst.append(t.get_data())
            lst.extend(preorder(t.get_left()))
            lst.extend(preorder(t.get_right()))
        return lst
    
    def inorder(t):
        lst = []
        if t != None:
            lst.extend(inorder(t.get_left()))
            lst.append(t.get_data())
            lst.extend(inorder(t.get_right()))
        return lst
    

    这将遍历每个节点左右的全部深度,并且根据它是preorderpostorder 还是inorder,将按照遍历的顺序附加所有遍历的元素。一旦发生这种情况,它会将正确排序的列表返回到下一级以附加到其列表中。这将递归,直到您回到根级别。

    现在,来自您的flat_listIndexError 可能是由于尝试访问x[n] 而导致n 可能等于len(x)。请记住Python 中的列表/数组是从0 索引的,这意味着列表的最后一个元素将是x[n-1],而不是x[n]

    因此,要解决此问题,请将 x[n] 替换为 x[n-1]。像这样:

    def flat_list2(x,n):
        if not x or len(x) < 1 or n < 1 or n > len(x) or x[n-1] == None:
            return None
    
        bt = BinaryTree( x[n-1] )
        bt.set_left( flat_list2(x, 2*n))
        bt.set_right(flat_list2(x, 2*n + 1))
        return bt
    

    【讨论】:

    • 嘿,它仍然打印出错误,显示我的 flat_list 方法
    • 我得到一个空列表,因为输出一直在尝试修复,但无法找出问题所在
    • Pre = [] In = [] Post = [] 这就是输出看起来像 atm 的样子
    • 你知道为什么我仍然没有得到输出吗? ://
    • @deans7 请问你怎么称呼flat_list2
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多