简体   繁体   English

Java广度优先搜索漂亮的印刷品

[英]Java Breadth-first-search nice print

This is my code for breadth-first-search. 这是我的广度优先搜索代码。 I'd like to print level by level. 我想逐级打印。 One line, one level. 一线,一级。

public static void printTreeBreadthFirst(Tree t)
{
    Node root = t.getRoot();
    Queue<Node> queue = new LinkedList<Node>() ;
        if (root == null)
            return;
        queue.clear();
        queue.add(root);
        while(!queue.isEmpty()){
            Node<?> node = queue.remove();
            System.out.println(node.getData() + " ");
            if(node.getChildren().isEmpty())
                continue;
            else
                queue.addAll(node.getChildren());
        }
}

But, this is not a nice print since it prints everything on the same line. 但是,由于它在同一行上打印所有内容,因此打印效果不佳。 How can I implement this nice print? 如何实现这种精美的打印效果?

EDIT: example of a nice print INPUT: (root (child1 (child 1.1, child 1.2) (child 2 (child 2.1)) (child3)) NICE output: 编辑:好的打印输入示例:(root(child1(child1.1,child 1.2)(child 2(child 2.1))(child3))NICE输出:

root                           (level 1)
child1 - child2 - child3       (level 2)
child1.1 - child1.2 - child2.1 (level 3)

To get the desired "nice print", you are missing the level when you pull a node out of the queue. 为了获得所需的“漂亮的打印效果”,当您从队列中拉出节点时,您将丢失该level Therefore you must create a new structure which you'll insert into the Queue, eg 因此,您必须创建一个要插入队列的新结构,例如

class NodeLevel {
    private Node node;
    private int level;
    // ... constructor, getters, ...
}

And each time you add new elements to the queue, you use current level + 1 . 每次将新元素添加到队列中时,都使用current level + 1

So, first insert root with level 1: 因此,首先插入根与级别1:

queue.add(new NodeList(root, 1));

When you remove element from queue, save the level: 从队列中删除元素时,请保存级别:

NodeList nodeList = queue.remove();
Node<?> node = nodeList.getNode();
int level = nodeList.getLevel();
// pretty print using the node & level

And add new children with level + 1 : 并添加level + 1新子level + 1

node.getChildren().forEach(child -> queue.add(new NodeList(child, level + 1))); 

Or you can simply increase the level when you retrieve it from NodeList , so you don't do the addition in every iteration: 或者,您可以在从NodeList检索level时简单地增加level ,因此不必在每次迭代中都进行添加:

int childLevel = nodeList.getLevel() + 1;
//pretty print

The complicated part is to know when a given level ends. 复杂的部分是知道给定级别的结束时间。 Nodes do not (typically) know their level, but can find it out by counting how many ancestors they have: 节点(通常)不知道其级别,但是可以通过计算它们拥有多少祖先来找到它:

public static void getLevel(Node n) {
   return n == null ? 0 : 1 + getLevel(n.getParentNode());
}

Another, more efficient way to calculate these levels is to store it in the nodes themselves, and store these extended nodes in the Queue : 计算这些级别的另一种更有效的方法是将其存储在节点本身中,并将这些扩展的节点存储在Queue

public class NodeWithLevel {
   private Node node;
   private int level;
   ...
}

Now you just have to change your printing code to check the level. 现在,您只需要更改打印代码即可检查级别。 If the level is increased, then you should skip a line: 如果级别增加,则应跳过一行:

int currentLevel = 0; // level of root
while (...) {
   ...
   System.out.print(node.getData() + " - ");
   if (getLevel(node) > currentLevel) {
       currentLevel ++;
       System.out.println(" (level " + currentLevel + ")");
   }
   if(node.getChildren().isEmpty())
   ...
}

This is not exactly what you asked for, but it is close. 这与您要求的不完全相同,但是很接近。 To remove the last " - " and align the levels, you would need to store the whole lines before you print them, and check the length of the longest line before generating any output. 要删除最后一个" - "并对齐级别,您需要在打印整行之前存储它们,并在生成任何输出之前检查最长行的长度。

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

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