我试图实现类似于BFS的树遍历算法,但只做了一些小修改。每当我们跳到下一行时,我们应该从最近的子节点(行中最后一个节点的子节点)开始,而不是从下一行的最远节点开始。如何修改BFS代码来实现这一目标?
这是原始的BFS代码:
public void bfs()
{
// BFS uses Queue data structure
Queue q = new LinkedList();
q.add(rootNode);
visited[rootNode] = true;
printNode(rootNode);
while( !q.isEmpty() )
{
int n, child;
n = (q.peek()).intValue();
child = getUnvisitedChildNode(n); // Returns -1 if no unvisited niode left
if ( child != -1 )
{ // Found an unvisted node
visited[child] = true; // Mark as visited
printNode(child);
q.add(child); // Add to queue
}
else
{
q.remove(); // Process next node
}
}
}
这就是我想要的修改后的BFS应该如何工作:
答案 0 :(得分:1)
有2个堆叠 - 一个用于当前级别,一个用于下一级别。
从当前级别查看/弹出并进入下一级别。如果当前级别为空,则交换两个堆栈(因此下一级别将成为当前级别,反之亦然)。
它看起来像这样:
(例如您的代码,但q
替换为current
和next
,并交换了两个代码
Stack current, next;
// ...
current.push(rootNode);
while (!current.isEmpty() || !next.isEmpty())
{
if (current.isEmpty())
{
current = next;
next.clear();
}
int n = current.peek();
// ...
next.add(child);
// ...
current.pop();
}
getUnvisitedChildNode
也需要更改(因为它当前可能会强制在单个节点上从左到右的方向)。一种选择是向下传递一个方向,以决定是从左侧还是右侧返回下一个孩子(在交换next
和current
时您反转)。
可以在不更改getUnvisitedChildNode
的情况下执行此操作,但需要一些“丑陋”的代码 - 基本的想法是在循环中调用getUnvisitedChildNode
,直到您拥有某个给定节点的所有子节点,将所有这些孩子扔进一个阵列(不进行处理,即打印它们),然后使用类似的方向变量选择处理它们的方向。
如果你已经可以访问子数组,你可以直接从左边或右边循环。