Topological Sorting

给定一个有向图,图节点的拓扑排序被定义为:

 

  • 对于每条有向边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 elements
S ← Set of all nodes with no incoming edges
while 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 S
if 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

 

dfs解法:
class Solution:
    """
    @param: graph: A list of Directed graph node
    @return: Any topological order for the given graph.
    """
    def topSort(self, graph):
        # write your code here
        
        if len(graph) == 0:
            return []
            
        res = []
        visited = set()
        for node in graph:
            if node not in visited:
                self.dfs(node, visited, res)
        return res[::-1]
        
    def dfs(self, node, visited, res):    
        visited.add(node)
        for neigh in node.neighbors:
            if neigh not in visited:
                self.dfs(neigh, visited, res)
        
        res.append(node)   

 

 

posted on 2016-06-12 16:34  Sheryl Wang  阅读(211)  评论(0编辑  收藏  举报

导航