如何用C语言实现类tree命令的二叉树树形打印?
二叉树打印格式修正问题
期望输出格式
50 ├─25 | ├─10 | | ├─5 | | └─15 | └─40 | ├─35 | └─45 └─75 ├─60 | ├─55 | └─65 └─90 ├─85 └─95
当前错误输出
50 ├─25 | ├─10 | | ├─5 | | └─15 | └─40 | | ├─35 | | └─45 └─75 | ├─60 | | ├─55 | | └─65 | └─90 | | ├─85 | | └─95
问题核心是:原代码仅通过indent和is_right参数无法区分哪些层级需要保留竖线标记,导致右子树的所有层级错误继承了祖先节点的竖线前缀。需要传递动态前缀来精准控制每一层的符号输出。
修正后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> struct Node { int data; struct Node* left; struct Node* right; }; struct Node* get_node(int value) { struct Node* new_node = (struct Node*) malloc(sizeof (struct Node)); new_node->data = value; new_node->left = NULL; new_node->right = NULL; return new_node; } void insert(struct Node **ptr, int value) { struct Node* root = *ptr; if(root == NULL) { *ptr = get_node(value); } else if(value <= root->data){ insert(&root->left, value); } else { insert(&root->right, value); } } // 新增prefix参数,控制每一层的前缀符号 void print_subtree(struct Node* root, char* prefix, int is_right) { if(root == NULL) return; printf("\n%s", prefix); printf(is_right ? "└─%d" : "├─%d", root->data); int prefix_len = strlen(prefix); // 左子节点前缀:当前是右节点则补空格,左节点则补竖线 char* left_prefix = (char*)malloc(prefix_len + 4); strcpy(left_prefix, prefix); strcat(left_prefix, is_right ? " " : "| "); // 右子节点前缀:统一补空格,因为右节点之后没有同级节点 char* right_prefix = (char*)malloc(prefix_len + 4); strcpy(right_prefix, prefix); strcat(right_prefix, " "); print_subtree(root->left, left_prefix, 0); print_subtree(root->right, right_prefix, 1); free(left_prefix); free(right_prefix); } void print(struct Node* root) { if(root != NULL) { printf("%d", root->data); print_subtree(root->left, "", 0); print_subtree(root->right, "", 1); } } int main() { struct Node* root = NULL; insert(&root, 50); insert(&root, 25); insert(&root, 75); insert(&root, 10); insert(&root, 40); insert(&root, 60); insert(&root, 90); insert(&root, 5); insert(&root, 15); insert(&root, 35); insert(&root, 45); insert(&root, 55); insert(&root, 65); insert(&root, 85); insert(&root, 95); print(root); }
关键修改说明
- 动态前缀控制:新增
prefix参数,传递当前节点的前缀符号,决定后续子节点是否显示竖线。 - 前缀生成逻辑:
- 左子节点:如果当前节点是父节点的右子节点,后续层级用三个空格填充(无竖线);如果是左子节点,保留竖线
|。 - 右子节点:无论当前节点是左还是右,后续层级都用三个空格填充(右节点之后没有同级节点,无需竖线)。
- 左子节点:如果当前节点是父节点的右子节点,后续层级用三个空格填充(无竖线);如果是左子节点,保留竖线
- 内存管理:动态分配前缀字符串,递归结束后释放,避免内存泄漏。
运行修正后的代码即可得到期望的树形打印格式。
内容的提问来源于stack exchange,提问作者Voimmamored
相关产品推荐
相关产品推荐

