Java 使用HashMap
我正在尝试在一个大型图上执行广度优先搜索。我有一个顶点列表和它的每个邻居。我将数据放入一个hashmap,其中键是顶点,值是与键相邻的顶点列表。我尝试了以下方法,但是第二个For循环无限期地运行,因为我使用键/值对进行循环。但我想不出其他方法来正确循环并命中每个节点Java 使用HashMap,java,hashmap,queue,breadth-first-search,Java,Hashmap,Queue,Breadth First Search,我正在尝试在一个大型图上执行广度优先搜索。我有一个顶点列表和它的每个邻居。我将数据放入一个hashmap,其中键是顶点,值是与键相邻的顶点列表。我尝试了以下方法,但是第二个For循环无限期地运行,因为我使用键/值对进行循环。但我想不出其他方法来正确循环并命中每个节点 public static void BFS(HashMap<Vertex, List<Vertex>> map) { Queue<Vertex> myQ = new Linked
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());
}
}
}
}
“计数”属性用于跟踪是否已访问顶点
任何帮助都将不胜感激,只需寻找一种新的思维方式来思考如何循环使用HashMap。或者,如果我做了一些完全错误的事情:如果我理解您的问题和示例代码,那么您所要做的就是迭代所有贴图的值,而不必多次访问顶点。如果是这样,那么您可以使用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);
}
假设有一个顶点根开始搜索,您可以编写如下代码:
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);
}
}
}
}
在这里,我并没有真正尝试过这段代码,所以它甚至可能不会像现在这样编译,但让它工作起来应该并不困难。事实上,它应该能让你很好地了解算法应该如何工作
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类,封装顶点映射,并提供在Graph术语而不是java collections术语中有意义的操作。我看不到您的搜索在搜索什么,也看不到它从何处开始whilemyq!=无效的{永远不会是真的,因为您从未将myQ设置为null。现在我只是尝试迭代每个节点及其所有邻居,如果它正确循环,那么在映射的末尾,最后一个元素将在myQ.remove中被删除,这将使队列为null。当我逐步执行代码时,最大的问题是我无法更改值到键。如果我曾经遍历过340,25的子键,那么我需要使40和25与键相等,然后开始遍历它们的子键…我只是不能把我的头绕在那上面,这会使队列null不是null。空的。这也是在开始时。我会研究一下,谢谢,但我无法解决的是我的co上面的mment^很遗憾,我必须使用Java 7