noaman_wgs

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

【题目】

对于一个有向图,请实现一个算法,找出两点之间是否存在一条路径。

给定图中的两个结点的指针UndirectedGraphNode* a,UndirectedGraphNode* b(请不要在意数据类型,图是有向图),请返回一个bool,代表两点之间是否存在一条路径(a到b或b到a)。

【代码】

import java.util.*;

/*
public class UndirectedGraphNode {
    int label = 0;
    UndirectedGraphNode left = null;
    UndirectedGraphNode right = null;
    ArrayList<UndirectedGraphNode> neighbors = new ArrayList<UndirectedGraphNode>();

    public UndirectedGraphNode(int label) {
        this.label = label;
    }
}*/
public class Path {
     //将访问的结点标记为true
    Map<UndirectedGraphNode, Boolean> visitedMap = new HashMap<>();
    
    public boolean checkPath(UndirectedGraphNode a, UndirectedGraphNode b) {

           /*if (checkDFS(a, b)) {
                 return true;
           } else {
                 visitedMap.clear();
                 return checkDFS(b, a);
           }*/
        return checkBFS(a, b) || checkBFS(b, a);
    }
    
    //深度优先搜索(递归)
    public boolean checkDFS(UndirectedGraphNode a, UndirectedGraphNode b){
        if(a == null || b == null)
            return false;
        if (a == b)
            return true;
        
       
        visitedMap.put(a, true);
        for (UndirectedGraphNode neighborNode : a.neighbors ){
            //若当前结点neighborNode 没有被访问到,且结点的值与b相同
            //则表示a邻结点neighborNode 与 b相通,即a与b相通
            if(!visitedMap.containsKey(neighborNode) && checkDFS(neighborNode, b)){
                return true;
            }
        }
        return false;
        
    }
    //深度优先搜索(递归)
    public boolean checkBFS(UndirectedGraphNode a, UndirectedGraphNode b){
        if(a == null || b == null)
            return false;
        if (a == b)
            return true;
        
        Queue<UndirectedGraphNode> queue = new LinkedList<>();
        //将访问的结点标记为true
         Map<UndirectedGraphNode, Boolean> visitedMap2 = new HashMap<>();
        
        visitedMap2.put(a, true);
        queue.offer(a);
        while (!queue.isEmpty()){
            //弹出队列的头结点
            UndirectedGraphNode node = queue.poll();
            //遍历该结点的邻结点
            for(UndirectedGraphNode neighboreNode : node.neighbors){
                
                if (!visitedMap2.containsKey(neighboreNode)){
                    if(neighboreNode == b){
                        return true;
                    }
                    visitedMap2.put(neighboreNode, true);
                    queue.offer(neighboreNode);
                } 
                
            }
            
        }
        
        return false;
    }
    
}

【解析】

深度优先遍历(DFS):从图中某个顶点v出发,访问此顶点,然后从v的未被访问的邻结点出发深度优先遍历图,直至图中所有和v有路径相通的顶点都被访问到。
若图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程。
遍历规则:不断地沿着顶点的深度方向遍历。顶点的深度方向是指它的邻接点方向。
广度优先遍历(BFS):类似于树的层序遍历。先访问完当前顶点的所有邻接点。(应该看得出广度的意思)
先访问顶点的邻接点先于后访问顶点的邻接点被访问。


深度优先遍历适合目标比较明确,以找到目标为主要目的的情况;
广度优先遍历更适合在不断扩大范围找到相对最优解的情况。

 

posted on 2017-06-26 16:41  noaman_wgs  阅读(160)  评论(0编辑  收藏  举报