算法——广搜(BFS)/深搜(DFS)
在图的基本算法中,最初接触的就是图的遍历算法,根据访问节点的顺序,可分为广度优先搜索(BFS
)和深度优先搜索(DFS
)。
广度优先搜索
广度优先搜索算法主要解决两个问题:
- 从节点A出发有到节点B的路径吗?
- 从节点A出发到节点B的最短路径是哪条?
实现方式:
它的实现方式可以用队列的数据结构去理解(先进先出),每次取出一个节点都将这个节点相邻的节点加入队列尾部,直到找到需要寻找的节点。(这里需要注意的是循环依赖的问题,通常每取出一个节点就将其放入一个数组中,然后每次入队时都判断一下是否已使用过这个节点了)
实现:
首先我会生成一颗二叉树,然后根据广搜,一层一层的便利:
class Node(object):"""初始化一个节点,需要为节点设置值"""def __init__(self, val):self.val = valself.left = Noneself.right = Noneclass BinaryTree(object):"""创建二叉树,完成- 添加元素- 广度遍历"""def __init__(self):self.root = Nonepass# 添加元素def addNode(self, val):# 创建队列结构存储结点nodeStack = [self.root]# 如果根结点为空if self.root == None:self.root = Node(val)print("添加根节点{0}成功!".format(self.root.val))return# 模拟生成一颗二叉树,本身只持有root节点while len(nodeStack) > 0:# 队列元素出列p_node = nodeStack.pop()# 如果左子结点为空if p_node.left == None:p_node.left = Node(val)print("添加左:{0} ".format(p_node.left.val))return# 如果右子节点为空if p_node.right == None:p_node.right = Node(val)print("添加右:{0} ".format(p_node.right.val))return# 入队nodeStack.insert(0, p_node.left)nodeStack.insert(0, p_node.right)# 广度优先遍历def BFS(self):nodeStack = [self.root];# 只要队列不为空while len(nodeStack) > 0:my_node = nodeStack.pop()print("-->", my_node.val)if my_node.left is not None:nodeStack.insert(0, my_node.left)if my_node.right is not None:nodeStack.insert(0, my_node.right)def main():# 生成一个二叉树bt = BinaryTree()bt.addNode(0)bt.addNode(1)bt.addNode(2)bt.addNode(3)bt.addNode(4)bt.addNode(5)bt.addNode(6)bt.addNode(7)bt.addNode(8)bt.addNode(9)print("广度遍历-->")bt.BFS()if __name__ == '__main__':main()
结论:广度优先搜索的适用场景适用于深度不深且权值相同的图,搜索的结果为最短路径或者最小权值和。
深度优先搜索
深度优先搜索算法解决的问题有:
- 通过便利所有节点路径找到最小权重路径
实现方式:
它的实现方式可以用栈的数据结构去理解(先进后出),每次出栈时,都将它相邻的节点,压入栈头。直到该条路径都便利完了,它会回溯到上个节点然后继续这个步骤。(这里需要注意的是循环依赖的问题,通常每取出一个节点就将其放入一个数组中,然后每次入队时都判断一下是否已使用过这个节点了)
实现:
首先我会生成一颗二叉树,然后根据深搜,进行先序便利:
class Node(object):"""初始化一个节点,需要为节点设置值"""def __init__(self, val):self.val = valself.left = Noneself.right = Noneclass BinaryTree(object):"""创建二叉树,完成- 添加元素- 深度遍历"""def __init__(self):self.root = Nonepass# 添加元素def addNode(self, val):# 创建队列结构存储结点nodeStack = [self.root]# 如果根结点为空if self.root == None:self.root = Node(val)print("添加根节点{0}成功!".format(self.root.val))return# 模拟生成一颗二叉树,本身只持有root节点while len(nodeStack) > 0:# 队列元素出列p_node = nodeStack.pop()# 如果左子结点为空if p_node.left == None:p_node.left = Node(val)print("添加左:{0} ".format(p_node.left.val))return# 如果右子节点为空if p_node.right == None:p_node.right = Node(val)print("添加右:{0} ".format(p_node.right.val))return# 入队nodeStack.insert(0, p_node.left)nodeStack.insert(0, p_node.right)# 深度优先(先序遍历)栈def DFS(self, start_node):# 如果节点为null说明没有valif start_node == None:returnprint("-->", start_node.val)# 入栈,先入先出self.DFS(start_node.left)self.DFS(start_node.right)def main():# 生成一个二叉树bt = BinaryTree()bt.addNode(0)bt.addNode(1)bt.addNode(2)bt.addNode(3)bt.addNode(4)bt.addNode(5)bt.addNode(6)bt.addNode(7)bt.addNode(8)bt.addNode(9)print("先序遍历-->")bt.DFS(bt.root)if __name__ == '__main__':main()
结论:深度优先搜索的适用于针对深度很深或者深度不确定的图或者权值不相同的图,优势在于节省资源,但想要得到最优解需要完整遍历后比对所有路径选取最优解。
例子:
通过广搜和深搜便利文件目录:
广搜:
import os
import collections# if __name__ == '__main__':
# main()def getAllDirByBFS(path):queue = collections.deque()# 进队queue.append(path)# 循环,当队列为空,停止循环while len(queue) > 0:# 出队数据 这里相当于找到A元素的绝对路径dirPath = queue.popleft()try:# 找出跟目录下的所有的子目录信息,或者是跟目录下的文件信息dirList = os.listdir(dirPath)# 遍历该文件夹下的其他信息for filename in dirList:# 绝对路径dirAbsPath = os.path.join(dirPath, filename)# 判断:如果是目录dir入队操作,如果不是dir打印出即可if os.path.isdir(dirAbsPath):print("目录:" + dirAbsPath + filename)queue.append(dirAbsPath)else:print("普通文件:" + dirAbsPath + filename)except:print("打开异常" + dirPath)# 函数的调用
getAllDirByBFS('D:\\automatedTestTool')
深搜:
import osdef getAllDirByDFS(path):stack = []# 压栈操作,相当于图中的A压入stack.append(path)# 处理栈,当栈为空的时候结束循环while len(stack) > 0:# 从栈里取数据,相当于取出A,取出A的同时把BC压入dirPath = stack.pop()try:firstList = os.listdir(dirPath)# 判断:是目录压栈,把该目录地址压栈,不是目录即是普通文件,打印for filename in firstList:fileAbsPath = os.path.join(dirPath, filename)if os.path.isdir(fileAbsPath):# 是目录就压栈stack.append(fileAbsPath)getAllDirByDFS(fileAbsPath)else:# 是普通文件就打印即可,不压栈print("普通文件:", fileAbsPath + filename)except:print("打开异常" + dirPath)getAllDirByDFS(r'D:\\automatedTestTool')
算法——广搜(BFS)/深搜(DFS)相关推荐
- 图 相关算法~从头学算法【广搜、 深搜、 拓扑排序、 并查集、 弗洛伊德算法、迪杰斯特拉算法】
图的相关主流算法主要有: 广度优先搜索 深度优先搜索 拓扑排序 并查集 多源最短路径(弗洛伊德算法) 单源最短路径(迪杰斯特拉算法) 其中呢,最基本的是前两种,也就是平时常用的广搜和深搜,本文中将概要 ...
- DFS(爆搜、深搜)
DFS俗称爆搜,深搜.DFS对应的流程是一个树的结构,DFS的精髓在于递归求解的思路以及回溯的处理.针对搜索的过程,又有重要的剪枝优化.必要的剪枝优化对DFS的顺序执行有很大的作用. DFS的过程就是 ...
- 算法学习笔记 4-3 深搜(DFS)与广搜(BFS):初识问题状态空间 与 LeetCode真题(Java)
喜欢该类型文章可以给博主点个关注,博主会持续输出此类型的文章,知识点很全面,再加上LeetCode的真题练习,每一个LeetCode题解我都写了详细注释,比较适合新手入门数据结构与算法,后续也会更新进 ...
- 【算法合集】深搜广搜Prim与Kruskal
✅
- 算法学习 (门徒计划)3-3 深搜(DFS)与广搜(BFS)及经典问题 学习笔记
算法学习 (门徒计划)3-3 深搜(DFS)与广搜(BFS)及经典问题 学习笔记 前言 深搜与广搜 搜索的核心概念 问题求解树 搜索剪枝和优化 问题求解树的状态 对比深搜与广搜 DFS-深度(deep ...
- 二叉树的深搜(DFS)与广搜(BFS)
转载自: https://blog.csdn.net/u011613367/article/details/50950408 数据结构中的有两个比较重要的算法.深度优先搜索和广度优先搜索. 二叉树中的 ...
- 深搜DFS\广搜BFS 图初步入门
首先,不管是BFS还是DFS,由于时间和空间的局限性,它们只能解决数据量比较小的问题. 深搜,顾名思义,它从某个状态开始,不断的转移状态,直到无法转移,然后退回到上一步的状态,继续转移到其他状态,不断 ...
- 深搜和广搜的原理及优缺点
深搜原理 深搜,顾名思义,是深入其中.直取结果的一种搜索方法. 如果深搜是一个人,那么他的性格一定倔得像头牛!他从一点出发去旅游,只朝着一个方向走,除非路断了,他绝不改变方向!除非四个方向全都不通或遇 ...
- 简单深搜广搜基本模板
简单搜索 DFS: 剪枝,条件 容易超时,超时后基本就是剪枝的问题/无限递归?,或者用广搜试试? 模板(自己的理解) int n,m;//一般输入的行列数/边界 int mov[4][2] = {1, ...
最新文章
- ASP.NET程序中常用的三十三种代码 〔转〕
- KindEditor ASP.NET 上传/浏览服务器 附源码
- git 删除本地仓库中的分支_本地 Git 仓库与 GitHub 关联
- 计算机科学入门指南游戏攻略,【基础攻略】从零开始新手入门指南
- 如何分析request download在R3AR3显示成功执行,但是对应material没有生成的问题
- 【HTML+CSS网页设计与布局 从入门到精通】第7章-class、ID选择器,CSS格式
- Uploadify插件上传图片并且插入到FCKeditor
- 当前常见游戏服务器引擎
- pdf转换成word转换器注册码
- ros重置后地址_初始化ROS路由器后,怎么使用Setup 指令配置IP地址?
- 浏览器服务器响应报文查看,通过 Chrome浏览器 查看http请求报文
- 利用微信机器人 自动发送验证码
- 计算机的组装怎么学,如何学习组装电脑
- 均值定理最大值最小值公式_数学均值定理怎么求不等式的最大值最小值,求教会(ฅω*ฅ)...
- ESP8266 阿里云物联网平台 (详细步骤)
- easypoi导出一对多,合并单元格,且根据内容自适应行高
- 检测网页是否打开开发者工具(检测F12)
- NRC词语情绪词典和词语色彩词典
- iOS 12升级_iOS 12描述文件安装操作方法
- inno setup打包脚本总结
热门文章
- 大数据(5q)ClickHouse元数据
- Android SparseArray和ArrayMap相关总结
- 微信小程序缓存(本地缓存,同步缓存,异步缓存)
- 贵州开采大数据“钻石矿”
- linux中将python程序挂起命令
- 第三届云计算大会 - Dell云计算: 企业的有效转型策略(转载)
- Java中的映射Map - 入门篇
- 阔别7年,故地重游---崇明岛
- 关于《伤心者》,关于那些看不到结果的努力
- python+requests+pytest+allure+yaml+DDT+logs 接口自动化框架使用手册