【图的深度优先遍历】

发布时间:2024年01月12日

前言

深度优先遍历简称DFS,主要思路是从图中一个未访问的顶点 V 开始,沿着一条路一直走到底,然后从这条路尽头的节点回退到上一个节点,再从另一条路开始走到底,不断递归重复此过程,直到所有的顶点都遍历完成,它的特点是不撞南墙不回头,先走完一条路,再换一条路继续走。

使用递归实现深度优先遍历算法代码实现

public class DataFlowGraph {
   private static final String NODE_PROPERTY="nodeProperty";
   private static final String EDGE_LABLE="link";
   /**
    * 图
    */
   private Graph graph =null;
   /**
    * 图遍历临时栈
    */
   private Stack<String> stack = new Stack<String>();
   /**
    * 起点开始的所有路径
    */
   private Map<String,List<List<String>>> allPathMap=new HashMap<>();
   public DataFlowGraph (String flow) {
      JSONObject jsonObj= JSONObject.parseObject(flow);
      generateGraph(jsonObj);
   }
   public FlowGraph(JSONObject flowJson) {
      generateGraph(flowJson);
   }
   /**
    * 遍历DAG图中所有路径
    * @param id
    * @throws Exception 
    */
   public void findPathByStart(String id) throws Exception {
      stack.push(id);
      boolean bl=cyclicCheck(stack);
      if(bl) {
         throw new Exception("图存在环路");
      }
      Vertex vertex=graph.getVertex(id);
      Iterable<Vertex>  outVertexs=vertex.getVertices(Direction.OUT);
       int len=count(outVertexs);
      if(len>0) {          
         for(Vertex node:outVertexs) {
            findPathByStart(node.getId().toString());        
         }
         stack.pop();   
      }else {
         addToPath(stack);
         if(!stack.isEmpty()) {
            stack.pop();
         }
         return;
      }
      
   }

   /**
    * 检查是否存在环路 
    * @param pathStack
    * @return true 存在 false 不存在
    */
   private boolean cyclicCheck(Stack<String> pathStack) {
      HashSet<String> set = new HashSet<>();
      set.addAll(pathStack);
      int setSize=set.size();
      int stackSize=pathStack.size();
      if(stackSize>setSize) {
         return true;
      }else {
         return false;
      }
   }
   /**
    * 将pathStack转换为list,
    * @param pathStack
    */
   private void addToPath(Stack<String> pathStack) {
      List<String> singlePath=new ArrayList<String>();
      singlePath.addAll(pathStack);
      String startId=singlePath.get(0);
      List<List<String>> pathList=allPathMap.get(startId);
      if(pathList==null) {
         pathList=new ArrayList<List<String>>();
         allPathMap.put(startId, pathList);
      }
      pathList.add(singlePath);
   }
   /**
    * 根据节点id获取其属性
    * @param nodeId
    * @return
    */
   public JSONObject getNode(String nodeId) {
      Vertex vertex=graph.getVertex(nodeId);
      if(vertex!=null) {
         return (JSONObject)vertex.getProperty(NODE_PROPERTY);
      }else {
         return null;
      }
   }
   /**
    * 获取下一步所有节点
    * @param nodeId
    * @return
    */
   public JSONArray getNextNode(String nodeId) {
      JSONArray array=null;
      Iterable<Edge> ie=graph.getVertex(nodeId).getEdges(Direction.OUT);
      for(Edge edge:ie) {
         Vertex vertex=edge.getVertex(Direction.OUT);
         if(array==null) {
            array=new JSONArray();
         }
         array.add(vertex.getProperty(NODE_PROPERTY));
      }
      return array;
   }
   /**
    * 获取所有起始节点
    * @return
    */
   public List<String> getStartNodes() {
      List<String> starts=new ArrayList<String>();
       Iterable<Vertex> iterator=graph.getVertices();
        for(Vertex tmpv:iterator) {
           Iterable<Edge> edges=tmpv.getEdges(Direction.IN, EDGE_LABLE);
           int count=count(edges);
           if(count==0) {
              starts.add(tmpv.getId().toString());
           }
        }
        return starts;
   }
   
   /**
    * 通过json串生成图
    * @param flowJson
    */
   private void generateGraph(JSONObject flowJson) {
      graph = new TinkerGraph();
      //构建Vertex
      JSONArray nodes=flowJson.getJSONArray("nodes");
      Map<String,Vertex> nodeMap=new HashMap<String,Vertex>();
      int len=nodes.size();
      for(int i=0;i<len;i++) {
         JSONObject node=nodes.getJSONObject(i);
         String id=node.getString("id");
         
         Vertex vertex = GraphHelper.addVertex(graph, id, NODE_PROPERTY, node);
         nodeMap.put(id, vertex);
      }
      //构建Edge
      JSONArray links=flowJson.getJSONArray(JsonContant.DAG_LINKS);
      Map<String,JSONObject> linkMap=new HashMap<String,JSONObject>();
      len=links.size();
      for(int i=0;i<len;i++) {
         JSONObject link=links.getJSONObject(i);
         String id=link.getString(JsonContant.DAG_LINKS_ID);
         String fromId=link.getString(JsonContant.DAG_LINKS_FROM);
         String toId=link.getString(JsonContant.DAG_LINKS_TO);
         linkMap.put(id, link);
         Vertex vertexFrom=nodeMap.get(fromId);
         Vertex vertexTo=nodeMap.get(toId);
         GraphHelper.addEdge(graph,id, vertexFrom, vertexTo,"link" ,"name", "edge"+i);
      }

   }

   public List<List<String>> getAllPath(String startId) {
      return allPathMap.get(startId);
   } 
}

文章来源:https://blog.csdn.net/gwc791224/article/details/135545458
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。