Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4688815

Browse files
committed
更新拓扑排序代码模版
1 parent 2f43b6d commit 4688815

File tree

2 files changed

+80
-16
lines changed

2 files changed

+80
-16
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import collections
2+
3+
class Solution:
4+
# 拓扑排序,graph 中包含所有顶点的有向边关系(包括无边顶点)
5+
def topologicalSortingDFS(self, graph: dict):
6+
visited = set() # 记录当前顶点是否被访问过
7+
onStack = set() # 记录同一次深搜时,当前顶点是否被访问过
8+
order = [] # 用于存储拓扑序列
9+
hasCycle = False # 用于判断是否存在环
10+
11+
def dfs(u):
12+
nonlocal hasCycle
13+
if u in onStack: # 同一次深度优先搜索时,当前顶点被访问过,说明存在环
14+
hasCycle = True
15+
if u in visited or hasCycle: # 当前节点被访问或者有环时直接返回
16+
return
17+
18+
visited.add(u) # 标记节点被访问
19+
onStack.add(u) # 标记本次深搜时,当前顶点被访问
20+
21+
for v in graph[u]: # 遍历顶点 u 的邻接顶点 v
22+
dfs(v) # 递归访问节点 v
23+
24+
order.append(u) # 后序遍历顺序访问节点 u
25+
onStack.remove(u) # 取消本次深搜时的 顶点访问标记
26+
27+
for u in graph:
28+
if u not in visited:
29+
dfs(u) # 递归遍历未访问节点 u
30+
31+
if hasCycle: # 判断是否存在环
32+
return [] # 存在环,无法构成拓扑序列
33+
order.reverse() # 将后序遍历转为拓扑排序顺序
34+
return order # 返回拓扑序列
35+
36+
def findOrder(self, n: int, edges):
37+
# 构建图
38+
graph = dict()
39+
for i in range(n):
40+
graph[i] = []
41+
for v, u in edges:
42+
graph[u].append(v)
43+
44+
return self.topologicalSortingDFS(graph)
45+
46+
print(Solution().findOrder(2, [[1,0]]))
47+
print(Solution().findOrder(4, [[1,0],[2,0],[3,1],[3,2]]))
48+
print(Solution().findOrder(1, []))
Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,41 @@
11
import collections
22

3-
class solution:
4-
def topologicalSorting(graph):
5-
indegrees = {u: 0 for u in graph}
3+
class Solution:
4+
# 拓扑排序,graph 中包含所有顶点的有向边关系(包括无边顶点)
5+
def topologicalSortingKahn(self, graph: dict):
6+
indegrees = {u: 0 for u in graph} # indegrees 用于记录所有节点入度
67
for u in graph:
78
for v in graph[u]:
8-
indegrees[v] += 1
9-
9+
indegrees[v] += 1 # 统计所有节点入度
1010

11+
# 将入度为 0 的顶点存入集合 S 中
1112
S = collections.deque([u for u in indegrees if indegrees[u] == 0])
12-
order = []
13+
order = []# order 用于存储拓扑序列
1314

1415
while S:
15-
u = S.pop()
16-
order.append(u)
17-
for v in graph[u]:
18-
indegrees[v] -= 1
19-
if indegrees[v] == 0:
20-
S.append(v)
16+
u = S.pop()# 从集合中选择一个没有前驱的顶点 0
17+
order.append(u)# 将其输出到拓扑序列 order 中
18+
for v in graph[u]:# 遍历顶点 u 的邻接顶点 v
19+
indegrees[v] -= 1# 删除从顶点 u 出发的有向边
20+
if indegrees[v] == 0:# 如果删除该边后顶点 v 的入度变为 0
21+
S.append(v)# 将其放入集合 S 中
2122

22-
size = len(indegrees)
23-
if size == len(S):
24-
return order
25-
return None
23+
if len(indegrees) != len(order): # 还有顶点未遍历(存在环),无法构成拓扑序列
24+
return []
25+
return order # 返回拓扑序列
26+
27+
28+
def findOrder(self, n: int, edges):
29+
# 构建图
30+
graph = dict()
31+
for i in range(n):
32+
graph[i] = []
33+
34+
for u, v in edges:
35+
graph[u].append(v)
36+
37+
return self.topologicalSortingKahn(graph)
38+
39+
print(Solution().findOrder(2, [[1,0]]))
40+
print(Solution().findOrder(4, [[1,0],[2,0],[3,1],[3,2]]))
41+
print(Solution().findOrder(1, []))

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /