【问题标题】:Ouputting the binary tree in using in-order and pre-order traversal使用中序和前序遍历输出二叉树
【发布时间】:2021-07-07 14:10:06
【问题描述】:
class Node:
    def __init__(self, data, left=None, right=None):
        self.data = data
        self.left = left
        self.right = right
 
def inorderTraversal(root):
 
    if root is None:
        return
 
    inorderTraversal(root.left)
    print(root.data, end=' ')
    inorderTraversal(root.right)
 
def preorderTraversal(root):
 
    if root is None:
        return
 
    print(root.data, end=' ')
    preorderTraversal(root.left)
    preorderTraversal(root.right)
 
def construct(start, end, preorder, pIndex, dict):
 
    # base case
    if start > end:
        return None, pIndex
 
    root = Node(preorder[pIndex])
    pIndex = pIndex + 1
 
    index = dict[root.data]
 
    root.left, pIndex = construct(start, index - 1, preorder, pIndex, dict)
 
    root.right, pIndex = construct(index + 1, end, preorder, pIndex, dict)
 
    return root, pIndex     

def constructTree(inorder, preorder):
 
    dict = {}
    for i, e in enumerate(inorder):
        dict[e] = i
 
    pIndex = 0
 
    return construct(0, len(inorder) - 1, preorder, pIndex, dict)[0]
 
 
if __name__ == '__main__':
 
 
    inorder = [4, 2, 1, 7, 5, 8, 3, 6]
    preorder = [1, 2, 4, 3, 5, 7, 8, 6]
 
    root = constructTree(inorder, preorder)
 
    print("The inorder traversal is ", end='')
    inorderTraversal(root)
 
    preorderTraversal(root)

我有这个构造二叉树的代码,但它无法在终端中显示二叉树。很难做到!这里有没有人可以添加一个可以在终端中显示二叉树的方法?

对于上面的例子,它可能看起来像

Binary Tree

【问题讨论】:

  • 有一个名为binarytree 的库,它将生成随机树,或者您可以提供自己的。它还将在终端中直观地生成它,pypi.org/project/binarytree
  • 是的,这很难。您可能要考虑以非递归方式执行此操作。您可以创建一个堆栈。对于每个节点,您将其左右子节点添加到堆栈中。然后在某个时候,堆栈的所有元素都属于同一个“级别”(高度)。您弹出并打印所有这些,直到堆栈为空(然后您知道已经打印了一个级别)。你可以先让它简单地在一个新行上打印每个级别,没有任何花哨的斜线。斜线和空格/缩进是更难的部分
  • 看看这个geeksforgeeks.org/print-level-order-traversal-line-line。除非你真的需要斜线,否则就这样吧
  • 这感觉像是一项家庭作业,查看此链接以获取有关二叉树的更多信息medium.com/@ajinkyajawale/…

标签: python binary-tree inorder preorder


【解决方案1】:

用于解决您的任务的实施算法。例如,在与您的图片相同的数据上测试输出,尝试更大数量的数字以查看更漂亮的图片。

在我的算法中,每个子树的宽度和高度以及边的长度都是自适应的。

那些懂俄语的人可以阅读我的other post关于相同主题,控制台中的二叉树构造。另一篇文章在 C++ 中实现了几种可视化算法。如果你至少不会俄语,你可以从那里复制 C++ 代码。

Try it online!

class Node:
    def __init__(self, data, left=None, right=None):
        self.data = data
        self.left = left
        self.right = right
        
