我正在尝试在大图上执行广度优先搜索。我有一个与其每个邻居的顶点列表。我已将数据放入散列图中,其中Key为Vertex,Value为邻近Key的Vertex List。我试过以下但是第二个" For Loop"由于我使用键/值对循环的方式,它无限期地运行。但我无法想到另一种正确循环并击中每个节点的方法。
public static void BFS(HashMap<Vertex, List<Vertex>> map) {
Queue<Vertex> myQ = new LinkedList<Vertex>();
for(HashMap.Entry<Vertex, List<Vertex>> entry : map.entrySet()) {
if(entry.getKey().getCount() == 0){
count++;
entry.getKey().setCount(count);
myQ.add(entry.getKey());
while(!myQ.isEmpty()) {
for(Vertex neighbor : entry.getValue()){
if(neighbor.getCount() == 0) {
count++;
neighbor.setCount(count);
myQ.add(neighbor);
}
}
myQ.remove(entry.getKey());
}
}
}
}
count属性用于跟踪是否已访问过顶点。
任何帮助都会受到赞赏,只是在寻找一种思考如何循环HashMap的新方法。或者如果我做错了什么:)
答案 0 :(得分:0)
如果我理解你的问题和示例代码,那么你要做的就是遍历所有地图的值,而不必多次访问一个顶点。如果是这样,那么您可以使用Java 8执行以下操作:
map.values().stream().flatMap(List::stream).distinct()
.forEach(vertex -> {...});
但是,如果您想从根节点开始并执行广度优先搜索(这是正常的机制),那么它会更复杂一些:
List<Vertex> completedList = new ArrayList<>();
for (List<Vertex> searchList = Arrays.toList(root);
!searchList.isEmpty();
searchList = searchList.stream().map(map::get).flatMap(List::steam)
.filter(v -> !completedList.contains(v))
.collect(Collectors.toList())) {
searchList.forEach(vertex -> {...});
completedList.addAll(searchList);
}
答案 1 :(得分:0)
假设Vertex根开始搜索,您的代码可能类似于:
public static void BFS(Vertex root, HashMap<Vertex, List<Vertex>> map) {
Deque<Vertex> myQ = new LinkedList<Vertex>();
myQ.add(root);
while(!myQ.empty()) {
Vertex current = myQ.getFirst();
current.visited = true;
// Or you can store a set of visited vertices somewhere
List<Vertex> neighbors = map.get(current);
for (Vertex neighbor : neighbors) {
if (!neighbor.visited) {
myQ.addLast(neighbor);
}
}
}
}
答案 2 :(得分:0)
在这里,我还没有真正尝试过这段代码,所以它甚至可能无法按原样进行编译,但要让它工作起来并不困难。事实上,它应该让你很好地了解算法应该如何工作。
public void BFS( HashMap<Vertex, List<Vertex>> map )
{
if( map.isEmpty() )
return;
/* pick an arbitrary first vertex to start from */
Vertex start = null;
for( Vertex temp : map.getKeys() )
{
start = temp;
break;
}
/* visit first vertex */
visit( start );
/* start recursion */
BFS( start, map );
}
public void BFS( Vertex start, HashMap<Vertex, List<Vertex>> map )
{
/* mark the current vertex as visited */
int count = start.getCount();
assert count == 0;
count++;
start.setCount( count );
/* visit each unvisited neighboring vertex */
for( Vertex neighbor : map.get( start ) )
{
if( neighbor.getCount() != 0 )
continue;
visit( neighbor );
}
/* recurse into each unvisited neighboring vertex */
for( Vertex neighbor : map.get( start ) )
{
if( neighbor.getCount() != 0 )
continue;
BFS( neighbor, map );
}
}
但是,在继续这个之前,我强烈建议您定义一个新的Graph
类,封装顶点映射,并提供在图形术语中有意义的操作,而不是java集合术语。