📜  检测无向图中的循环(1)

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

检测无向图中的循环

在无向图中,循环指的是从一个节点出发通过若干个其他节点又回到该节点的路径。

本文将介绍如何检测无向图中的循环,并提供一些代码示例。

深度优先搜索

深度优先搜索(DFS)是一种常用的图遍历算法,通过遍历每一个节点来寻找循环。

实现思路

在深度优先搜索过程中,需要维护一个访问状态列表,记录每个节点的状态,包括未访问、正在访问和已访问三种状态。

当我们访问一个节点时,将其状态设置为正在访问,然后依次访问它的邻居节点。如果邻居节点的状态是正在访问,则说明存在循环;如果邻居节点的状态是未访问,则递归访问该节点;如果邻居节点的状态是已访问,则说明该节点已经处理过了,不需要再次访问。

代码示例

以下是使用深度优先搜索检测无向图循环的示例代码:

def dfs(node, visited, parent):
    visited[node] = True
    for neighbor in graph[node]:
        if not visited[neighbor]:
            if dfs(neighbor, visited, node):
                return True
        elif neighbor != parent:
            return True
    return False

def has_cycle(graph):
    visited = [False] * len(graph)
    for node in range(len(graph)):
        if not visited[node]:
            if dfs(node, visited, -1):
                return True
    return False
广度优先搜索

广度优先搜索(BFS)也是一种常用的图遍历算法,通过遍历每一个节点来寻找循环。

实现思路

和深度优先搜索不同的是,广度优先搜索不需要维护访问状态列表,而是使用队列来存储待访问节点。

当一个节点被加入队列时,将其状态设置为正在访问,然后依次访问它的邻居节点。如果邻居节点的状态是正在访问,则说明存在循环;如果邻居节点的状态是未访问,则将其加入队列;如果邻居节点的状态是已访问,则说明该节点已经处理过了,不需要再次访问。

代码示例

以下是使用广度优先搜索检测无向图循环的示例代码:

def bfs(node, visited):
    queue = [(node, -1)]
    visited[node] = True
    while queue:
        node, parent = queue.pop(0)
        for neighbor in graph[node]:
            if not visited[neighbor]:
                visited[neighbor] = True
                queue.append((neighbor, node))
            elif neighbor != parent:
                return True
    return False

def has_cycle(graph):
    visited = [False] * len(graph)
    for node in range(len(graph)):
        if not visited[node]:
            if bfs(node, visited):
                return True
    return False
测试

以下是使用上述两种方法测试无向图中是否存在循环的示例代码:

graph = [[1, 2], [0, 2], [0, 1, 3], [2]]
if has_cycle(graph):
    print("图中存在循环")
else:
    print("图中不存在循环")

输出结果为:

图中存在循环
总结

本文介绍了两种检测无向图中循环的方法:深度优先搜索和广度优先搜索。这两种方法都可以有效地找出无向图中的循环,并且实现方式也非常简单。在实际开发中,可以根据需要选择适合自己的方法来处理无向图循环的问题。