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

这里有一个无向图的深度遍历算法,无向图 深度优先遍历 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));
    }
}
  • 10
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
对于使用深度优先遍历实现图的拓扑排序,并判断有向图是否有环的问题,可以按照以下步骤进行: 1. 创建一个空栈,用于存储拓扑排序的结果。 2. 对于图中的每个节点,从任意一个未访问过的节点开始进行深度优先遍历。 3. 在深度优先遍历的过程中,对于每个节点,首先将其标记为已访问,并将其所有未访问过的邻居节点递归地进行深度优先遍历。 4. 当一个节点的所有邻居节点都已经被访问过时,将该节点压入栈中。 5. 最后,从栈中依次弹出节点,即可得到拓扑排序的结果。 在实现过程中,如果在深度优先遍历的过程中遇到一个已经被访问过的节点,则说明图中存在环。 以下是一个使用深度优先遍历实现图的拓扑排序并判断有向图是否有环的示例代码(使用 Python 语言): ```python def topologicalSort(graph): visited = set() stack = [] def dfs(node): visited.add(node) for neighbor in graph[node]: if neighbor not in visited: dfs(neighbor) stack.append(node) for node in graph: if node not in visited: dfs(node) return stack[::-1] def hasCycle(graph): visited = set() stack = set() def dfs(node): visited.add(node) stack.add(node) for neighbor in graph[node]: if neighbor not in visited: if dfs(neighbor): return True elif neighbor in stack: return True stack.remove(node) return False for node in graph: if node not in visited: if dfs(node): return True return False ``` 在上述代码中,`graph` 表示输入的有向图,使用邻接表来表示。`topologicalSort` 函数返回拓扑排序的结果,`hasCycle` 函数返回有向图是否存在环。 请注意,这只是一个简单的示例,实际应用中可能需要根据具体情况进行适当的修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值