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

时间:2012-10-10 09:30:34

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

我想逐级显示树结构。我当前的代码执行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    

另外,我之前发布了一个逻辑问题同样的功能,因为回答了问题,当前的问题解决了另一个问题,我发布了一个新问题,这种方法是否正常,还是我应该对之前的问题进行编辑而不是开一个新的?

5 个答案:

答案 0 :(得分:2)

我所知道的最简单的解决方案是使用哨兵。队列初始化为根节点后跟sentinel,然后循环队列:

  1. 删除前元素
  2. 如果是哨兵:
    • 我们处于某个级别的末尾,因此我们可以结束输出行
    • 如果队列不为空,则将最后一个推送回队列。
  3. 如果不是哨兵:
    • 打印出来
    • 将所有孩子推入队列。
  4. 我不做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。

答案 1 :(得分:1)

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

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

答案 2 :(得分: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 + " ");
    } 
}

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

我上周在微软采访中遇到过这个问题......通过电话对我来说并不是那么顺利。擅长学习它。

答案 3 :(得分:1)

我认为我们还需要三个变量。 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编程并不熟悉。

答案 4 :(得分:0)

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()