实现图的拓扑排序,支持检测有向环。

图的拓扑排序是一种线性排序,适用于有向无环图(DAG)。如果图中存在有向环,则无法进行拓扑排序。我们可以使用 Kahn 算法或深度优先搜索(DFS)来实现拓扑排序,并检测有向环。

以下是使用 Kahn 算法和 DFS 的两种实现方式:

方法 1:Kahn 算法

Kahn 算法通过维护一个入度为零的节点队列来逐步生成拓扑排序。如果在处理过程中无法将所有节点排序,则说明存在环。

pythonCopy Codefrom collections import deque, defaultdictdef topological_sort_kahn(graph):    # 计算每个节点的入度
    in_degree = defaultdict(int)    for node in graph:        for neighbor in graph[node]:
            in_degree[neighbor] += 1
    # 初始化队列,将所有入度为零的节点加入队列
    queue = deque([node for node in graph if in_degree[node] == 0])
    topological_order = []    while queue:
        current = queue.popleft()
        topological_order.append(current)        # 遍历当前节点的邻居,减少其入度
        for neighbor in graph[current]:
            in_degree[neighbor] -= 1
            if in_degree[neighbor] == 0:
                queue.append(neighbor)    # 如果拓扑排序中的节点数不等于图中的节点数,说明存在环
    if len(topological_order) != len(graph):        return None  # 存在环
    return topological_order# 示例图(无环)graph = {    'A': ['C'],    'B': ['C', 'D'],    'C': ['E'],    'D': ['F'],    'E': ['H'],    'F': ['G'],    'G': [],    'H': []
}print(topological_sort_kahn(graph))  # 输出: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] 或其他合法顺序# 示例图(有环)cyclic_graph = {    'A': ['B'],    'B': ['C'],    'C': ['A']
}print(topological_sort_kahn(cyclic_graph))  # 输出: None

方法 2:深度优先搜索(DFS)

DFS 方法通过递归访问节点,并在回溯时构建拓扑排序。如果在访问过程中遇到一个正在访问的节点,则说明存在环。

pythonCopy Codedef topological_sort_dfs(graph):
    visited = {'visiting': set(), 'visited': set()}
    topological_order = []
    has_cycle = False
    def dfs(node):        nonlocal has_cycle        if has_cycle:            return
        if node in visited['visiting']:
            has_cycle = True
            return
        if node in visited['visited']:            return
        visited['visiting'].add(node)        for neighbor in graph.get(node, []):
            dfs(neighbor)
        visited['visiting'].remove(node)
        visited['visited'].add(node)
        topological_order.append(node)    for node in graph:        if node not in visited['visited']:
            dfs(node)        if has_cycle:            return None  # 存在环
    topological_order.reverse()  # 因为是后序添加,需要反转
    return topological_order# 示例图(无环)print(topological_sort_dfs(graph))  # 输出: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] 或其他合法顺序# 示例图(有环)print(topological_sort_dfs(cyclic_graph))  # 输出: None

解释:

  • Kahn 算法‌:通过维护入度为零的节点队列来逐步生成拓扑排序。
  • DFS 方法‌:通过递归访问节点,利用标记集合来检测环。

这两种方法都能有效地进行拓扑排序并检测有向环。选择哪种方法取决于具体需求和偏好。


http://www.zgjzs.org

http://www.shangpin.org

http://www.snjrw.org

http://wangluo.zgjzs.org

http://zhineng.zgjzs.org

http://gaosu.zgjzs.org

http://anquan.zgjzs.org

http://wangzhan.zgjzs.org

http://jiaoyu.zgjzs.org

http://guanggao.zgjzs.org

http://shuju.zgjzs.org

http://zhifu.zgjzs.org

http://yingyong.zgjzs.org

http://yonghu.zgjzs.org

http://houtai.zgjzs.org

http://fenxi.zgjzs.org

http://jiekou.zgjzs.org

http://fenxiang.zgjzs.org

http://neirong.zgjzs.org

http://zhuce.zgjzs.org

http://tongji.zgjzs.org

http://ditu.zgjzs.org

http://tuisong.zgjzs.org

http://gouwu.zgjzs.org

http://tuiguang.zgjzs.org

http://shejiao.zgjzs.org

http://zhongguo.zgjzs.org

http://wangguan.zgjzs.org

http://yule.zgjzs.org

