算法图解之广度优先算法

一、用途

广度优先算法是为了解决两样东西之间的最短距离,其中最短距离的含义很多,如:

  • 编写国际跳棋AI,计算最少走多少步就可获胜
  • 编写拼写检查器, 计算最少编辑多少个地方就可将错拼的单词改成正确的单词
  • 根据你的人际关系网络找到关系最近的医生

二、图

图由节点和边组成,模拟一组链接。

三、广度优先搜索

应用场景

  • 从节点A出发,有前往节点B的路径吗?
  • 从节点A出发,前往节点B的哪条路径最短?

问题:你经营着一个芒果农场,你要找一个芒果销售商并把芒果卖给他。

解决思路:你需要优先从你的朋友中开始找,朋友中没有,再从朋友的朋友中找,在找完所有朋友之前,不去找朋友的朋友。以此类推。如下图所示:

这就需要按顺序进行添加,并按顺序进行查找,有一种数据结构可以实现这个目的,就是队列

四、队列(Queues)

队列的工作原理就和在医院排队挂号一张,排在前面的先挂号。

队列是一种先进先出(First In First Out)的数据结构,而栈是一种后进先出(Last In First Out,LIFO)的数据结构。

队列图示:

五、有向图和无向图

有箭头指向自己,但是没有从自己指向其他人的箭头,这被称为有向图(directed graph),其中的关系是单向的。 (Anuj、Peggy、Thom、Jonny)

直接相连的节点互为邻居,被称为无向图。

六、实现算法

from collections import deque

graph = {}
graph[‘you‘] = [‘alices‘, ‘bobs‘, ‘claires‘]
graph[‘bobs‘] = [‘anujs‘, ‘peggys‘]
graph[‘alices‘] = [‘peggys‘]
graph[‘claires‘] = [‘thoms‘, ‘jonnys‘, ‘jack‘]
graph[‘anujs‘] = []
graph[‘peggys‘] = []
graph[‘thoms‘] = []
graph[‘jonnys‘] = []
graph[‘jack‘] = [‘lucy‘, ‘mango_andrew‘]
graph[‘lucy‘] = []
graph[‘mango_andrew‘] = []

def person_is_seller(name):
    return ‘mango‘ in name

def search(name):
    search_queue = deque()
    search_queue += graph[name]
    searched = []

    while search_queue:
        person = search_queue.popleft()

        if person not in searched:
            if person_is_seller(person):
                print(person[6:] + ‘ is a mongo seller‘)
                return True
            else:
                search_queue += graph[person]
                searched.append(person)
    print(‘Not find mango seller‘)
    return False

search(‘you‘)

顺便提一下,字典这么写是为了看起来更清晰,它的添加顺序对结果是没有影响的,因为散列表是无序的。

graph[‘you‘] = [‘alices‘, ‘bobs‘, ‘claires‘]
graph[‘bobs‘] = [‘anujs‘, ‘peggys‘]

# 写成下面这样对结果一点影响都没有
graph[‘bobs‘] = [‘anujs‘, ‘peggys‘]
graph[‘you‘] = [‘alices‘, ‘bobs‘, ‘claires‘]

七、运行时间

你在整个人际关系网中搜索芒果销售商,就意味着你需要沿每条边前行(一个人到另一个人的箭头),时间至少为O(边数)。将每一个人添加到队列的时间是O(1),因此广度搜索的运行时间为O(人数 + 边数),通常写作O(V+E),其中V为定点(vertice),E为边数。

原文地址:https://www.cnblogs.com/lshedward/p/10480342.html

时间: 2024-10-12 11:42:54

算法图解之广度优先算法的相关文章

算法图解之广度优先搜索

