给定一个有向图,图节点的拓扑排序被定义为:
- 对于每条有向边A--> B,则A必须排在B之前
- 拓扑排序的第一个节点可以是任何在图中没有其他节点指向它的节点
找到给定图的任一拓扑排序.
拓扑排序一共有两种解法:
1.是kahn’s algorithm
2.DFS的做法(按结束顺序放入L中)
kahn算法从入度考虑实际是BFS,DFS从出度考虑。复杂度都为O(V+E).
维基百科给出的kahn算法的伪代码为:
L ← Empty list that will contain the sorted elementsS ← Set of all nodes with no incoming edgeswhile S is non-empty do remove a node n from S add n to tail of L for each node m with an edge e from n to m do remove edge e from the graph if m has no other incoming edges then insert m into Sif graph has edges then return error (graph has at least one cycle)else return L (a topologically sorted order)
分三步走:1.先找到度为0的节点,加入队列。
2.处理队列中的节点,拿出一个结点,对每个结点的临接结点的入度都减少
3.如果结点的临接结点入度减少为0,则加入队列中。(意思是排在前面的都已经处理完了,到了当前节点)
代码如下:
# Definition for a Directed graph node# class DirectedGraphNode:# def __init__(self, x):# self.label = x# self.neighbors = []class Solution: """ @param graph: A list of Directed graph node @return: A list of graph nodes in topological order. """ def topSort(self, graph): if not graph: return [] hashmap = {} #count the in-degree of the node #这题graph里包含了所有的结点,所以可以这么写,否则还需要存储一个包含所有结点的集合。 for node in graph: for neigh in node.neighbors: if neigh not in hashmap: hashmap[neigh] = 1 else: hashmap[neigh] += 1 from collections import deque queue = deque() for node in graph: if node not in hashmap: queue.append(node) res = [] while queue: cur = queue.popleft() res.append(cur) #when pop, add to the result for neigh in cur.neighbors: #不会有重复出现,因为拓扑排序的设置,入度高的都在后面,不存在前后重复的问题。 hashmap[neigh] -= 1 if hashmap[neigh] == 0: #when the indegree is reduced to 0,means the prior node are all tackled. queue.append(neigh) return res