Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用HashMap_Java_Hashmap_Queue_Breadth First Search - Fatal编程技术网

Java 使用HashMap

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

我正在尝试在一个大型图上执行广度优先搜索。我有一个顶点列表和它的每个邻居。我将数据放入一个hashmap,其中键是顶点,值是与键相邻的顶点列表。我尝试了以下方法,但是第二个For循环无限期地运行,因为我使用键/值对进行循环。但我想不出其他方法来正确循环并命中每个节点

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