广度优先搜索的应用场景,如下:(1)编写国际跳棋AI,计算最少走多少步就可获胜;(2)编写拼写检查器,计算最少编辑多个地方就可将错拼的单词改为正确的单词,如将READED改为READER需要编辑一个地方;(3)根据你的人际关系网络找到关系最近的医生; 图简介 假设你居住在旧金山,要从双子峰前往金门大桥.你想乘公交车前往,并希望换乘最少.可乘坐的公交车如下: 由图可知,换乘最少的路线是:步行->44路公交车->28路公交车(一共三步,这种问题也被称作为最短路径问题,解决最短路径问题的算法,又称广

【算法日记】广度优先算法

广度优先算法是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型.Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想.其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果.换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止.广度优先搜索让你能够找出两样东西之间最短的距离.在学习这个算法之前我们要了解图的概念 1.什么是图 如上图所示.图是有节点和边组成的.一个节点可能和很多节点直接相连,这些相

算法入门《数据结构与算法图解》+《我的第一本算法书》+《学习JavaScript数据结构与算法第3版》

最近几年学前端的人会越来越多,再加上前端的范围越来越广,从前端发展为全栈,数据结构和算法的功底要求势必将越来越高. <数据结构与算法图解>电子书及代码是数据结构与算法的入门指南,不局限于某种特定语言,略过复杂的数学公式,用通俗易懂的方式针对编程初学者介绍数据结构与算法的基本概念,培养编程逻辑.主要内容包括:为什么要了解数据结构与算法,大O表示法及其代码优化利用,栈.队列等的合理使用,等等. <算法图解>电子书非常的体贴,看起来也很快,用图来解释算法是非常好的想法,可作为学习数据结构

算法基础, 常用算法总结

接触的一些算法,搞不清楚搞得清楚的 列一个,大部分是最近看算法图解里边的算法,平常也经常用到,包括 二分查找,选择排序,快速排序,BFS DFS 动态规划 def binary_search(arr,item): #二分查找 l,h=0,len(arr)-1 while l<h: mid=(l+h)//2 if arr[mid]<item: l = mid + 1 elif arr[mid]>item: h=mid-1 else: return mid return None def s

《算法图解》代码实现和改进

<算法图解>代码实现和改进 请随意观看表演 二分查找 数组和链表 递归 递归条件和基线条件 快速排序 散列表 广度优先搜索 狄克斯特拉算法 贪婪算法 二分查找 def bin_search(list,item): low = 0 high = len(list) - 1 while low<=high: mid = (low+high)//2 #得到中间值 guess = list[mid] if guess==item: return mid elif guess>item: h

BFS广度优先算法的思路

广度优先算法的思想是 对所有的Node进行遍历 然后将第一个Node入队列 设置其visited为真 然后 对第一个Node跟其它剩余的Node进行遍历对比 找出连通的Node 并将其visited属性赋值为真 然后将其入队列 接下来对队列里面的Node进行迭代处理 最终完全遍历所有节点

深度优先算法和广度优先算法

算法:深度优先算法和广度优先算法(基于邻接矩阵) 1.写在前面 图的存储结构有两种:一种是基于二维数组的邻接矩阵表示法. 另一种是基于链表的的邻接表. 在邻接矩阵中,可以如下表示顶点和边连接关系: 说明: 将顶点对应为下标,根据横纵坐标将矩阵中的某一位置值设为1,表示两个顶点向联接. 图示表示的是无向图的邻接矩阵,从中我们可以发现它们的分布关于斜对角线对称. 我们在下面将要讨论的是下图的两种遍历方法(基于矩阵的): 我们已经说明了我们要用到的是邻接矩阵表示法,那么我首先要来构造图: 矩阵图的数据

树图 广度优先算法和深度优先算法

原文链接: ????????深度优先算法:http://blog.163.com/zhoumhan_0351/blog/static/3995422720098342257387/ ????????广度优先算法:http://blog.163.com/zhoumhan_0351/blog/static/3995422720098711040303/ 树图 广度优先算法和深度优先算法

深度优先与广度优先算法

图的遍历有深度优先和广度优先算法. 深度优先遍历可描述为一个递归算法.当到达顶点v时,具体操作是: ①访问(v); ②for(与v相邻的每个顶点w) 遍历(w): //深度优先算法 template<int max_size> void Diagraph<max_size>::depth_first(void(*visit)(Vertex &)) const { bool visited[max_size]; //引入数组防止无限循环 Vertex v; for (all