BFS算法整理(python实现)

广度优先算法(Breadth-First-Search),简称BFS,是一种图形搜索演算算法。

1. 算法的应用场景

2. 算法的模板

2.1 针对树的BFS模板

  • 无需分层遍历
  1. from collections import deque
  2. # Definition for a binary tree node.
  3. class TreeNode:
  4. def __init__(self, x):
  5. self.val = x
  6. self.left = None
  7. self.right = None
  8. def level_order_tree(root, result):
  9. if not root:
  10. return
  11. # 这里借助python的双向队列实现队列
  12. # 避免使用list.pop(0)出站的时间复杂度为O(n)
  13. queue = deque([root])
  14. while queue:
  15. node = queue.popleft()
  16. # do somethings
  17. result.append(node.val)
  18. if node.left:
  19. queue.append(node.left)
  20. if node.right:
  21. queue.append(node.right)
  22. return result
  23. if __name__ == "__main__":
  24. tree = TreeNode(4)
  25. tree.left = TreeNode(9)
  26. tree.right = TreeNode(0)
  27. tree.left.left = TreeNode(5)
  28. tree.left.right = TreeNode(1)
  29. print(level_order_tree(tree, []))
  30. # [4, 9, 0, 5, 1]
  • 需要分层遍历
  1. def level_order_tree(root):
  2. if not root:
  3. return
  4. q = [root]
  5. while q:
  6. new_q = []
  7. for node in q:
  8. # do somethins with this layer nodes...
  9. # 判断左右子树
  10. if node.left:
  11. new_q.append(node.left)
  12. if node.right:
  13. new_q.append(node.right)
  14. # 记得将旧的队列替换成新的队列
  15. q = new_q
  16. # 最后return想要返回的东西
  17. return xxx

2.2 针对图的BFS

  • 无需分层遍历的图
  1. from collections import deque
  2. def bsf_graph(root):
  3. if not root:
  4. return
  5. # queue和seen为一对好基友,同时出现
  6. queue = deque([root])
  7. # seen避免图遍历过程中重复访问的情况,导致无法跳出循环
  8. seen = set([root])
  9. while queue:
  10. head = queue.popleft()
  11. # do somethings with the head node
  12. # 将head的邻居都添加进来
  13. for neighbor in head.neighbors:
  14. if neighbor not in seen:
  15. queue.append(neighbor)
  16. seen.add(neighbor)
  17. return xxx
  • 需要分层遍历的图
  1. def bsf_graph(root):
  2. if not root:
  3. return
  4. queue = [root]
  5. seen = set([root])
  6. while queue:
  7. new_queue = []
  8. for node in queue:
  9. # do somethins with the node
  10. for neighbor in node.neighbors:
  11. if neighbor not in seen:
  12. new_queue.append(neighbor)
  13. seen.add(neighbor)
  14. return xxx

2.3 拓扑排序

在图论中,由一个有向无环图的顶点组成的序列,当且仅当满足下列条件时,称为该图的一个拓扑排序(英语:Topological sorting)。

每个顶点出现且只出现一次;

若A在序列中排在B的前面,则在图中不存在从B到A的路径。

实际应用

  • 检测编译时的循环依赖
  • 制定有依赖关系的任务的执行顺序(例如课程表问题)

算法流程

  1. 统计所有点的入度,并初始化拓扑排序序列为空。
  2. 将所有入度为0的点,放到如BFS初始的搜索队列中。
  3. 将队列中的点一个一个释放出来,把访问其相邻的点,并把这些点的入度-1.
  4. 如何发现某个点的入度为0时,则把这个点加入到队列中。
  5. 当队列为空时,循环结束。

算法实现

  1. class Solution():
  2. def top_sort(self, graph):
  3. node_to_indegree = self.get_indegree(graph)
  4. # 初始化拓扑排序序列为空
  5. order = []
  6. start_nodes = [node for node in graph if node_to_indegree[node] == 0]
  7. queue = collection.deque(start_nodes)
  8. while queue:
  9. head = queue.popleft()
  10. order.append(node)
  11. for neighbor in head.neighbors:
  12. node_to_indegree[neighbor] -= 1
  13. if node_to_indegree[neighbor] == 0:
  14. queue.append(neighbor)
  15. return order
  16. def get_indegree(self, graph):
  17. node_to_indegree = {x: 0 for x in graph}
  18. for node in graph:
  19. for neighbor in node.neighbors:
  20. node_to_indegree[neighbor] += 1
  21. return node_to_indegree

