【问题标题】:How to print nested linked list pretty如何漂亮地打印嵌套链表
【发布时间】:2019-05-19 16:02:36
【问题描述】:

有这样的结构:

struct a{
  char name[10];
  struct a* child;
  struct a* friend;
};

并且有许多具有这种结构的对象,它们作为孩子和朋友联系在一起

所以如果我知道第一个地址,我就可以访问所有这些

第一个对象是这样的:

struct a start;

我将在这些对象生成后立即设置它们中的所有值

所以如果他们没有孩子或朋友,他们的孩子和朋友的成员变量将为零

我想像这样打印所有这些对象:

a
└ aa
  └ aaa
  │  └ aaaa
  ab
  ac
  └ aca
    acb
    acc

我真的很抱歉这幅糟糕的图画

所以astartaa 的名称 是孩子的名字startabacaa 的朋友。像这样。

我知道如何打印那些特殊字符

问题是对象是在运行时确定的

所以我需要一个算法来打印这样 像这样:

void print(struct a* b)
{
    if(b)
    {
        printf(”%s\n”, b->name);
        print(b->child);
        print(b->friend);
    }
}

但这远不是我想要的

我真的不知道该怎么做

有可能吗? 如果不是,我想获得一些关于如何漂亮地打印这种结构的帮助

【问题讨论】:

  • 那么……您打印孩子的方式与打印朋友的方式有什么不同吗?
  • @Mikhail 孩子们走到他们父母正下方的右侧,朋友们打印完他们所有的孩子后和他们的朋友们一起去同一个位置
  • 这看起来有点像家庭作业转储,而且它的范围很广。你应该向你的老师寻求澄清和建议。
  • 同意@Broman。此外,如果您使用比“a”、“ab”等更有意义的名称,您可能会增加获得答案的机会。
  • 您将需要一个递归打印函数,它知道或被告知要缩进自己的输出多少。

标签: c algorithm printf


【解决方案1】:

通常,这种类型的树打印非常简单:添加一个 depth 字段并打印空格以使子级缩进以匹配其嵌套级别。

添加 字符也可以使用布尔标志来告诉节点它是否是子节点,如果是,则在打印自身之前添加一个角度字符。

但是,添加子栏| 会带来一些麻烦。现在,我们需要为每个父节点保留状态以确定它是否有尚未打印的子节点。为此,我们可以创建一个标志数组,并根据特定深度的子项的存在来打开或关闭它们。它应该是一个可扩展的数组,因为我们无法确定结构的深度。

下面是一些示例代码:

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

typedef struct node {
    char name[10];
    struct node* child;
    struct node* friend;
} node;

void print(node *root, int depth, bool *notch_locs, 
          size_t notch_locs_capacity, bool friend) {
    if (root) {
        for (int i = 0; i < depth * 2; i++) {
            if (friend && depth * 2 - 2 == i) {
                printf("└");
            }
            else if (i % 2 == 0 && notch_locs[i/2]) {
                printf("│");
            }
            else {
                printf(" ");
            }
        }

        if (depth >= notch_locs_capacity) {
            notch_locs_capacity *= 2;
            size_t size = sizeof(bool) * notch_locs_capacity;
            notch_locs = realloc(notch_locs, size);
        }

        notch_locs[depth] = root->child ? true : false;  
        printf("%s\n", root->name);
        print(root->friend, depth + 1, 
              notch_locs, notch_locs_capacity, true);
        print(root->child, depth, notch_locs, 
              notch_locs_capacity, false);
    }
}

void pprint(node *root) {
    bool *notch_locs = malloc(sizeof(bool));
    memset(notch_locs, false, sizeof(bool));
    print(root, 0, notch_locs, 1, false);
    free(notch_locs);
}

node *rand_chain() {
    int i = 0;
    node *root = malloc(sizeof(*root));
    memset(root, 0, sizeof(*root));
    sprintf(root->name, "%c", i + 97);
    i = (i + 1) % 25;

    while (rand() % 12) {
        node *curr = root;

        while (rand() % 5) {
            if (rand() % 2) {
                if (!curr->child) {
                    curr->child = malloc(sizeof(*curr));
                    memset(curr->child, 0, sizeof(*curr));   
                    sprintf(curr->child->name, "%c", i + 97);
                    i = (i + 1) % 25;
                }
                
                curr = curr->child;
            }
            else {
                if (!curr->friend) {
                    curr->friend = malloc(sizeof(*curr));
                    memset(curr->friend, 0, sizeof(*curr));
                    sprintf(curr->friend->name, "%c", i + 97);
                    i = (i + 1) % 25;
                }
                
                curr = curr->friend;
            }
        }
    }

    return root;
}

void free_chain(node *root) {
    if (root) {
        free_chain(root->child);
        free_chain(root->friend);
        free(root);
    }
}

int main(void) {
    /*
    a
    └ aa
      └ aaa
      │  └ aaaa
      ab
      ac
      └ aca
        acb
        acc
    */
    node acc = {"acc", NULL, NULL};
    node acb = {"acb", &acc, NULL};
    node aca = {"aca", &acb, NULL};
    node aaaa = {"aaaa", NULL, NULL};
    node aaa = {"aaa", NULL, &aaaa};
    node ac = {"ac", NULL, &aca};
    node ab = {"ab", &ac, NULL};
    node aa = {"aa", &ab, &aaa};
    node a = {"a", NULL, &aa};
    pprint(&a);

    node *root = rand_chain();
    pprint(root);
    free_chain(root);
    return 0;
}

输出:

a
└ aa
  └ aaa
  │ └ aaaa
  ab
  ac
  └ aca
    acb
    acc
a
└ k
│ └ t
│ │ u
│ │ └ v
│ │   └ w
│ l
│ └ p
│ │ q
│ │ r
│ │ └ s
│ │   └ t
│ │     u
│ │     └ v
│ │       └ w
│ │         x
│ m
│ └ f
│ │ └ g
│ │   └ n
│ │     └ o
│ n
│ o
│ p
│ └ q
│   └ r
│     s
b
└ c
│ └ d
│ │ e
│ │ └ f
│ │ │ └ g
│ │ │   h
│ │ │   i
│ │ │   └ j
│ │ c
│ │ d
│ h
│ └ i
│   └ j
│     k
│     l
│     └ m
x
└ e
y
└ z
  b

【讨论】:

    猜你喜欢
    • 2011-03-14
    • 2014-05-18
    • 2015-09-16
    • 1970-01-01
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    • 2016-03-08
    • 2012-05-04
    相关资源
    最近更新 更多