📅  最后修改于: 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 算法查找循环的示例代码:
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 算法效率较高,但是实现比较复杂。无论使用哪种方法,都可以很好地解决在无向图中查找所有循环的问题。