在bfs

时间:2016-10-13 12:45:27

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

您已获得一个由N个节点组成的树。树是由N个节点和N-1个边组成的完全连接的图。此树中的节点从1到N编制索引。请将节点索引1视为此树的根节点。根节点位于树中的第一级。您将获得树和单个整数x。您需要找出位于x级的节点数。

输入格式

第一行由一个整数N组成,表示树中的节点数。接下来的n-1行中的每一行由2个整数a和b组成,表示节点a和节点b之间的无向边。下一行包含一个整数x。

输出格式

您需要打印一个整数,表示级别x上的节点数。

下面的

是我写的代码片段,它不正确。请帮我找到错误。

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner;

public class LevelNodes {
    public static ArrayList[] adj;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        boolean[] visites = new boolean[N];
        ArrayList[] adj = new ArrayList[N];
        for(int j=0;j<N;j++){
            adj[j] = new ArrayList();
        }
        for(int i = 0;i < (N-1) ;i++){
            int a = sc.nextInt();
            int b = sc.nextInt();
            adj[a-1].add(b);
            adj[b-1].add(a);
        }
        int level = sc.nextInt();
        int counter = 0;
        LinkedList list = new LinkedList();
        list.add(1);
        counter++;
        while(!list.isEmpty()){
            int n = (Integer) list.poll();
            for(int x = 0; x< adj[n-1].size();x++){
                list.add(adj[n-1].get(x));
            }
            counter++;
            if(counter == level){
                System.out.println(list.size());
                break;
            }

        }
    }

}

1 个答案:

答案 0 :(得分:0)

您的代码中存在许多问题:

第一个问题是您的代码可能无法终止。这是因为您将两个边u-&gt; v和v-> u添加到邻接列表中。因此,无论何时从列表中轮询u并添加其邻居,您都要将v添加到列表中。同样,无论何时轮询v并添加其邻居,您都要将u添加回列表。只要将u添加到列表中,就需要维护一个布尔数组visited并设置visited[u]=true。这样,您只能将未访问的节点添加到扫描列表中。

另一个主要问题是在while循环中。每当您访问新节点时,您都​​在递增级别计数器变量counter++;。考虑下面的树,并假设我们需要找到级别2(最后一级)的节点数。

     1
    / \
   2   3
  / \ / \
 4  5 6  7

最初,您的列表包含1和counter=1。在第一次迭代中,您从列表中轮询1并添加其邻居:2和3.在此阶段,counter=2。在接下来的两次迭代中,您将从列表中删除2和3,添加它们的邻居,并每次递增counter。所以到达第二级时,counter将等于4.If语句永远不会被执行。

要解决此问题,如果您已完成处理当前级别的所有节点,则必须递增counter。一种简单(未经测试)的方法是使用第二个临时列表来保存当前级别的所有节点的邻居。然后,只要原始列表为空,您就知道已经处理了当前级别的所有节点。在这里,您递增counter并将所有节点从临时列表移动到主列表。

while(!list.isEmpty()){
    int n = (Integer) list.poll();
    for(int x = 0; x< adj[n-1].size();x++){
        tmpList.add(adj[n-1].get(x));
    }

    if(list.isEmpty()) {
        if(counter == level){
            System.out.println(tmpList.size());
            break;
        }

        list.addAll(tmpList);
        tmpList.clear();
        counter++;
    }
}