数据结构与算法之 leetcode 图论环检测 有向图 / 无向图

数据结构与算法阿木 发布于 2025-07-12 7 次阅读


图论环检测:有向图与无向图的算法实现

在图论中,环是一个非常重要的概念。它表示图中存在一条路径,该路径的起点和终点是同一个顶点。环的存在可能会影响算法的正确性和效率。在处理图相关问题时,环检测是一个基础且重要的任务。本文将围绕数据结构与算法,探讨有向图和无向图的环检测问题,并给出相应的代码实现。

环检测概述

环检测的主要目的是判断图中是否存在环。根据图的不同类型,环检测的方法也有所不同。以下是两种常见的环检测方法:

1. 有向图的环检测

有向图的环检测可以通过以下几种方法实现:

- 深度优先搜索(DFS):通过DFS遍历图,如果在访问某个顶点时,该顶点已经被访问过,则说明图中存在环。

- 拓扑排序:如果图中存在环,则无法进行拓扑排序。通过尝试对图进行拓扑排序,如果排序失败,则说明图中存在环。

2. 无向图的环检测

无向图的环检测可以通过以下几种方法实现:

- 并查集:通过并查集算法,将图中所有顶点进行合并,如果在合并过程中发现两个已经合并的顶点之间存在边,则说明图中存在环。

- DFS:与有向图类似,通过DFS遍历图,如果在访问某个顶点时,该顶点已经被访问过,则说明图中存在环。

有向图的环检测

深度优先搜索(DFS)

以下是一个使用DFS进行有向图环检测的Python代码实现:

python

def has_cycle_dfs(graph):


visited = set()


rec_stack = set()

def dfs(v):


visited.add(v)


rec_stack.add(v)

for i in graph[v]:


if i not in visited:


if dfs(i):


return True


elif i in rec_stack:


return True

rec_stack.remove(v)


return False

for i in graph:


if i not in visited:


if dfs(i):


return True


return False

示例


graph = {


0: [1],


1: [2],


2: [0],


3: [3]


}


print(has_cycle_dfs(graph)) 输出:True


拓扑排序

以下是一个使用拓扑排序进行有向图环检测的Python代码实现:

python

def has_cycle_topological_sort(graph):


in_degree = {u: 0 for u in graph}


for u in graph:


for v in graph[u]:


in_degree[v] += 1

queue = [u for u in graph if in_degree[u] == 0]


visited_count = 0

while queue:


u = queue.pop(0)


visited_count += 1


for v in graph[u]:


in_degree[v] -= 1


if in_degree[v] == 0:


queue.append(v)

return visited_count != len(graph)

示例


graph = {


0: [1],


1: [2],


2: [0],


3: [3]


}


print(has_cycle_topological_sort(graph)) 输出:True


无向图的环检测

并查集

以下是一个使用并查集进行无向图环检测的Python代码实现:

python

def find(parent, i):


if parent[i] == i:


return i


return find(parent, parent[i])

def union(parent, rank, x, y):


xroot = find(parent, x)


yroot = find(parent, y)

if xroot != yroot:


if rank[xroot] < rank[yroot]:


parent[xroot] = yroot


elif rank[xroot] > rank[yroot]:


parent[yroot] = xroot


else:


parent[yroot] = xroot


rank[xroot] += 1


return False


return True

def has_cycle_union(parent, rank, edges):


for u, v in edges:


if not union(parent, rank, u, v):


return True


return False

示例


edges = [(0, 1), (1, 2), (2, 0), (3, 3)]


parent = [i for i in range(len(edges))]


rank = [0 for i in range(len(edges))]


print(has_cycle_union(parent, rank, edges)) 输出:True


深度优先搜索(DFS)

以下是一个使用DFS进行无向图环检测的Python代码实现:

python

def has_cycle_dfs(graph):


visited = set()


rec_stack = set()

def dfs(v):


visited.add(v)


rec_stack.add(v)

for i in graph[v]:


if i not in visited:


if dfs(i):


return True


elif i in rec_stack:


return True

rec_stack.remove(v)


return False

for i in graph:


if i not in visited:


if dfs(i):


return True


return False

示例


graph = {


0: [1, 2],


1: [2],


2: [0, 3],


3: [3]


}


print(has_cycle_dfs(graph)) 输出:True


总结

本文介绍了有向图和无向图的环检测方法,并给出了相应的代码实现。在实际应用中,根据具体问题选择合适的环检测方法,可以有效地提高算法的效率和正确性。希望本文对您有所帮助。