【问题标题】:Recursive tree traversal递归树遍历
【发布时间】:2018-07-12 16:03:53
【问题描述】:
struct Node {
    char*label;
    struct Node *children;     
};

我正在尝试遍历树并根据当前深度打印节点的值/标签(如上定义)。

输出:

Output

我的代码:

void recurse_helper(struct Node **root, int level, int max_level){
    if (level > max_level){
        return;
    }
    struct Node* r = *root;
    if(r->children == NULL){
    }

    else{
        struct Node *current = r->children;
}
void traverse_and_print(struct Node* root, max_dep){

   recurse_helper(&root, 0,max_dep);

}

我的代码似乎无法正常工作。有没有人有更好的递归解决方案,或者有人可以推荐如何更改我当前的实现?

【问题讨论】:

  • 您需要对树进行广度优先遍历。您可以轻松找到执行此操作的算法(在 SO 上,标签 breadth-first-search 有超过 1000 个问题)——它们通常涉及一个队列,该队列最初填充有根节点,并在遇到子节点时将其推送到该队列上。
  • 起初我也认为是广度优先,但我认为他可能想要预购遍历,将子级缩进到父级下面而不是全部组合在一起。从他给出的例子中肯定不清楚。
  • 在您的示例输出中,如果 firstkid 有一个孩子,您希望它直接打印在 firstkid 下方(但缩进),还是直接打印在 grandkid 上方?
  • @Stephen Docy 那个孩子将被缩进并且位于 firstkid 和 secondkid 之间。所以直接在firstkid下面。
  • @Stephen Docy 树的每一层都像一个链表,这就是兄弟姐妹存在的原因。那么我不是必须以某种方式追踪兄弟姐妹吗?

标签: c recursion struct tree


【解决方案1】:

这似乎可以解决问题。

void printTree(Node *root, int level) {
    if (root == NULL)
        return;

    for (int i = 0; i < level; i++) {
        printf("   ");
    }

    printf("%s\n", root->data);

    for (Node *child = root->children; child != NULL; child = child->next_sib) {
        printTree(child, level + 1);
    }
}

它没有实现 max_level,我将把它留给你做广告。

【讨论】:

  • 这个实现似乎有效。无论如何,函数中是否有一个静态级别计数器,而不是向每个递归调用传递 level + 1?你能告诉我如何使用静态计数器来实现吗?
  • 嗯,我能想到的问题是摆脱关卡传递并使用静态是......你会为同一个关卡多次调用这个例程,一次对于该级别的每个孩子。因此,只有在实际下降一个级别时,您才必须弄清楚如何增加静态变量。我认为将级别作为参数传递是最好的方法。
【解决方案2】:

一个明显的问题似乎是....您正在调用 recurse_helper() 且 max_level = 0 :

recurse_helper(&root, 0,0);

你所说的意思是打印出整个树,但是 recurse_helper() 中的这一行:

if (level > max_level){
    return;
}

将导致递归在第一次迭代后停止。第二次调用 recurse_helper() 将传入 1 表示级别,0 表示 max_level:

recurse_helper(&((r->children)->children), level+1, max_level);

所以你肯定需要专门考虑 max_level = 0。

您没有描述您看到的错误行为,但这看起来确实是个问题。

【讨论】:

  • 还有比我做的更好的递归解决方案吗?
  • 是否清楚遍历是如何工作的?您需要澄清一下吗?
猜你喜欢
  • 2014-03-11
  • 1970-01-01
  • 1970-01-01
  • 2017-05-11
  • 1970-01-01
  • 1970-01-01
  • 2014-12-21
  • 2019-12-01
相关资源
最近更新 更多