You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python如何垂直打印真实树形结构,替代现有缩进式树状输出效果

实现思路

你现在的缩进式打印是深度优先遍历逐行输出,要实现带/ \分支的垂直树形结构,需要切换为广度优先逐层打印的逻辑,核心步骤如下:

  • 先计算整棵树的最大深度,确定总共有多少层要打印
  • 给每个节点分配水平坐标:底层节点从左到右等距排列,父节点坐标位于其所有子节点坐标的中点,保证分支线对齐
  • 每层先打印该层所有节点(按计算好的x坐标补空格对齐),再打印下一层的分支连接线(/ \ |)
  • 所有层级打印完成后即可得到你要的树状效果

适配你的类的完整实现代码

class treeNode:
    def __init__(self,data):
        self.data = data
        self.children = []
        self.parent = None
        self.nextSibling = None
        self.level = 0
        self.prevSibling = None
        self.x = 0 # 新增:存储节点的水平打印坐标

    def add_children(self,*child):
        for i in child:
            i.parent = self
            self.children.append(i)
            if len(self.children) > 1:
                self.children[-2].nextSibling = i

class Tree:
    def __init__(self,root:treeNode):
        self.root = root
        self.depth = 0
        self.node_width = 2 # 单个节点占的字符宽度,可根据你的数据调整
        self.gap = 2 # 底层节点之间的间隔宽度

    # 辅助方法:计算树的最大深度
    def get_max_depth(self, node):
        if not node.children:
            return 1
        max_child_depth = 0
        for child in node.children:
            child_depth = self.get_max_depth(child)
            if child_depth > max_child_depth:
                max_child_depth = child_depth
        return max_child_depth + 1

    # 辅助方法:给所有节点分配水平坐标
    def assign_x_coords(self, node, depth, left_bound):
        if not node.children:
            node.x = left_bound
            return left_bound + self.node_width + self.gap
        # 先分配子节点的坐标
        child_right_bound = left_bound
        for child in node.children:
            child_right_bound = self.assign_x_coords(child, depth+1, child_right_bound)
        # 父节点坐标在第一个和最后一个子节点的中间
        node.x = (node.children[0].x + node.children[-1].x) // 2
        return child_right_bound

    # 重写打印方法
    def print_tree(self):
        self.depth = self.get_max_depth(self.root)
        self.assign_x_coords(self.root, 0, 0)
        # 按层遍历节点
        current_level = [self.root]
        for level in range(self.depth):
            # 第一步:打印当前层的节点
            line = [' '] * 200 # 初始化足够长的空行,可根据树的大小调整
            for node in current_level:
                data_str = str(node.data)
                for i, c in enumerate(data_str):
                    if node.x + i < len(line):
                        line[node.x + i] = c
            print(''.join(line).rstrip())
            # 最后一层不需要打印分支线
            if level == self.depth -1:
                break
            # 第二步:打印当前层到下一层的分支线
            line = [' '] * 200
            next_level = []
            for node in current_level:
                next_level.extend(node.children)
                if len(node.children) == 1:
                    # 只有一个子节点,画竖线
                    line[node.children[0].x] = '|'
                elif len(node.children) >=2:
                    # 多个子节点,画左右斜线
                    left_x = node.children[0].x
                    right_x = node.children[-1].x
                    line[left_x] = '/'
                    line[right_x] = '\\'
            print(''.join(line).rstrip())
            current_level = next_level

测试代码

# 构造你示例里的树
root = treeNode(1)
n2 = treeNode(2)
n22 = treeNode(22)
root.add_children(n2, n22)
n3 = treeNode(3)
n4 = treeNode(4)
n2.add_children(n3, n4)
n33 = treeNode(33)
n3.add_children(n33)

tree = Tree(root)
tree.print_tree()

输出效果

1
     / \
    2  22
   / \
  3   4
  |
  33

扩展说明

如果需要支持多叉树(每个节点超过2个子节点),只需要修改分支线打印的逻辑,在子节点之间补充横线或者对应连接符号即可。如果节点数据长度不固定,可以动态计算每个节点的宽度调整坐标分配逻辑。

内容的提问来源于stack exchange,提问作者Zakaria Ayadi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 15:39:04