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. CSS实现宽度自适应100%,宽高16:9的比例的圖片或者矩形

    前言 图片的大小是多少,宽度一定,高度要始终自自适应为16:9. 解决 1通过js,程序算出绝对高度再进行设置.这是解决问题最容易想到的方法. 2.我们的原则是能用css实现的功能尽量用css,这有利 ...

  2. 2019牛客多校C Governing sand——桶&&思维题

    题意 有 $n$ 种树,每种树都有高度 $H_i$,费用 $C_i$,数量 $P_i$,现要砍掉一些树,使得剩下的树中最高的树的数量超过一般,求最小的费用.($1 \leq n \leq 10^5, ...

  3. 2019HDU多校第四场 K-th Closest Distance ——主席树&&二分

    题意 给定 $n$ 个数,接下来有 $q$ 次询问,每个询问的 $l, r, p, k$ 要异或上一次的答案,才是真正的值(也就是强制在线).每次询问,输出 $[l, r]$ 内第 $k$ 小的 $| ...

  4. Luogu P3690【模板】Link Cut Tree (LCT板题)

    省选前刷道LCT板题(话说之前没做这道题-) CODE #include<bits/stdc++.h> using namespace std; inline void read(int ...

  5. date对象获取get

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 9、组件注册-@Import-使用ImportSelector

    9.组件注册-@Import-使用ImportSelector 9.1 @Import 源码: @Target(ElementType.TYPE) @Retention(RetentionPolicy ...

  7. JavsScript 一些技巧方法

    直接定义一个匿名函数,并立即调用: (function(){     //TODO: }()); 说明:function之前的左圆括号是必需的,如果不写这个,JavaScript解析器会试图将关键字f ...

  8. 023_STM32之PID算法原理及应用

    (O)关于程序BUG说明,看最后面的红色字体,视频和源代码中都没有说明 (一)PID控制算法(P:比例 I:积分 D:微分) (二)首先先说明原理,使用的是数字PID算法,模拟PID算法在计算机这样的 ...

  9. VUE 异步数据传递给 component props 的问题

    案例一 父组件parent.vue // asyncData为异步获取的数据,想传递给子组件使用 <template> <div> 父组件 <child :child-d ...

  10. elasticsearch _bulk api

    https://www.elastic.co/guide/cn/elasticsearch/guide/current/bulk.htmlbulk API 允许在单个步骤中进行多次 create . ...