小朋友们好,大朋友们好!
我是猫妹,一名爱上Python编程的小学生。
和猫妹学Python,一起趣味学编程。
今日主题
咱们之前分别学习了图的基本概念,和图的深度优先遍历算法dfs。
你学会了吗?
咱们今天要学习图的另一种遍历方法:
广度优先遍历
广度优先遍历
广度优先遍历(Breadth First Search)是一种图的遍历算法,它从一个顶点出发,沿着与该顶点相邻的所有边进行遍历,直到无法继续为止。
然后再回溯到上一个顶点,沿着与该顶点不相邻的其他边进行遍历,直到无法继续为止。
重复这个过程,直到所有顶点都被访问过为止。
深度优先和广度优先
分别对下图进行深度优先遍历和广度优先遍历
深度优先搜索(Depth First Search)
先选择一条路一直往前走,走到尽头后,就返回到上一个交叉路口选择另一条没走过的路。
一直重复,这样就能走完所有的地点。
像不像老鼠走迷宫,一条路一条路地尝试?
深度优先搜索的一种实现:
广度优先搜索(Breadth First Search)
从顶点开始,先访问距离起始顶点长度为1的顶点,再访问距离起始顶点长度为2的顶点。
如此反复。
广度优先搜索的一种实现:
广度优先代码实现
假设从0开始,实现上图的广度优先遍历。
首先访问距离顶点0长度为1的结点{1,2,3}
然后访问距离顶点0长度为2的顶点{4,6},
然后访问长度为3的顶点{5},
最后访问长度为4的顶点{7}。
具体该怎么实现呢?
这里需要用到一个双端队列。
双端队列
双端队列(Deque)是一种允许我们同时从前端和后端添加和删除元素的特殊队列,它是队列和栈的结合体。
相对于普通队列,双端队列的入队和出队操作在两端都可进行。
双端队列初始状态为{0}。
我们访问0后,0从队首出队,同时用集合记录0已经被访问。将0的邻接顶点{1,2,3}从对尾入队,这都是距离起始顶点长度为1的节点。
然后1从队首出队,同时用集合记录1已经被访问。将1的邻接顶点从对尾入队,这都是距离起始顶点长度为2的节点。(也可能是2或3,看123入队的顺序)。
依次访问2和3,并用集合记录以访问,其邻接顶点分别从队尾入队。
如上反复,知道双端队列为空。
参考代码:
1行:deque 是Python标准库 collections 中的一个类,实现了两端都可以操作的队列,相当于双端队列,与Python的基本数据类型列表很相似。
15行:将起始顶点的邻接顶点添加到队列中。
16行:将起始顶点放入以访问过的结合中。
17行:如果队列非空,则继续访问。
18行:从队首弹出元素,进行访问。
20~23行:判断出队元素的邻接顶点没有被访问,放入队列尾部。
你学会了吗?
好了,我们今天就学到这里吧!
如果遇到什么问题,咱们多多交流,共同解决。
我是猫妹,咱们下次见!