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

如何以水平方式打印二叉树?如何实现指定格式的二叉树打印?

如何修改二叉树打印函数以实现指定的水平分层格式

嘿,我来帮你搞定这个二叉树格式化打印的问题!你的现有函数本质是前序遍历的实现,但它的换行逻辑只在访问左子树前触发,完全没考虑树的层级结构,所以输出是一串线性的节点序列,根本体现不出树的形状。要实现你想要的那种分层水平格式,我们需要解决三个核心问题:按层级顺序打印节点、控制每一层的缩进对齐、打印父子节点间的连接符号(/ 和 \)。

现有函数的问题拆解

原函数的递归逻辑是先打印当前节点,再递归左子树(前加换行),最后递归右子树。这种逻辑只会输出:5 2 0 3 9 7 12,完全没有层级区分。要实现目标格式,我们需要切换到**按层遍历(广度优先搜索,BFS)**的思路,因为这种方式天然适合处理分层结构。

修改后的实现方案(BFS版)

下面是用C++实现的完整代码,它会严格按照你想要的格式打印二叉树:

#include <iostream>
#include <queue>
#include <vector>
#include <cmath>

using namespace std;

struct node {
    int data;
    node* left;
    node* right;
    node(int val) : data(val), left(nullptr), right(nullptr) {}
};

// 辅助函数:计算树的最大深度,用于确定缩进量
int getDepth(node* root) {
    if (!root) return 0;
    return 1 + max(getDepth(root->left), getDepth(root->right));
}

// 打印指定数量的空格,保证树结构对齐
void printSpaces(int count) {
    for (int i = 0; i < count; ++i) {
        cout << " ";
    }
}

void display(node* root) {
    if (!root) return;

    int treeDepth = getDepth(root);
    queue<node*> nodeQueue;
    nodeQueue.push(root);

    // 逐层处理每一层的节点和连接符
    for (int currentLevel = 0; currentLevel < treeDepth; ++currentLevel) {
        int nodesInLevel = nodeQueue.size();
        // 计算当前层的前置空格和节点间的空格数
        int leadingSpaces = pow(2, treeDepth - currentLevel - 1) - 1;
        int betweenNodeSpaces = pow(2, treeDepth - currentLevel) - 1;

        // 打印当前层的节点
        printSpaces(leadingSpaces);
        for (int i = 0; i < nodesInLevel; ++i) {
            node* currNode = nodeQueue.front();
            nodeQueue.pop();

            if (currNode) {
                cout << currNode->data;
                // 把左右子节点加入队列,供下一层处理
                nodeQueue.push(currNode->left);
                nodeQueue.push(currNode->right);
            } else {
                cout << " "; // 空节点占位,避免结构错位
                nodeQueue.push(nullptr);
                nodeQueue.push(nullptr);
            }

            // 节点间的空格(最后一个节点不需要)
            if (i != nodesInLevel - 1) {
                printSpaces(betweenNodeSpaces);
            }
        }
        cout << endl;

        // 打印当前层与下一层之间的连接符(最后一层不需要)
        if (currentLevel == treeDepth - 1) break;
        printSpaces(leadingSpaces - 1);
        for (int i = 0; i < nodesInLevel; ++i) {
            // 取出当前节点的左右子节点(用来判断是否打印/或\)
            node* leftChild = nodeQueue.front();
            nodeQueue.pop();
            node* rightChild = nodeQueue.front();
            nodeQueue.pop();

            // 把左右子节点塞回队列,下一轮要处理它们
            nodeQueue.push(leftChild);
            nodeQueue.push(rightChild);

            // 打印左连接符
            cout << (leftChild ? "/" : " ");
            printSpaces(betweenNodeSpaces - 1);
            // 打印右连接符
            cout << (rightChild ? "\\" : " ");

            // 连接符之间的空格(最后一组不需要)
            if (i != nodesInLevel - 1) {
                printSpaces(betweenNodeSpaces - 1);
            }
        }
        cout << endl;
    }
}

// 测试代码
int main() {
    // 构建你指定的二叉树
    node* root = new node(5);
    root->left = new node(2);
    root->right = new node(9);
    root->left->left = new node(0);
    root->left->right = new node(3);
    root->right->left = new node(7);
    root->right->right = new node(12);

    display(root);
    return 0;
}

代码逻辑说明

  1. getDepth函数:计算树的最大深度,这样我们可以根据层级动态计算需要的缩进量,保证树的结构对齐。
  2. printSpaces函数:辅助打印指定数量的空格,是实现对齐的关键。
  3. BFS核心逻辑:
    • 用队列存储每一层的节点,逐层处理
    • 先打印当前层的节点(带前置和节点间空格)
    • 再打印当前层与下一层之间的/和\连接符,空节点用空格占位避免结构错位

输出效果

运行这段代码后,你会得到完全符合要求的输出:

5
   / \
  2   9
 / \ / \
0  3 7 12

内容的提问来源于stack exchange,提问作者Hardik Poudel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 20:02:29