BFS模板,记住这5个: (1)针对树的BFS 1.1 无需分层遍历 from collections import deque def levelOrderTree(root): if not root: return q = deque([root]) while q: head = q.popleft() do something with this head node... if head.left: q.append(head.left) if head.right: q.append(head.right) return xxx 1.2 需要分层遍历 def levelOrderTree(root): if not root: return q = [root] while q: new_q = [] for node in q: # 和上面代码相比 差异就在这里 和 deque do something with this layer nodes... if node.left: new_q.append(node.left) if node.right: new_q.append(node.right) q = new_q return xxx (2)针对图的BFS 2.1 无需分层遍历 from collections import deque def bfs_graph(root): if not root: return queue = deque([root]) seen = set([root]) while queue: head = queue.popleft() do something with this head... for neighbor in head.neighbors: if neighbor not in seen: # 和tree的区别无非就是多了一个是否访问过的判断 seen.add(neighbor) queue.append(neighbor) return xxx 上述代码中: neighbor 表示从某个点 head 出发,可以走到的下一层的节点。 set/seen 存储已经访问过的节点(已经丢到 queue 里去过的节点) queue 存储等待被拓展到下一层的节点 set/seen 与 queue 是一对好基友,无时无刻都一起出现,往 queue 里新增一个节点,就要同时丢到 set 里。 需要分层遍历的宽度搜先搜索 2.2 需分层遍历 def bfs_graph(root): if not root: return [] q = [root] seen = set([root]) while q: new_q = [] for node in q: do something with this layer nodes... for neighbor in node.neighbors: if neighbor not in seen: # 和tree的区别无非就是多了一个是否访问过的判断 seen.add(neighbor) new_q.append(neighbor) q = new_q return xxx (3)拓扑排序 记住下面的代码 class Solution: """ @param graph: A list of Directed graph node @return: Any topological order for the given graph. """ def topSort(self, graph): node_to_indegree = self.get_indegree(graph) # bfs order = [] start_nodes = [n for n in graph if node_to_indegree[n] == 0] queue = collections.deque(start_nodes) while queue: node = queue.popleft() order.append(node) for neighbor in node.neighbors: node_to_indegree[neighbor] -= 1 if node_to_indegree[neighbor] == 0: queue.append(neighbor) return order def get_indegree(self, graph): node_to_indegree = {x: 0 for x in graph} for node in graph: for neighbor in node.neighbors: node_to_indegree[neighbor] += 1 return node_to_indegree 算法流程 拓扑排序的算法是典型的宽度优先搜索算法,其大致流程如下: 统计所有点的入度,并初始化拓扑序列为空。 将所有入度为 0 的点,也就是那些没有任何依赖的点,放到宽度优先搜索的队列中 将队列中的点一个一个的释放出来,放到拓扑序列中,每次释放出某个点 A 的时候,就访问 A 的相邻点(所有A指向的点),并把这些点的入度减去 1。 如果发现某个点的入度被减去 1 之后变成了 0,则放入队列中。 直到队列为空时,算法结束 一些实际案例: https://www.cnblogs.com/bonelee/p/11724346.html