首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用HashMap<Vertex、List<Vertex>>进行广度优先搜索

使用HashMap<Vertex、List<Vertex>>进行广度优先搜索
EN

Stack Overflow用户
提问于 2015-02-11 05:43:09
回答 3查看 5.7K关注 0票数 0

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

代码语言:javascript
复制
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中循环即可。或者如果我做了完全错误的事情:)

EN

回答 3

Stack Overflow用户

发布于 2015-02-11 05:57:57

如果我理解您的问题和示例代码,那么您要做的就是在不多次访问顶点的情况下迭代所有map的值。如果是这样,那么您可以使用Java 8执行以下操作:

代码语言:javascript
复制
map.values().stream().flatMap(List::stream).distinct()
    .forEach(vertex -> {...});

但是,如果您想从根节点开始并执行广度优先搜索(这是正常的机制),那么它就有点复杂了:

代码语言:javascript
复制
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);
}
票数 0
EN

Stack Overflow用户

发布于 2015-02-11 06:02:40

假设开始搜索的是一个顶点根,您的代码可能如下所示:

代码语言:javascript
复制
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);
            }
        }
    }
}
票数 0
EN

Stack Overflow用户

发布于 2015-02-11 06:04:29

在这里,我还没有真正尝试过这段代码,所以它可能甚至不会按原样编译,但让它工作起来应该不难。事实上,它应该让你对算法是如何工作的有一个很好的了解。

代码语言:javascript
复制
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集合术语。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28442385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档