zoukankan      html  css  js  c++  java
  • 【19】有向路径检查

    【题目】

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

    给定图中的两个结点的指针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):类似于树的层序遍历。先访问完当前顶点的所有邻接点。(应该看得出广度的意思)
    先访问顶点的邻接点先于后访问顶点的邻接点被访问。


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

  • 相关阅读:
    easy ui 常用控件配置
    oracel 查询语句
    .Net 取树形结构的数据
    Asp.Net Core File的操作
    js 页面技巧
    ASP.NET Core 文件上传
    ASP.NET EF实体主外键关系
    ASP.NET MVC 后台传值前端乱码解决方案 富文本Ueditor编辑
    手机访问网站自动跳转到手机版
    Ecshop布局参考图
  • 原文地址:https://www.cnblogs.com/noaman/p/7081231.html
Copyright © 2011-2022 走看看