首页 > 代码库 > 基础算法(三)——广度优先搜索
基础算法(三)——广度优先搜索
广度优先搜索(Breadth First Search),是很多重要的图的算法的原型。
重要的作用:遍历。对于图的遍历,一般有以下的基本思想:
①从图中某个顶点V0出发,并访问此顶点;
②从V0出发,访问V0的各个未曾访问的邻接点W1,W2,…,Wk;然后,依此从W1,W2,…,Wk
出发访问各自未被访问的邻接点。
③重复②,直到全部顶点都被访问为止。
【例】如图1-7,按照广度优先搜索的思想遍历这张图。
正确的方法应该是:
【例】编写“连连看”的简单程序
规则是:相连不超过两个弯的相同图形是可以消去的。
写这个程序的时候的基本步骤:
1. 判断是否能消去
2. 消去/不消去,提示信息
重点应用BFS的是在第一个步骤中:
①图形是否相等非常简单,只要判断该处元素的值即可;
②相连是否不超过两个弯,我们需要从中取一个结点为起始点,先拿到无须转弯就能到达的结点集合A,看目标结点是否在里面;如果不在,则需要对结点集合A中所有结点,拿到其无须转弯就能到达的结点(未在之前访问过),判断目标结点是否在内;如果不在,则继续扩展,这次如果再不在,说明两结点连接超过两个弯了,不满足。
【重点】广度优先的缺点是:有的时候耗时会很大,这时候可以使用哈希表进行优化。在此不会特别用到,故不再细述。广度优先搜索与深度有限搜索是两个相对的搜索方法。对于广度优先搜索,一般的最短路径会用到它。
Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。注意该算法要求图中不存在负权边。
【例】在无向图 G=(V,E) 中,假设每条边 E[i] 的长度为 w[i],找到由顶点 V0 到其余各点的最短路径。(单源最短路径)例如图1-8所示:
第一步:先锁定一个点,这里我用A作为初始的;
第二步:先设A到所有的点的路径的长度为无穷大,然后按照图1-9的步骤一步一步做就可以得到答案。
回顾:这里面当选定一个点的时候,就对其可连接到的点进行BFS,所以当问题可以抽象成类似于这个样子就可以进行BFS进行查找答案(最短路径)。
这是我从博客园上找到的完整的解题思路供参考:
对于以下的无向图(图1-10)进行遍历
图1-10 无向图例题
解答过程见图1-11.
图1-11 图1-10的解答过程
下面是Floyd算法。
Floyd算法是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被用于计算有向图的传递闭包。Floyd算法的时间复杂度为O(N?)(有点费时间),空间复杂度为O(N?)。
以下的例题和解题过程来自博客园:
基本解题思路:
a.从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。
b.对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比己知的路径更短。如果是更新它。
对于这种题目,我们一般使用的是十字交叉法如图1-12:
图1-12 十字交叉法
基础算法(三)——广度优先搜索