Python中使用逆邻接表解决拓扑排序问题
拓扑排序是一种针对有向无环图(DAG)的排序算法,可以将DAG中所有顶点排成一个线性序列,使得对于任意一条边(u,v),顶点u都排在顶点v的前面。在实际应用中,拓扑排序有着广泛的应用,例如编译器的代码优化、任务调度等领域。
Python中使用逆邻接表来解决拓扑排序问题,逆邻接表可以快速地找到顶点的入度信息,从而实现拓扑排序。逆邻接表是一个字典类型的数据结构,其中每个顶点v对应一个列表,列表包含了所有以v为终点的有向边的起点集合。
下面是Python代码演示拓扑排序的过程,具体思路如下:
-
首先将所有顶点的入度初始化为0,将所有边的终点对应的顶点入度加1。
-
使用一个队列来存储入度为0的顶点。
-
将队列中的顶点出队,并将其所有邻接点的入度减1,如果减1后入度为0,则将其加入到队列中。
-
重复执行步骤3,直到队列为空。
-
如果最终所有顶点的入度都为0,则说明拓扑排序成功,并返回拓扑排序的结果。
代码如下:
from collections import defaultdict def topo_sort(graph): # 建立逆邻接表 reverse_graph = defaultdict(list) for u in graph: for v in graph[u]: reverse_graph[v].append(u) # 初始化入度为0的顶点 in_degree = {u: 0 for u in graph} for u in graph: for v in graph[u]: in_degree[v] += 1 # 将入度为0的顶点加入队列 queue = [u for u in in_degree if in_degree[u] == 0] # 拓扑排序 result = [] while queue: u = queue.pop(0) result.append(u) for v in reverse_graph[u]: in_degree[v] -= 1 if in_degree[v] == 0: queue.append(v) # 如果存在入度不为0的顶点,则说明存在环 if len(result) != len(graph): return None else: return result
测试代码如下:
graph = { "a": ["b", "c"], "b": ["d"], "c": ["d"], "d": [] } print(topo_sort(graph)) # ["a", "c", "b", "d"] graph = { "a": ["b", "c"], "b": ["d"], "c": ["d"], "d": ["a"] } print(topo_sort(graph)) # None
上述代码中,第一个图是一个DAG,可以通过拓扑排序得到正确的结果;第二个图中存在环,无法通过拓扑排序得到正确的结果,返回None。
相关文章