BFS算法模板(python实现)的更多相关文章

  1. [笔记]BFS算法的python实现

    #!/usr/bin/env python # -*- coding:utf-8 -*- graph = {} graph["you"] = ["alice", ...

  2. BFS (1)算法模板 看是否需要分层 (2)拓扑排序——检测编译时的循环依赖 制定有依赖关系的任务的执行顺序 djkstra无非是将bfs模板中的deque修改为heapq

    BFS模板,记住这5个: (1)针对树的BFS 1.1 无需分层遍历 from collections import deque def levelOrderTree(root): if not ro ...

  3. BFS算法(——模板习题与总结)

    首先需要说明的是BFS算法(广度优先算法)本质上也是枚举思想的一种体现,本身效率不是很高,当数据规模很小的时候还是可以一试的.其次很多人可能有这样的疑问,使用搜索算法的时候,到底选用DFS还是BFS, ...

  4. POJ 1273 Drainage Ditches(网络流dinic算法模板)

    POJ 1273给出M条边,N个点,求源点1到汇点N的最大流量. 本文主要就是附上dinic的模板,供以后参考. #include <iostream> #include <stdi ...

  5. 机器学习算法与Python实践之(三)支持向量机(SVM)进阶

    机器学习算法与Python实践之(三)支持向量机(SVM)进阶 机器学习算法与Python实践之(三)支持向量机(SVM)进阶 zouxy09@qq.com http://blog.csdn.net/ ...

  6. 算法模板学习专栏之总览(会慢慢陆续更新ing)

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/7495310.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  7. POJ 1815 - Friendship - [拆点最大流求最小点割集][暴力枚举求升序割点] - [Dinic算法模板 - 邻接矩阵型]

    妖怪题目,做到现在:2017/8/19 - 1:41…… 不过想想还是值得的,至少邻接矩阵型的Dinic算法模板get√ 题目链接:http://poj.org/problem?id=1815 Tim ...

  8. HDU1532最大流 Edmonds-Karp,Dinic算法 模板

    Drainage Ditches Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...

  9. Day1 BFS算法的学习和训练

    ​ 因为自己的原因,之前没有坚持做算法的相应学习,总是觉得太难就半途而废,真的算是一个遗憾了,所以现在开始,定一个30天入门学习算法计划. ​ 我是根据<算法图解>的顺序进行安排的,自己对 ...

随机推荐

  1. email.py

    import os import argparse import yaml import smtplib import csv from email.mime.multipart import MIM ...

  2. 团队开发前端VUE项目代码规范

    团队开发前端VUE项目代码规范 2018年09月22日 20:18:11 我的小英短 阅读数 1658   一.规范目的: 统一编码风格,命名规范,注释要求,在团队协作中输出可读性强,易维护,风格一致 ...

  3. MySQL 5.7 GTID OOM bug案例分析 --大量压测后主从不同步

    转载自:http://www.sohu.com/a/231766385_487483 MySQL 5.7是十年内最为经典的版本,这个观点区区已经表示过很多次.然而,经典也是由不断地迭代所打造的传奇.5 ...

  4. LOJ #121. 「离线可过」动态图连通性 LCT维护最大生成树

    这个还是比较好理解的. 你考虑如果所有边构成一棵树的话直接用 LCT 模拟一波操作就行. 但是可能会出现环,于是我们就将插入/删除操作按照时间排序,然后依次进行. 那么,我们就要对我们维护的生成树改变 ...

  5. robotframework出现错误:Keyword 'AppiumLibrary.Open Application' expected 1 to 2 non-keyword arguments,got 5.

    robotframework官网: http://robotframework.org/#introduction -------------- 出现的场景: 由于一开始不了解robotframewo ...

  6. 数据结构实验之数组三:快速转置(SDUT 3347)

    Problem Description 转置运算是一种最简单的矩阵运算,对于一个m*n的矩阵M( 1 = < m < = 10000,1 = < n < = 10000 ),它 ...

  7. c++问题集合

    1.对于程序未运行和运行后的代码段到底存储什么? 2.编写程序时为什么先申请变量后使用? 3.malloc本质到底分配了什么?谁赋给的? 4.程序在系统上是怎么运行起来的? 5.当我们双击一个程序运行 ...

  8. ERRORS: ?: (corsheaders.E013) Origin '*' in CORS_ORIGIN_WHITELIST is missing scheme or netloc HINT:

    报错信息 ERRORS: ?: (corsheaders.E013) Origin '*' in CORS_ORIGIN_WHITELIST is missing scheme or netloc H ...

  9. c++ 容器切片反转次序(拷贝到新容器)

    code: // rotate_copy algorithm example #include <iostream> // cout #include <algorithm> ...

  10. JQuery 行内编辑(即点即改)

    行内编辑 下面是详细的代码: <style> .dian { cursor: pointer; } </style> //这个让鼠标 移动到 span上 的时候 是一个小手 & ...