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

如何用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);
}

关键修改说明

  1. 动态前缀控制:新增prefix参数,传递当前节点的前缀符号,决定后续子节点是否显示竖线。
  2. 前缀生成逻辑:
    • 左子节点:如果当前节点是父节点的右子节点,后续层级用三个空格填充(无竖线);如果是左子节点,保留竖线| 。
    • 右子节点:无论当前节点是左还是右,后续层级都用三个空格填充(右节点之后没有同级节点,无需竖线)。
  3. 内存管理:动态分配前缀字符串,递归结束后释放,避免内存泄漏。

运行修正后的代码即可得到期望的树形打印格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 02:45:44