首页 > 代码库 > 基础算法(三)——广度优先搜索

基础算法(三)——广度优先搜索

广度优先搜索(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 十字交叉法

基础算法(三)——广度优先搜索