如何以水平方式打印二叉树?如何实现指定格式的二叉树打印?
如何修改二叉树打印函数以实现指定的水平分层格式
嘿,我来帮你搞定这个二叉树格式化打印的问题!你的现有函数本质是前序遍历的实现,但它的换行逻辑只在访问左子树前触发,完全没考虑树的层级结构,所以输出是一串线性的节点序列,根本体现不出树的形状。要实现你想要的那种分层水平格式,我们需要解决三个核心问题:按层级顺序打印节点、控制每一层的缩进对齐、打印父子节点间的连接符号(/ 和 \)。
现有函数的问题拆解
原函数的递归逻辑是先打印当前节点,再递归左子树(前加换行),最后递归右子树。这种逻辑只会输出: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; }
代码逻辑说明
getDepth函数:计算树的最大深度,这样我们可以根据层级动态计算需要的缩进量,保证树的结构对齐。printSpaces函数:辅助打印指定数量的空格,是实现对齐的关键。- BFS核心逻辑:
- 用队列存储每一层的节点,逐层处理
- 先打印当前层的节点(带前置和节点间空格)
- 再打印当前层与下一层之间的
/和\连接符,空节点用空格占位避免结构错位
输出效果
运行这段代码后,你会得到完全符合要求的输出:
5 / \ 2 9 / \ / \ 0 3 7 12
内容的提问来源于stack exchange,提问作者Hardik Poudel
相关产品推荐
相关产品推荐

