广度优先搜索算法

14人阅读 评论(0) 收藏 举报
分类:

广度优先搜索的概念

 广度优先搜索(BFS)类似于二叉树的层序遍历算法,它的基本思想是:首先访问起始顶点v,然后由v出发,依次访问v的各个未被访问过的邻接顶点w1,w2,w3….wn,然后再依次访问w1,w2,…,wi的所有未被访问过的邻接顶点,再从这些访问过的顶点出发,再访问它们所有未被访问过的邻接顶点….以此类推,直到途中所有的顶点都被访问过为止。类似的想法还将应用与Dijkstra单源最短路径算法和Prim最小生成树算法。(这个过程我觉得可以举个这样的例子来理解:比如要从你开始介绍你的家人,可以先从你开始,然后一个一个介绍和你有直接血缘关系的这一层亲属(爸爸妈妈儿子女儿),当把你所有的这些第一层亲属全都遍历完之后再从你的妈妈开始遍历(也可以从爸爸或儿子),把你妈妈的有直接血缘关系的亲戚先遍历一遍,然后再从爸爸开始,以此类推,直到全部都遍历完成)。 
 广度优先搜索是一种分层的查找过程,每向前走一步可能访问一批顶点,不像深度优先搜索那样有回退的情况(另一篇博客会介绍),因此它不是一个递归的算法,为了实现逐层的访问,算法必须借助一个辅助队列并且以非递归的形式来实现。

算法伪代码

其伪代码如下: 
 

bool visited[MAX_VERTEX_NUM];//访问数组,也就是顶点个数

void BFSTraverse(Graph G)
//外层的函数,为准备实现遍历做一些准备工作。
{
 for(int i=0;i<G.vexnum;++i)
     visited[i]=false;//先将所有的顶点都设置为没有被访问过
  InitQueue(Q);//初始化辅助队列方便遍历顶点
  for(int i=0;i<G.vexnum;++i)
      if(!visited[i])
           BFS(G,i);
//外层循环使用if语句来调用BFS的原因是为了防止有的顶点它不能从初始顶点出发而遍历到,所以这里需要一个完全的循环来避免这种极端情况。
}

void BFS(Graph G,int v)
//从顶点v出发,广度优先遍历图G,算法借助了一个辅助队列Q
 visit(v);//visit函数访问这个顶点的信息
 visited[v]=true;//访问过了这个顶点之后就将这个顶点设置为已访问,即true
 Enqueue(Q,v);//将顶点v入队列,这样就可以从队列中出队并访问它的相邻顶点
 while(!isEmpty(Q)){
    DeQueue(Q,v);//将队头的元素出队列存储在v
    for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w))//这一步是检查v的所有邻接顶点
    if(!visited[w]){
    visit(w);
    visited[w]=true;
    EnQueue(Q,w);
    //如果w没有被访问过,那么访问这个顶点,并把它入队
    }
}

实例以及解析

广度优先搜索算法 
  假设从a顶点开始访问,a先入队。此时队列非空,取出队头元素a,由于b,c和a直接相邻且未被访问过,于是依次访问b,c,并且b,c依次入队。队列非空,取出队头元素b,依次访问与b相邻且未被访问的顶点d,e,并且将d,e入队(注意:a与b也邻接,但是a已经访问过,就不会再访问了)。此时队列非空,取出队头元素c,访问与c邻接且未被访问过的顶点f,g,并且将f,g入队。此时,取出队头元素d,但与d邻接且为被访问的顶点为空,故不再进行任何操作,继续取出对头元素e,将h入队….当最后取出队头元素h后,队列为空,从而循环自动跳出,遍历的结果为abcdefgh。

BFS算法性能分析

  无论是邻接表还是邻接矩阵的存储访问,BFS算法都需要借助一个辅助队列Q,n个顶点都需要入队依次,在最坏的情况下,空间复杂度为O(|V|)。 
  当采用邻接表存储方式时,每个顶点均需要搜索依次(或入队依次),故时间复杂度为O(|V|),再搜索任一顶点时,每条边至少访问依次,故时间复杂度为O(|E|),算法的总时间复杂度为O(|V|+|E|);当采用邻接矩阵存储方式的时候,查找每个顶点的邻接点所需时间为O(|V|),故算法总的时间复杂度为O(|V|²)

BFS算法求单源最短路径问题

  如果图G=(V,E)为非带权图。定义从顶点u到顶点v的最短路径d(u,v)为从u到v的任何路径中最少的边数;如果从u到v没有通路,则d(u,v)=∞。 
  使用BFS,我们可以求解一个满足上述定义的非带权图的单源最短路径问题,这是由广度优先搜索总是按照距离由近到远来遍历图中每个顶点的性质决定的(这让我想到:在2d游戏中计算两个位置的最短路径是否可以采用BFS算法来求出呢?) 
  BFS算法求解单源最短路径问题的算法如下: 
 

