算法分析与设计 PAT程序填空题 图的解析2

238 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

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;
}