【问题标题】:Level Order tree Traversal for a generic tree, displaying the tree level by level级别顺序树遍历通用树,逐级显示树
【发布时间】:2012-10-10 09:30:34
【问题描述】:

我想逐级显示树结构。我当前的代码执行 BFS 或 Level Order Traversal 但我无法获得输出以显示树状结构,如树 查看当前输出和预期输出。

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

我该怎么做。

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

Level Order traversal of a generic tree(n-ary tree) in java

谢谢!

   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    

另外,我之前发布了一个具有相同功能的逻辑问题,因为该问题已得到解答,并且当前问题涉及另一个问题,我发布了一个新问题,这种方法是否可行,或者我应该对之前的问题进行编辑不开一个新的?

【问题讨论】:

    标签: java algorithm tree tree-traversal directed-acyclic-graphs


    【解决方案1】:

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

    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 + " ");
        } 
    }
    

    当你切换关卡时,将下一个关卡换成当前关卡并重置下一个关卡。我更喜欢这种简单性,而不是保留一个完整的单独队列。

    上周我在接受微软采访时遇到了这个问题……电话对我来说不太顺利。很高兴你学习它。

    【讨论】:

      【解决方案2】:

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

      1. 移除前面的元素
      2. 如果是哨兵:
        • 我们已经到了关卡的末尾,所以我们可以结束输出行
        • 如果队列不为空,则在最后将哨兵推回队列。
      3. 如果不是哨兵:
        • 打印出来
        • 将其所有子代推入队列。

      我不使用 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 << ' ';
          }
        }
      }
      

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

      【讨论】:

        【解决方案3】:

        使用另一个队列来指示深度。 下面的代码未经测试,但它应该给你的想法(引入 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);
            }
          }
        }
        

        就我的口味而言,与其他方法相比,这种方法更加不言自明。

        【讨论】:

          【解决方案4】:

          我认为我们还需要三个变量。 numInCurrentLevel 用于跟踪当前关卡中的元素数量,indexInCurrentLevel 用于在当前关卡中遍历时进行计数,numInNextLevel 用于跟踪下一级的元素数量。代码如下:

          static void displayBFS(NaryTreeNode root) {
          
              Queue<NaryTreeNode> q  = new LinkedList<NaryTreeNode>();;
              q.add(root);
              int numInCurrentLevel = 1;
              int numInNextLevel = 0;
              int indexInCurrentLevel=0;
          
              while(!q.isEmpty()) { 
                  NaryTreeNode node = q.poll();
                  System.out.print(node.data + " ");
                  indexInCurrentLevel++;
          
                  for(NaryTreeNode n : node.nary_list) {
                      q.add(n);
                      numInNextLevel++;
                  }
          
                  //finish traversal in current level
                  if(indexInCurrentLevel==numInCurrentLevel) {
                      System.out.println();
                      numInCurrentLevel=numInNextLevel;
                      numInNextLevel=0;           
                      indexInCurrentLevel=0;
                  }
            } 
          }
          

          希望对你有帮助,我对java编程不是很熟悉。

          【讨论】:

            【解决方案5】:
            def printLevelWiseTree(tree):
            q= queue.Queue()
            if tree == None:
                return None
            q.put(tree)
            while (not(q.empty())):
                c = q.get()
                print(c.data,end=":")
                for i in range(len(c.children)):
                    if i != len(c.children)-1:
                        print(c.children[i].data,end=",")
                    else:
                        print(c.children[i].data,end="")
                    q.put(c.children[i])
                print()
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-11-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-08-01
              相关资源
              最近更新 更多