我想逐级显示树结构。我当前的代码执行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
另外,我之前发布了一个逻辑问题同样的功能,因为回答了问题,当前的问题解决了另一个问题,我发布了一个新问题,这种方法是否正常,还是我应该对之前的问题进行编辑而不是开一个新的?
答案 0 :(得分:2)
我所知道的最简单的解决方案是使用哨兵。队列初始化为根节点后跟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 << ' ';
}
}
}
请注意,我更喜欢使用双指针解决方案(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()