当前位置: 首页 > 知识库问答 >
问题:

通用树的级别顺序树遍历,逐级显示树

巢嘉志
2023-03-14

我想逐级显示树结构。我当前的代码执行BFS或级别顺序遍历,但我无法使输出像树一样显示树结构。请参阅当前输出和预期输出。

我的想法是使用某种计数来迭代队列中同一级别的元素。

我怎么能这样做呢。

没有此功能的原始代码可以在下面的链接中找到,以防有人需要整个实现,否则只需查看下面的显示BFS功能。

java中泛型树(n元树)的级顺序遍历

谢谢

   void displayBFS(NaryTreeNode n)
   {
      Queue<NaryTreeNode> q  = new LinkedList<NaryTreeNode>();
      System.out.println(n.data);

       while(n!=null)
     {   
         for(NaryTreeNode x:n.nary_list)
         {
             q.add(x);
             System.out.print(x.data + " ");
         }
         n=q.poll();
         System.out.println();
      } 
  }

Current Tree Structure for reference:

         root(100)
        /      |       \
      90       50       70
      /        \
    20 30   200  300


    Current Output:
        100
        90 50 70
        20 30
        200 300

    Expected Output
        100
        90 50 70
        20 30 200 300    

另外,我之前发布了一个具有相同功能的逻辑问题,因为已经回答了这个问题,并且当前的问题与另一个问题相关,我发布了一个新问题,这种方法可以吗,或者我应该编辑前面的问题,而不是打开一个新问题?

共有3个答案

张财
2023-03-14

使用另一个队列指示深度。下面的代码未经测试,但它应该能让您了解这一点(引入sep变量是为了避免尾随空格):

void displayBFS(NaryTreeNode n) {
  Queue<NaryTreeNode> q  = new LinkedList<NaryTreeNode>();
  Queue<Integer> depth  = new LinkedList<Integer>();
  q.add(n);
  depth.add(0);

  String sep = "";
  int oldDepth = 0

  while(!q.isEmpty()) {
    NaryTreeNode currN = q.poll();
    int currDepth = depth.poll();
    if (currDepth > oldDepth) {
      System.out.println();
      oldDepth = currDepth;
      sep = "";
    }
    System.out.print(sep + currN.data);
    sep = " ";

    for(NaryTreeNode x : currN.nary_list) {
      q.add(x);
      depth.add(currDepth + 1);
    }
  }
}

在我看来,与其他方法相比,这种方法更不言自明。

洪高阳
2023-03-14

我所知道的解决这个问题的最简单方法是使用哨兵。使用根节点和sentinel初始化队列,然后在队列中循环:

  • 删除前元素
  • 如果是哨兵:
    • 我们在一个关卡的末尾,所以我们可以结束输出行
    • 如果队列不是空的,将哨兵推回到队列的最后。
    • 打印出来

    我不使用Java,但我有一些用于深度感知BFS的C代码,我将其剥离以执行此打印任务:

    void show_tree_by_levels(std::ostream& os, Node* tree) {
      Node* sentinel = new Node;
      std::deque<Node*> queue{tree, sentinel};
      while (true) {
        Node* here = queue.front();
        queue.pop_front();
        if (here == sentinel) {
          os << std::endl;
          if (queue.empty())
            break;
          else
            queue.push_back(sentinel);
        } else {
          for (Node* child = here->child; child; child = child->sibling)
            queue.push_back(child);
          os << here->value << ' ';
        }
      }
    }
    

    请注意,我更喜欢使用双指针解决方案(第一个子/下一个子),因为它通常比嵌入列表更简单。YMMV。

顾俊誉
2023-03-14

只需要跟踪当前级别和下一级别。

static void displayBFS(NaryTreeNode root) {
    int curlevel = 1;
    int nextlevel = 0;

    LinkedList<NaryTreeNode> queue = new LinkedList<NaryTreeNode>();
    queue.add(root);

    while(!queue.isEmpty()) { 
        NaryTreeNode node = queue.remove(0);

        if (curlevel == 0) {
            System.out.println();
            curlevel = nextlevel;
            nextlevel = 0;
        }

        for(NaryTreeNode n : node.nary_list) {
            queue.addLast(n);
            nextlevel++;
        }

        curlevel--;
        System.out.print(node.data + " ");
    } 
}

切换级别时,将nextlevel替换为currentlevel并重置nextlevel。我更喜欢这样简单,而不是保持一个完整的单独队列。

上周我在接受微软的采访时问了这个问题。。。我在电话里感觉不太好。谢谢你学习它。

 类似资料:
  • (为了避免冗长的解释,我所要寻找的只是java中泛型树(n元树)的级别顺序遍历。提供的代码正常工作,需要级别顺序显示功能。环顾四周一个小时,但找不到通用n元树的参考。如果soemone能帮助我在代码上构建LevelOrderDisplay函数,我将不胜感激,因为它将帮助我理解我遇到的队列错误。谢谢 我一直在尝试在工作中实现Autosys作业计划的树表示。由于每个作业(流程)可以有一个或多个依赖作业

  • 我知道树的水平顺序遍历的算法。(我想大家都知道)该算法使用队列存储树的节点。有没有不使用额外内存的算法?该算法不能使用递归(这样我们就可以使用堆栈)。注意,该树以左子右同级表示形式给出。不允许使用其他指针 对于树,C中的结构是: 树用指向根节点的指针表示。当然,root不能有正确的兄弟。

  • 我正在尝试对二叉树进行级别顺序遍历。但诀窍是代替正常的级别顺序遍历,我想做另一种选择。对于例如。 普通等级顺序遍历 : 我要找的是我们打印根。现在,对于每一个偶数级,我都想逆时针旋转,对于每奇数级,都会顺时针旋转: 对于这种遍历,输出应该是: 这是我到目前为止尝试的,但这产生的输出与我试图实现的输出略有不同: 该程序产生以下输出: < code>1 3 2 5 4 7 6 10 11 9 8 我需

  • 这是一个leetcode问题。 给定一个二叉树,返回其节点值的级序遍历(即从左到右,逐级)。 例如:给定二叉树, 将其级别顺序遍历返回为: 但我正在用JavaScript尝试一种新的方式,而不是完全按照他们的解决方案。到目前为止,我能够打印阵列,但 如何在新行中打印不同的级别 以下是我目前的代码: 输入:[3,9,20,空,空,15,7], LeetCode问题链接:BinarytreeTrave

  • 我正在尝试编写一个函数,该函数将使用级别顺序遍历将一个元素插入到二叉树中。我的代码遇到的问题是,当我在树中插入一个新节点后打印级别顺序遍历时,它以无限循环的方式打印元素。1,2,3,4,5,6,7,8这个数字一直在飞驰过终点站。我将感谢任何关于如何补救这种情况的指示和建议。 这是我通过修改级别顺序遍历技术将一个元素插入到树中的地方 主

  • 我试图使用队列的链表实现实现二叉搜索树的级别顺序遍历。 我已经检查了二叉查找树的实现,它是好的。队列的链表实现也是正确的。在这里,我试图访问节点并将其子节点排队。然后使用弹出函数实际访问节点。 这最终是通过递归调用完成的。当我运行以下代码时,我以不同的顺序获得输出。