BFS算法整理(python实现)

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

1. 算法的应用场景

2. 算法的模板

2.1 针对树的BFS模板

  • 无需分层遍历
from collections import deque

# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None def level_order_tree(root, result):
if not root:
return
# 这里借助python的双向队列实现队列
# 避免使用list.pop(0)出站的时间复杂度为O(n)
queue = deque([root]) while queue:
node = queue.popleft()
# do somethings
result.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return result if __name__ == "__main__":
tree = TreeNode(4)
tree.left = TreeNode(9)
tree.right = TreeNode(0)
tree.left.left = TreeNode(5)
tree.left.right = TreeNode(1) print(level_order_tree(tree, []))
# [4, 9, 0, 5, 1]
  • 需要分层遍历
def level_order_tree(root):
if not root:
return
q = [root]
while q:
new_q = []
for node in q:
# do somethins with this layer nodes...
# 判断左右子树
if node.left:
new_q.append(node.left)
if node.right:
new_q.append(node.right)
# 记得将旧的队列替换成新的队列
q = new_q
# 最后return想要返回的东西
return xxx

2.2 针对图的BFS

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

2.3 拓扑排序

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

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

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

实际应用

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

算法流程

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

算法实现

class Solution():
def top_sort(self, graph):
node_to_indegree = self.get_indegree(graph)
# 初始化拓扑排序序列为空
order = []
start_nodes = [node for node in graph if node_to_indegree[node] == 0] queue = collection.deque(start_nodes)
while queue:
head = queue.popleft()
order.append(node)
for neighbor in head.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

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. - The superclass "javax.servlet.http.HttpServlet" was not found on the Java

    网上有很多解决方法,如这种 下面是具体的解决方法:1.右击web工程->属性或Build Path->Java Build Path->Libraries-> Add Libr ...

  2. appium+python 【Mac】UI自动化测试封装框架介绍 <七>---脚本编写规范

    脚本的使用,注释非常关键,无论自己的后期查看还是别人使用,都可以通过注释很明确的知道代码所表达的意思,明确的知道如何调用方法等等.每个团队均有不同的商定形式来写脚本,因此没有明确的要求和规范来约束.如 ...

  3. vue slot及用法,$slots访问具名slot

  4. Java8-Lock-No.03

    import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutorService; import ...

  5. 总结 1121 Java面向对象

    总结 Java面向对象的基础 三大特征: 封装(抽象),继承,多态 面向对象的内存分析: 栈, 堆, 代码区, 静态区 this: 代表当前对象本身 有时候需要把当前调用对象进行传递,那么就可以使用t ...

  6. 使List<userClass>.Contains可以查找重復的對象

    List.Contains实现对比 http://blog.csdn.net/yswucn/article/details/4091469

  7. 【概率论】3-4:二维分布(Bivariate Distribution)

    title: [概率论]3-4:二维分布(Bivariate Distribution) categories: Mathematic Probability keywords: Discrete J ...

  8. Java 方法的重写

    方法重写规则: 1.子类要重写的方法与父类方法具有完全相同的返回类型+方法名称+参数列表: 2.子类要重写的方法的访问权限大于或者等于父类方法的访问权限: 3.子类要重写的方法不能抛出比父类方法更大的 ...

  9. Apache Kudu: Hadoop生态系统的新成员实现对快速数据的快速分析

    A new addition to the open source Apache Hadoop ecosystem, Apache Kudu completes Hadoop's storage la ...

  10. flask + nginx + uwsgi + ubuntu18.04部署python restful接口

    目录 参考链接 效果展示 一.准备工作 1.1 可运行的python demo: 1.2 更新系统环境 二.创建python虚拟环境 三.设置flask应用程序 四.配置uWSGI 五.设置系统启动 ...