简体   繁体   English

Level Order tree 遍历通用树,逐级显示树

[英]Level Order tree Traversal for a generic tree, displaying the tree level by level

I would like to display the tree structure level by level.我想逐级显示树结构。 My current code does a BFS or Level Order Traversal but I cannot get the output to display the tree structure like a tree See current output and Expected output.我当前的代码执行了 BFS 或 Level Order Traversal,但我无法获得像树一样显示树结构的输出 查看当前输出和预期输出。

My idea was to use some kind of count to iterate over elements from the same level in the queue.我的想法是使用某种计数来迭代队列中同一级别的元素。

How can I do so.我怎么能这样做。

Original Code without this function can be found in the link below in case someone needs the entire implementation else just look at the displayBFS function below.如果有人需要整个实现,可以在下面的链接中找到没有此功能的原始代码,否则只需查看下面的 displayBFS 功能。

Level Order traversal of a generic tree(n-ary tree) in java java中通用树(n元树)的层序遍历

Thanks!谢谢!

   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    

Also, I had posted a logic issue with the same function earlier, as that was answered and the current question realtes to a different problem, I posted a new question, is this approach okay or should I make edits to the earlier question and not open a new one?另外,我之前发布了一个具有相同功能的逻辑问题,因为已经回答了并且当前问题涉及另一个问题,我发布了一个新问题,这种方法可以吗,或者我应该对之前的问题进行编辑而不是打开一个新的?

only need to keep track of current level and next level.只需要跟踪当前级别和下一级别。

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

when you switch levels, swap nextlevel for currentlevel and reset nextlevel.当您切换级别时,将 nextlevel 交换为 currentlevel 并重置 nextlevel。 i prefer the simplicity of this over keeping a whole separate queue.我更喜欢这个简单而不是保持一个完整的单独队列。

i had this question for a microsoft interview last week... it didn't go so well for me over the phone.上周我在微软面试时遇到了这个问题……电话中的问题对我来说不太好。 good on you for studying it.很高兴你学习它。

The simplest solution I know of to this problem is to use a sentinel.我所知道的最简单的解决方案是使用哨兵。 The queue is initialized with the root node followed by the sentinel, and then you loop through the queue:队列初始化为根节点,后跟哨兵,然后循环遍历队列:

  1. remove the front element删除前面的元素
  2. if it is the sentinel:如果是哨兵:
    • we're at the end of a level, so we can end the output line我们在一个关卡的末尾,所以我们可以结束输出线
    • if the queue is not empty, push the sentinel back onto the queue at the end.如果队列不为空,最后将哨兵推回队列。
  3. if it is not the sentinel:如果不是哨兵:
    • print it out打印出来
    • push all its children onto the queue.将其所有孩子推入队列。

I don't do Java, but I have some C++ code for depth-aware BFS, which I stripped down to do this printing task:我不使用 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 << ' ';
    }
  }
}

Note that I prefer to use a two-pointer solution (first_child/next_sibling), because it usually works out to be simpler than embedded lists.请注意,我更喜欢使用双指针解决方案(first_child/next_sibling),因为它通常比嵌入式列表更简单。 YMMV.天啊。

Use another queue to indicate depth.使用另一个队列来指示深度。 The below code is not tested, but it should give you the idea (the sep variable is introduced to avoid trailing white-spaces):下面的代码没有经过测试,但它应该给你一个想法(引入 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);
    }
  }
}

For my taste this approach is more self-explanatory compared to other ways one could do it.在我看来,与其他方法相比,这种方法更容易解释。

I think we need three more variables.我认为我们还需要三个变量。 numInCurrentLevel for keeping track of the number of elements in current level, indexInCurrentLevel for doing the count when traversal in current level and numInNextLevel for keeping track of the number of elements in next level. numInCurrentLevel用于跟踪当前级别的元素数量, indexInCurrentLevel用于在当前级别遍历时进行计数, numInNextLevel用于跟踪下一级别的元素数量。 The code is below:代码如下:

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;
        }
  } 
}

Hope it helps, I am not so familiar with java programming.希望它有所帮助,我对java编程不太熟悉。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM