修改了BFS树遍历

时间:2017-06-23 21:03:00

标签: algorithm tree graph-theory breadth-first-search

我试图实现类似于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应该如何工作:

enter image description here

enter image description here

1 个答案:

答案 0 :(得分:1)

有2个堆叠 - 一个用于当前级别,一个用于下一级别。

从当前级别查看/弹出并进入下一级别。如果当前级别为空,则交换两个堆栈(因此下一级别将成为当前级别,反之亦然)。

它看起来像这样:
(例如您的代码,但q替换为currentnext,并交换了两个代码

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也需要更改(因为它当前可能会强制在单个节点上从左到右的方向)。一种选择是向下传递一个方向,以决定是从左侧还是右侧返回下一个孩子(在交换nextcurrent时您反转)。

可以在不更改getUnvisitedChildNode的情况下执行此操作,但需要一些“丑陋”的代码 - 基本的想法是在循环中调用getUnvisitedChildNode,直到您拥有某个给定节点的所有子节点,将所有这些孩子扔进一个阵列(不进行处理,即打印它们),然后使用类似的方向变量选择处理它们的方向。

如果你已经可以访问子数组,你可以直接从左边或右边循环。