http://pingtai.zgjzs.org

http://jichu.zgjzs.org

http://wangjie.zgjzs.org

http://zhishi.zgjzs.org

http://shangcheng.zgjzs.org

http://dianzi.zgjzs.org

http://yinyue.zgjzs.org

http://tupian.zgjzs.org

http://shipin.zgjzs.org

http://wuliu.zgjzs.org

http://gongju.zgjzs.org

http://anquan.zgjzs.org

http://sousuo.zgjzs.org

http://mima.zgjzs.org

http://jiankong.zgjzs.org

http://ceshi.zgjzs.org

http://wangyou.zgjzs.org

http://zixun.zgjzs.org

http://chajian.zgjzs.org

http://kuaidi.zgjzs.org

http://liuliang.zgjzs.org

http://zhengce.zgjzs.org

http://peizhi.zgjzs.org

http://baocun.zgjzs.org

http://yonghu.shangpin.org

http://houtai.shangpin.org

http://pingtai.shangpin.org

http://wangzhan.shangpin.org

http://zhifu.shangpin.org

http://guanggao.shangpin.org

http://yinyue.shangpin.org

http://zixun.shangpin.org

http://shejiao.shangpin.org

http://tuisong.shangpin.org

http://wangguan.shangpin.org

http://zhineng.shangpin.org

http://wangluo.shangpin.org

http://anquan.shangpin.org

http://zhongguo.shangpin.org

http://shuju.shangpin.org

http://jiekou.shangpin.org

http://zhishi.shangpin.org

http://gongneng.shangpin.org

http://tongji.shangpin.org

http://shipin.shangpin.org

http://jiaoyu.shangpin.org

http://ditu.shangpin.org

http://dianzi.shangpin.org

http://mima.shangpin.org

http://liuliang.shangpin.org

http://gouwu.shangpin.org

http://zhengce.shangpin.org

http://yule.shangpin.org

http://baocun.shangpin.org

http://jichu.shangpin.org

http://fenxi.shangpin.org

http://fenxiang.shangpin.org

http://shangcheng.shangpin.org

http://kuaidi.shangpin.org

http://peizhi.shangpin.org

http://wuliu.shangpin.org

http://ceshi.shangpin.org

http://tupian.shangpin.org

http://wangyou.shangpin.org

http://chajian.shangpin.org

http://tuiguang.shangpin.org

http://yingyong.shangpin.org

http://zhuce.shangpin.org

http://sousuo.shangpin.org

http://jiankong.shangpin.org

http://neirong.shangpin.org

http://gongju.shangpin.org

http://zonghe.shangpin.org

http://zhifu.snjrw.org

http://houtai.snjrw.org

http://yule.snjrw.org

http://wangluo.snjrw.org

http://guanggao.snjrw.org

http://shuju.snjrw.org

http://pingtai.snjrw.org

http://ditu.snjrw.org

http://wangzhan.snjrw.org

http://shejiao.snjrw.org

http://jiekou.snjrw.org

http://zhishi.snjrw.org

http://zhineng.snjrw.org

http://jiaoyu.snjrw.org

http://zhongguo.snjrw.org

http://yinyue.snjrw.org

http://yonghu.snjrw.org

http://tuiguang.snjrw.org

http://gouwu.snjrw.org

http://baocun.snjrw.org

http://fenxiang.snjrw.org

http://fenxi.snjrw.org

http://gongneng.snjrw.org

http://wangguan.snjrw.org

http://zixun.snjrw.org

http://dianzi.snjrw.org

http://tupian.snjrw.org

http://wangyou.snjrw.org

http://chajian.snjrw.org

http://wuliu.snjrw.org

http://mima.snjrw.org

http://liuliang.snjrw.org

http://zhuce.snjrw.org

http://zhengce.snjrw.org

http://peizhi.snjrw.org

http://shipin.snjrw.org

http://jichu.snjrw.org

http://tongji.snjrw.org

http://kuaidi.snjrw.org

http://yingyong.snjrw.org

http://sousuo.snjrw.org

http://jiankong.snjrw.org

http://neirong.snjrw.org

http://gongju.snjrw.org

http://tuisong.snjrw.org

http://shangcheng.snjrw.org

http://anli.snjrw.org

http://dianhua.snjrw.org

http://fuwu.snjrw.org

请使用浏览器的分享功能分享到微信等