数据结构之BFS(邻接表版)

来源:互联网 发布:php 中英文企业网站 编辑:程序博客网 时间:2024/05/22 05:34

最近效率有点低下唉,估计是蜷缩在宿舍的原因,下午跑大教室来了。果然还是大环境好,空气清新,也可能是最近晚上打球运动还没有适应过来,亦或者是还没有习惯于早起。不过习惯的养成是不急于一时的,还得 慢慢来,但是,现在的首要任务是如何利用好自己的现在的每一分每一秒这才是关键啊,自打前几日重新整理下自己的资源,计算了一下假期时间,最后发现,任重而道远。能够做的就是压缩压缩再压缩了。

上节说到图的深度优先搜索类似于树的前序遍历,这是有一定道理的。这次见面的是图的广度优先搜索(Breadth-First Search),BFS 类似于树的层次遍历,是树的层次遍历的推广。

BFS

1、从图中某个顶点Vi出发,首先访问Vi。
2、依次访问Vi的各个未访问的邻接点
3、分别从这些邻接点(端节点)出发,依次访问它们的各个未访问的邻接点(新的端节点)。访问时应该保证:如果Vi和Vj为当前端节点,Vi在Vj之前访问,则Vi的所有为访问的邻接点应在Vj的所有未访问的邻接点之前访问。重复(3),直到所有端节点均没有未访问的邻接点为止。
4、若访问的是非连通图,从某个顶点出发进行BFS后,则该顶点所在的连通分量的所有顶点都将被访问。此时,若图中还有顶点未访问,则另选图中一个未访问的顶点作为起始点,重复上述广度优先搜索过程,直至图中所有顶点均访问过为止。

说白了就是以层次遍历的形式来访问图中的各个顶点,即首先访问下图中的1,然后开始是2,3,然后是4,5,接着是6,7,最后是8

这里写图片描述

PS:上述是由一个算法可视化网站生成的,算法可视化网站,这个网站还不错,推荐给大家了,哦上图的箭头如果是无向图(例如本例)可以选择忽视,若是有向图则不能忽视,当然有向图的代码也要改变一些
因为开始访问的节点可以不一样,但是若V1在V2之前访问,则V1的邻接点也将在V2 的邻接点之前访问。即2在3之前访问,那么4,5将在6,7之前被访问。

对于上述广度优先搜索算法,要记录与一个顶点想邻接的全部顶点。由于访问过这些顶点之后,还将按照先访问的顶点就要先去访问它的邻接点的方式进行广度优先搜索,因此用一个先进先出的队列来记录这些顶点。

完整代码(邻接表版)

#include<stdio.h>#include<malloc.h>#define max 100typedef struct node{    int adjvex;    struct node*next;}arcnode;typedef struct {    int vertex;    arcnode*firstarc;}vexnode;vexnode adjlist[max];int creatadjlist(){    arcnode*ptr;    int arcnum,vexnum,k,v1,v2;    printf("input the vexnum,arcnum:");    scanf("%d,%d",&vexnum,&arcnum);    for(k=1;k<=vexnum;k++)    adjlist[k].firstarc=0;    for(k=0;k<arcnum;k++)    {        printf("v1,v2=");scanf("%d,%d",&v1,&v2);        ptr=(arcnode*)malloc(sizeof(arcnode));        ptr->adjvex=v2;        ptr->next=adjlist[v1].firstarc;        adjlist[v1].firstarc=ptr;        ptr=(arcnode*)malloc(sizeof(arcnode));        ptr->adjvex=v1;        ptr->next=adjlist[v2].firstarc;        adjlist[v2].firstarc=ptr;    }    return vexnum;}void bfs(int *v){    int queue[max];    int front=0,rear=1;    arcnode*p;    p=adjlist[*v].firstarc;    printf("%d ",*v);    adjlist[*v].vertex=1;    queue[rear]=*v;    while(front!=rear)    {        front=(front+1)%max;        *v=queue[front];        p=adjlist[*v].firstarc;        while(p!=NULL)        {            if(adjlist[p->adjvex].vertex==0)            {                adjlist[p->adjvex].vertex=1;                printf("%d ",p->adjvex);                rear=(rear+1)%max;                queue[rear]=p->adjvex;            }            p=p->next;        }    }}int main(){    int i,n,*v;    arcnode*p;    n=creatadjlist();    printf("the Adjacency Matrix:\n");    for(i=1;i<=n;i++)    {        printf("%d==>",i);        p=adjlist[i].firstarc;        while(p!=NULL)        {            printf("---->%d",p->adjvex);            p=p->next;        }        putchar('\n');    }    printf("input the bfs's node:");    scanf("%d",v);    printf("the bfs is:");    bfs(v);    return 0;}

这里写图片描述

总结

广度优先搜索相对于深度优先搜索来说难度加大了一点点,重点就在于它多用了一个队列来存储节点信息,所有在理解上会存在一丝难度,但是理解了其内在的思想还是好办的。

原创粉丝点击