void BFS_MIN_Distance(Graph G,int u){
//d[i]表示从u到i结点的最短路径
    for(i=0;i<G.vexnum;++i)
        d[i]=∞; //初始化路径长度
    visited[u]=true;
    d[u]=0;
    while(!isEmpty(Q)){
    DeQueue(Q,u);
    for(w=FirstNeighbor(G,u);w>=0;w=NextNeighbor(G,u,w))
    if(!visited[w]){//w为u未曾访问的邻接顶点
    visited[w]=true;//设为已经访问
    d[w]=d[u]+1;//路径长度+1
    EnQueque(Q,w);//w顶点入队
    }

    }
}

查看评论

广度优先搜索算法(BFS)

使用计算机求解的问题中,有许多问题是无法用数学公式进行计算推导采用模拟方法来找出答案的。这样的问题往往需要我们根据问题所给定的一些条件,在问题的所有可能解中用某种方式找出问题的解来,这就是所谓的搜索法...
  • kofandlizi
  • kofandlizi
  • 2011-05-15 12:44:00
  • 13689

基本图算法之广度优先搜索

广度优先搜索是最简单的图搜索算法之一,输入是图G=(V,E)和一个给定的源结点s。输出是一颗广度优先搜索树,该树以s为根结点,包含所有从s可以到达的节点。既可以适用于无向图,也适用于有向图广度优先搜索...
  • lucky_yang_
  • lucky_yang_
  • 2016-01-03 00:08:29
  • 675

图的搜索算法之广度优先搜索

图的邻接表表示 对图(有向或无向)G=(为方便记,假定V=1,2,…,n)G=(为方便记,假定V={1, 2, …, n}),其邻接表表示是一个由|V|个链表组成数组,对每个u∈Vu ∈ V,链表Ad...
  • u010177286
  • u010177286
  • 2015-07-10 16:32:03
  • 1023

广度优先搜索算法(BFS,Broad First Search)的PHP实现

2、 广度优先搜索的算法思想 广度优先搜索遍历类似于树的按层次遍历。 对于无向连通图,广度优先搜索是从图的某个顶点v0出发,在访问v0之后,依次搜索访问v0的各个未被访问过的邻接点w1,w...
  • baidu_22502417
  • baidu_22502417
  • 2014-10-28 01:09:16
  • 1245

广度优先遍历树的matlab算法实现

  • 2013年06月11日 13:34
  • 1KB
  • 下载

图算法(二)—深入理解广度优先搜索

@author : 罗正 @date time:2016年9月18日 上午9:20:34 无向图API,深度优先搜索参照上一篇文章 深度优先搜索 本文主要解析广度优先搜索广度优先搜索基于邻接表...
  • luoz_java
  • luoz_java
  • 2016-09-18 13:01:58
  • 1180

(算法入门)基本图论-广度优先搜索之JAVA实现

广度优先算法是最简单的图搜索算法之一,也是许多重要的图算法的原形,从PRIM到Dijkstra都使用了类似于广度优先算法的思想。 其思想如下: 已知图G=(V,E)和一个源顶点s,广度优先搜索以一...
  • tumaolin94
  • tumaolin94
  • 2015-07-18 15:34:37
  • 910

图的遍历之深度优先搜索算法&&广度优先优先算法的实现

一.序 和树的遍历类似,我们希望从图中的某一个顶点出发访问图中其余顶点,保证每个顶点只被访问一次,这一过程叫做图的遍历。图的遍历算法是求解图的连通性问题(最小生成树),拓扑排序,求关键路径的基础。 ...
  • derkampf
  • derkampf
  • 2017-02-28 19:47:22
  • 1468

双向广度优先搜索算法框架

双向广度优先搜索算法是对广度优先算法的一种扩展。广度优先算法从起始节点以广度优先的顺序不断扩展, 直到遇到目的节点;而双向广度优先算法从两个方向以广度优先的顺序同时扩展,一个是从起始节点开始扩展,另...
  • thudaliangrx
  • thudaliangrx
  • 2016-02-13 14:55:19
  • 3074

图的深度优先和广度优先搜索算法

图的深度优先和广度优先搜索算法     1.图的深度优先搜索算法:        图的深度优先搜索算法的基本思想是:从图G的某个顶点V0出发,访问V0,然后选择一个与V0相邻且未被访问过的顶点V...
  • wp1603710463
  • wp1603710463
  • 2016-03-13 16:21:33
  • 2524
    个人资料
    持之以恒
    等级:
    访问量: 6339
    积分: 1729
    排名: 2万+
    文章存档
    最新评论