📜  打印无向图中的所有循环(1)

📅  最后修改于: 2023-12-03 15:39:41.664000             🧑  作者: Mango

打印无向图中的所有循环

在图论中,循环是指一条路径,其起点和终点相同。本文将介绍如何在无向图中打印所有的循环。

方法一:深度优先搜索

深度优先搜索(DFS)是一种常用的遍历无向图的算法。在搜索的过程中,如果当前节点已经被访问过,且当前节点不是起点,则说明已经找到了一个循环。我们可以用一个列表来存储访问节点的顺序,只有当一个节点已经被访问过,才会将其加入到这个列表中。

下面是一个使用深度优先搜索方法查找循环的示例代码:

def dfs(node, visited, path, graph, result):
    visited.add(node)
    path.append(node)

    for neighbor in graph[node]:
        if neighbor not in visited:
            dfs(neighbor, visited, path, graph, result)
        else:
            if neighbor == path[0]:
                result.append(path[:])
            else:
                continue

    path.pop()
    visited.remove(node)

def find_cycles(graph):
    """
    :param graph: 无向图的邻接表表示
    :return: 返回所有循环的列表
    """
    result = []
    visited = set()
    path = []

    for node in graph:
        if node not in visited:
            dfs(node, visited, path, graph, result)

    return result

上述代码需要传入无向图的邻接表表示,返回所有的循环。

使用示例:

>>> graph = {0: [1, 2], 1: [0, 2], 2: [0, 1, 3], 3: [2]}
>>> find_cycles(graph)
[[0, 1], [1, 2, 0], [2, 1, 0], [2, 3, 2]]
方法二:Tarjan 算法

Tarjan 算法是一种高效的算法,用于查找有向图中的强连通分量。由于无向图中的循环是特殊的强连通分量,因此该算法也适用于查找无向图中的循环。

下面是一个使用 Tarjan 算法查找循环的示例代码:

def tarjan(node, graph, low, idx, stack, result):
    low[node] = idx
    idx += 1
    stack.append(node)

    for neighbor in graph[node]:
        if low[neighbor] == -1:
            tarjan(neighbor, graph, low, idx, stack, result)
            low[node] = min(low[node], low[neighbor])
        elif neighbor in stack:
            low[node] = min(low[node], low[neighbor])

    if low[node] == idx - 1:
        cycle = []
        while stack:
            vertex = stack.pop()
            cycle.append(vertex)
            if vertex == node:
                break
        result.append(cycle[::-1])

def find_cycles(graph):
    """
    :param graph: 无向图的邻接表表示
    :return: 返回所有循环的列表
    """
    n = len(graph)
    low = [-1] * n
    idx = 0
    stack = []
    result = []

    for node in range(n):
        if low[node] == -1:
            tarjan(node, graph, low, idx, stack, result)

    return result

上述代码需要传入无向图的邻接表表示,返回所有的循环。

使用示例:

>>> graph = {0: [1, 2], 1: [0, 2], 2: [0, 1, 3], 3: [2]}
>>> find_cycles(graph)
[[1, 0], [0, 2, 1], [2, 1, 0], [2, 3, 2]]
总结

本文介绍了两种方法查找无向图中的所有循环。深度优先搜索方法简单直观,但是效率较低;Tarjan 算法效率较高,但是实现比较复杂。无论使用哪种方法,都可以很好地解决在无向图中查找所有循环的问题。