【问题标题】:Binary trees post traversal into a linked list二叉树后遍历成链表
【发布时间】:2017-09-16 09:15:16
【问题描述】:

我正在准备考试,但我不知道如何回答这个问题。

创建一个返回二叉树后遍历的链表的函数。您不能使用任何容器预先存储数据,并且它必须是递归的。

所以我不能进行post遍历,把它放在一个列表中,然后遍历它来制作一个链表。

还有另一个问题说要做同样的事情,但要进行中序遍历,这就是解决方案。

有两种解决方案。一个我不明白的,一个清晰的版本

这是主要的解决方案

def inorder(root: BTNode) -> LLNode:
"""Return the first node in a linked list that contains every value from the
binary tree rooted at root, listed according to an inorder traversal.

>>> b = BTNode(1, BTNode(2), BTNode(3))
>>> repr(inorder(b))
'LLNode(2, LLNode(1, LLNode(3)))'
>>> b2 = BTNode(4, BTNode(5))
>>> b3 = BTNode(7, b, b2)
>>> str(inorder(b3))
'2 -> 1 -> 3 -> 7 -> 5 -> 4'
>>> # from the handout...
>>> left = BTNode('B', None, BTNode('D', BTNode('G')))
>>> right = BTNode('C', BTNode('E'), BTNode('F'))
>>> root = BTNode('A', left, right)
>>> str(inorder(root))
'B -> G -> D -> A -> E -> C -> F'
"""
return _inorder(root)[0]


def _inorder(root: BTNode) -> (LLNode, LLNode):
"""Return the first and last nodes in a linked list that contains every
value from the binary tree rooted at root, listed according to an inorder
traversal.
"""
if root:
    head_left, tail_left = _inorder(root.left)
    head_right, tail_right = _inorder(root.right)
    node_root = LLNode(root.item, head_right)
    if tail_left:
        tail_left.link = node_root
    return head_left or node_root, tail_right or node_root
else:
    return None, None

明确的解决方案

def inorder(root: BTNode) -> LLNode:
"""Return the first node in a linked list that contains every value from the
binary tree rooted at root, listed according to an inorder traversal.

>>> b = BTNode(1, BTNode(2), BTNode(3))
>>> repr(inorder(b))
'LLNode(2, LLNode(1, LLNode(3)))'
>>> b2 = BTNode(4, BTNode(5))
>>> b3 = BTNode(7, b, b2)
>>> str(inorder(b3))
'2 -> 1 -> 3 -> 7 -> 5 -> 4'
>>> # from the handout...
>>> left = BTNode('B', None, BTNode('D', BTNode('G')))
>>> right = BTNode('C', BTNode('E'), BTNode('F'))
>>> root = BTNode('A', left, right)
>>> str(inorder(root))
'B -> G -> D -> A -> E -> C -> F'
"""
return _inorder(root)[0] # what must this first item represent?


def _inorder(root: BTNode) -> (LLNode, LLNode): # what are these 1st and 2nd things?
"""Return the first and last nodes in a linked list that contains every
value from the binary tree rooted at root, listed according to an inorder
traversal.

>>> left = BTNode('B', None, BTNode('D', BTNode('G')))
>>> right = BTNode('C', BTNode('E'), BTNode('F'))
>>> root = BTNode('A', left, right)
>>> str(inorder(root))
'B -> G -> D -> A -> E -> C -> F'
"""    

if not root:
    return None, None

    else:
    # Start off by making a new node of our item, with None for a link
    # Obviously we will need to replace that None if we have a right branch
    new_node = LLNode(root.item)

    # Recursive call on right branch gives us its head and tail        
    right_head, right_tail = _inorder(root.right)

    # The link on our new node should be the right head, even if it's None
    new_node.link = right_head

    # Ultimately the tail for this whole node will be the rightmost tail
    # If there is no right side, though, this node is the rightmost tail
    if not right_tail:
        right_tail = new_node

    # Recursive call on left branch gives us its head and tail
    left_head, left_tail = _inorder(root.left)

    # If there is a left tail, we should string our current node to the end
    if left_tail:
        left_tail.link = new_node

    # Ultimately the head for this whole node will be the leftmost head
    # If there is no left head, though, this node is the leftmost head
    if not left_head:
        left_head = new_node

     # Return the leftmost head and the rightmost tail
    return left_head, right_tail

【问题讨论】:

    标签: algorithm python-3.x recursion linked-list binary-tree


    【解决方案1】:

    我不确定是什么让您无法理解主要解决方案。评论很好地解释了这一点。在任何情况下,对_inorder(root.left) 的递归调用将左子树展平,并返回结果列表的头部和尾部。同样,对_inorder(root.right) 的递归调用会展平右子树。现在你有两个列表,

    head_left-> ... ->tail_left
    head_right-> ... ->tail_right
    

    将它们与根缝合,

    head_left-> ... ->tail_left->root->head_right-> ... ->tail_right
    

    并返回结果列表

    head_left-> ... ->tail_right
    

    要实现后序,按如下方式缝合它们

    head_left-> ... ->tail_left->head_right-> ... ->tail_right->root
    

    然后返回

    head_left-> ... ->root
    

    【讨论】:

    • 谢谢,这帮助我理解了更多。如果tail_left:tail_left.link = node_root,我在主要解决方案中不明白的部分。我不明白,因为 tail_left 没有被返回,那么为什么将它链接到节点很重要,或者它是否在递归调用中链接到 head_left 的某个地方?另外我不理解 head_left 或 node_root、tail_right 或 node_root 的语法。
    • @andresmejia 链接 tail_left 使列表连接起来。
    • 花了一些时间后,我想不通。你介意告诉我解决方案吗?我的考试已经过去了,现在只是出于好奇
    • @andresmejia 恐怕我不能添加比您在原始帖子中 主要解决方案 中已有的更多内容。
    猜你喜欢
    • 2017-08-23
    • 2012-01-01
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    相关资源
    最近更新 更多