def print_tree(node):
    def inner(node):
        if node is None:
            return []
        sdat = str(node.data)
        l, r = inner(node.left), inner(node.right)
        cl, cr = len((l or ('',))[0]), len((r or ('',))[0])
        s = max(cl, cr)
        sll, slr = (s - cl + 1) // 2, (s - cl) // 2
        srl, srr = (s - cr) // 2, (s - cr + 1) // 2
        v = [' ' * s + sdat + ' ' * s]
        v.extend([' ' * (s - i - 1) + '/' + ' ' * i + ' ' * len(sdat) +
            ' ' * i + '\\' + ' ' * (s - i - 1) for i in range(s // 2)])
        v.extend([(' ' * sll + l[i] + ' ' * slr if i < len(l) else ' ' * s) +
            ' ' * len(sdat) + (' ' * srl + r[i] + ' ' * srr if i < len(r) else ' ' * s)
            for i in range(max(len(l), len(r)))])
        return v
    print('\n'.join(inner(node)))
        
if __name__ == '__main__':
    root = Node(1, Node(2, Node(4)), Node(3, Node(5, Node(7), Node(8)), Node(6)))
    print_tree(root)

输出:

       1
      / \
     /   \
    /     \
   2       3
  4       / \
         5   6
        7 8

上面的第一个算法是使用预购完成的。我正在使用 inorder 提供第二种算法。它有一个不同的更简单的输出:

Try it online!

class Node:
    def __init__(self, data, left=None, right=None):
        self.data = data
        self.left = left
        self.right = right
        
def print_tree(node):
    def inner(node, *, upref = '', cpref = '', dpref = ''):
        if node is None:
            return
        inner(node.right, upref = dpref + '  |',
            cpref = dpref + '  /', dpref = dpref + '   ')
        print(cpref + '--' + str(node.data))
        inner(node.left, upref = upref + '   ',
            cpref = upref + '  \\', dpref = upref + '  |')
    inner(node)
        
if __name__ == '__main__':
    root = Node(1, Node(2, Node(4)), Node(3, Node(5, Node(7), Node(8)), Node(6)))
    print_tree(root)

输出:

     /--6
  /--3
  |  |  /--8
  |  \--5
  |     \--7
--1
  \--2
     \--4

实现预排序的第三个算法,但它比第一个算法简单得多:

Try it online!

class Node:
    def __init__(self, data, left=None, right=None):
        self.data = data
        self.left = left
        self.right = right
        
def print_tree(node):
    def inner(node, *, last = True, pref = ''):
        if node is None:
            return
        print(pref + ('\\-' if last else '|-') + str(node.data))
        inner(node.right, last = False, pref = pref + ('  ' if last else '| '))
        inner(node.left, last = True, pref = pref + ('  ' if last else '| '))
    inner(node)
        
if __name__ == '__main__':
    root = Node(1, Node(2, Node(4)), Node(3, Node(5, Node(7), Node(8)), Node(6)))
    print_tree(root)

输出:

\-1
  |-3
  | |-6
  | \-5
  |   |-8
  |   \-7
  \-2
    \-4

【讨论】:

  • 对于 inorder-postorder 和 preorder-postorder 做同样的工作很难吗?您可以修改问题以使其适用于其他两种情况吗?你喜欢我开始另一个问题吗?
  • @Robert 只能以一种方式输出到控制台。没有其他办法。输出到控制台时没有 preorder/postorder/inorder。只有代码中的处理树可以使用中序/预序。但是控制台输出只是一个辅助功能,它与树内处理数据的方式无关。换句话说,可以为任何事情输出到控制台 - 顺序/预购/后购。
  • stackoverflow.com/questions/67062345/adjust-constructtree 我想这个问题是给你的。我知道我可以使用例如中序遍历和后序遍历来创建这样的树。我认为我们不必修改print_tree(),而是修改constructTree()
  • @Robert 我明白你想要什么。刚刚更新了我的答案,用第二个算法添加了第二部分。第一个算法使用前序,第二个使用中序。请看一下。
  • 这不是我真正想要的。一旦构建了树,您所做的就会打印它。假设它还没有建成。假设我有inorder=[3, 7, 1, 10, 9, 5, 8, 6, 4, 2]postorder = [3, 7, 10, 9, 1, 8, 4, 6, 2, 5]。您将如何使用这些信息打印树。 constructTree() 会这样做,但它不适合 inorder-postorder。所以我需要一个可以同时使用 inorder-postorder 和 preorder-postorder 的函数版本。
猜你喜欢
  • 1970-01-01
  • 2021-03-08
  • 2021-10-10
  • 2023-01-09
  • 2018-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-03
相关资源
最近更新 更多