本文已参与「新人创作礼」活动,一起开启掘金创作之路。
5-10 基于邻接表表示的广度优先遍历
BFS思想:
广度优先搜索——使用队列(queue)来实现,整个过程也可以看做一个倒立的树形:
1、把根节点放到队列的末尾。
2、每次从队列的头部取出一个元素,查看这个元素所有的下一级元素,把它们放到队列的末尾。并把这个元素记为它下一级元素的前驱。
3、找到所要找的元素时结束程序。 4、如果遍历整个树还没有找到,结束程序。
BFS伪代码:
BFS(需要访问的节点S)
{
定义队列
队列中加入S
S被标记访问过
当队列不为空时
取出队首的元素pos
输出pos,表示访问到pos
遍历与pos相连的节点(有边与pos相连)
如果当前节点没有被访问过
标记当前节点被访问过
加入队列
}
题目代码:
#include <stdio.h>
#include <stdlib.h>
#define MVNum 100
#define MAXQSIZE 100
int visited[MVNum];
typedef struct ArcNode{
int adjvex;
struct ArcNode *nextarc;
int info;
}ArcNode;
typedef struct VNode{
char data;
ArcNode *firstarc;
}VNode, AdjList[MVNum];
typedef struct{
AdjList vertices;
int vexnum, arcnum;
}ALGraph;
int CreateUDG(ALGraph &G);//实现细节隐藏
void BFS(ALGraph G, int v){
int Q[MAXQSIZE],f=0,r=0,u,w;//f,r表示队列队头队尾,注意这里特别声明了u,w,可能后面代码要用到
printf("%c ",G.vertices[v].data); visited[v] = 1;
Q[r++]=v;//队列存入访问的第一个节点v
while(f!=r){ //当队列不为空时(首部没有到达尾部)
u=Q[++f]; //取出队列首部节点
ArcNode *p = G.vertices[u].firstarc;
while(p != NULL){
w=p->adjvex; //定义邻接点w(题面中给出定义)
if(!visited[w]){
printf("%c ",G.vertices[w].data); visited[w] = 1; //打印并标记为1
Q[++r]=w; //把这个节点加入到队列中
}
p = p->nextarc;
}
}
}
void BFSTraverse(ALGraph G){
int v;
for(v = 0; v < G.vexnum; ++v) visited[v] = 0;
for(v = 0; v < G.vexnum; ++v)
if(!visited[v]) BFS(G, v);
}
int main(){
ALGraph G;
CreateUDG(G);
BFSTraverse(G);
return 0;
}