用深度遍历dfs判断一个有向图是否有环

来源:互联网 发布:淘宝外卖要实体店吗 编辑:程序博客网 时间:2024/06/10 19:50

这里有一个无向图的深度遍历算法,无向图 深度优先遍历 c语言实现, 有向图的DFS遍历跟这个算法一样。
利用DFS判断一个有向图是否有环的思路是:对一个节点v进行深度遍历,判断是否能从v到达自己这个节点,即是否存在从v到v的环路。
在图的深度遍历中,我们将图中每个节点设置为三个状态:-1,0,1,分别表示还没发现的节点;已经发现但是还没处理完的节点;已经处理完的节点。对应上述思路,假设我们正在处理v,那么v的状态为0,其余正在处理节点的状态也为0,如果从状态为0的节点遍历到状态为0的节点就存在环。
下面是leetcode中的一个题:Course Schedule,可以用dfs来解决,代码如下(下面代码效率很低,仅用来说明用dfs发现环的思路),

import java.util.ArrayList;import java.util.List;public class Solution {    boolean flag = true;    public void dfs(List<List<Integer>> adjList,int v,int[] color){        color[v] = 0;   //表示正在处理v节点        List<Integer> adjs = adjList.get(v);         for(int i=0;i<adjs.size();i++){            if(color[adjs.get(i)]==-1){                dfs(adjList,adjs.get(i),color);            }else if(color[adjs.get(i)]==0){//回到了状态为0的节点,有环                flag = false;            }        }        color[v] = 1;    }    public boolean canFinish(int numCourses, int[][] prerequisites) {        List<List<Integer>> adjList = new ArrayList<List<Integer>>();        //根据course个数初始化一个空的邻接表        for(int i=0;i<numCourses;i++){            adjList.add(new ArrayList<Integer>());        }        //初始化color数组        int[] color = new int[numCourses];        for(int i=0;i<numCourses;i++){            color[i] = -1;        }        //adjList表示邻接表,头结点是后面的课程,后面的list表示先修课        //由先修课指向 后修课        for(int i=0;i<prerequisites.length;i++){            int[] cp = prerequisites[i];            adjList.get(cp[1]).add(cp[0]);        }        //下面对邻接表进行深度遍历,看看是否有环,从每一个节点都遍历一次        for(int i=0;i<numCourses;i++){            dfs(adjList, i, color);            if(!flag){                return false;            }            for(int j=0;j<numCourses;j++){                color[j] = -1;            }        }        return flag;    }    public static void main(String[] args) {        Solution s = new Solution();        //4, [[0,1],[3,1],[1,3],[3,2]]        int[][] nums = {{0,1},{0,2},{1,2}};        System.out.println(s.canFinish(3, nums));    }}
0 0
原创粉丝点击