叠甲:本人也只是参考书本学习bfs,理解可能并不准确
目的:解决最短路径问题
。广度优先搜索是一种用于图的查找算法,可帮助回答两类问题。
❑ 第一类问题:从节点A出发,有前往节点B的路径吗?
❑ 第二类问题:从节点A出发,前往节点B的哪条路径最短?
例子
假设你现在缺钱。(缺到连下一顿饭都没得吃的哪一种)
你想要从身边人借钱 来让自己不饿死。
你打开手机通讯录,一个一个打电话
先从周围亲近的朋友(不妨称之为一度关系)开始借钱。
小陈没借到,小戴没借到。。。。。
你将亲密朋友一个一个划除
然后发现,一个一度关系的朋友都没能借钱给你
于是你只能打朋友的朋友的电话(不妨称之为二度关系)
再一个一个将没能借到的人划除
最后你在二度关系的小龚那里借到了
在你看来,一度关系胜过二度关系,二度关系胜过三度关系,以此类推。因此,你应先在一度关系中搜索,确定其中没有芒果销售商后,才在二度关系中搜索。广度优先搜索就是这样做的!在广度优先搜索的执行过程中,搜索范围从起点开始逐渐向外延伸,即先检查一度关系,再检查二度关系。
你按顺序依次检查名单中的每个人,看看他是否能借钱给你。这将先在一度关系中查找,再在二度关系中查找,因此找到的是关系最近的“小龚”。
广度优先搜索不仅查找从A到B的路径,而且找到的是最短的路径。
什么是图(模型的建立)
我们知道要找到最好的借钱人选需要我们整理周围的人际关系
你打开通讯录,搜索一度关系,二度关系的时候
也就是使用图开始建立模型了
图由节点(node)和边(edge)组成。
图用于模拟不同的东西是如何相连的。
- 节点是事物主体
- 边是节点之间的关系
什么是队列
队列是一种先进先出(First In First Out, FIFO)的数据结构
在餐厅就餐时,我们需要先在入口处排队等候。
当有空位时,排在最前面的客人会先被带坐,就像元素被入队;
当客人吃完饭要离开时(假设每个人吃饭的速度是一样的),
餐厅的服务员会带上最先入队的客人,就像元素被出队。
队列采用先进先出的原则,最先进入队列的元素最先被取出,就像餐厅的先来后到。
后来的客人需要在队尾排队等候,等前面的客人都就餐完毕后才能被带坐。
这样一来一往的队列顺序,确保了公平有序。队列系统就像我们日常生活中遇到的许多排队场景,先排队的人先获得服务。
回顾
当我们开始使用bfs来借钱
- 开始建立图
- 将你的人际网络使用图的形式建模
- 使用人来作为点,关系作为边
- 排成队列
- 第一次 将 一度关系的人排成一队
- 每次队列出来一个人,检查他能不能借钱
- 不能将他逐出队伍,但是在队伍后面加上他的朋友(二度关系)
- 结论
- 要么找到最短路径
- 要么发现你的对象中没有符合条件的
人际关系错综复杂
你的一度关系中小王认识小陈,小张也认识小陈
那么小陈会被检索两次
这是浪费时间的(毕竟你快饿死了)
我们需要定义一个数组,标记已经被检查过的人
代码事例(从你的朋友中找出一位芒果商人)
代码图解
小结
❑ 广度优先搜索指出是否有从A到B的路径。
❑ 如果有,广度优先搜索将找出最短路径。
❑ 面临类似于寻找最短路径的问题时,可尝试使用图来建立模型,再使用广度优先搜索来解决问题。
❑ 有向图中的边为箭头,箭头的方向指定了关系的方向,例如,rama→adit表示rama欠adit钱。❑ 无向图中的边不带箭头,其中的关系是双向的,例如,ross - rachel表示“ross与rachel约会,而rachel也与ross约会”。
❑ 队列是先进先出(FIFO)的。
❑ 栈是后进先出(LIFO)的。
❑ 你需要按加入顺序检查搜索列表中的人,否则找到的就不是最短路径,因此搜索列表必须是队列。
❑ 对于检查过的人,务必不要再去检查,否则可能导致无限循环。