/*
* 基于邻接矩阵存储的图的广度优先搜索算法(BFS)
*/
#include<stdio.h>
#include<stdlib.h>
typedef int Bool;
#define FALSE 0
#define TRUE 1
//定义顶点类型
typedef char VertexType;
//定义边上权值类型
typedef int EdgeType;
//定义图中顶点数目的最大值
#define MAXVEX 30
typedef struct Graph {
//存储顶点的一维数组
VertexType vertex[MAXVEX];
//存储边信息的二维数组
EdgeType edge[MAXVEX][MAXVEX];
//图中当前的顶点数和边数
int verNum;
int edgeNum;
}Graph;
//顶点访问标志的数组
Bool visited[MAXVEX];
#define MAXSIZE 30
typedef struct {
int data[MAXSIZE];
int front;
//尾指针,若队列不为空,指向对为元素的下一个位置
int rear;
}Queue;
//初始化一个空队列
void initQueue(Queue *Q) {
Q->front = 0;
Q->rear = 0;
}
//判断队列是否为空
Bool isEmpty(Queue Q) {
return Q.front == Q.rear;
}
//往队列中插入元素elem
Bool enQueue(Queue *Q, int elem) {
if((Q->rear+1)%MAXSIZE == Q->front) {
return FALSE;
}
Q->data[Q->rear] = elem;
Q->rear = (Q->rear+1)%MAXSIZE;
return TRUE;
}
//删除队列中的队头元素
Bool deQueue(Queue *Q, int *elem) {
if(Q->front == Q->rear) {
return FALSE;
}
*elem = Q->data[Q->front];
Q->front = (Q->front+1) % MAXSIZE;
return TRUE;
}
//创建图
void createGraph(Graph *G) {
G->verNum = 6;
G->edgeNum = 8;
//建立顶点表
G->vertex[0] = 'A';
G->vertex[1] = 'B';
G->vertex[2] = 'C';
G->vertex[3] = 'D';
G->vertex[4] = 'E';
G->vertex[5] = 'F';
//初始化图
for(int i = 0; i < G->verNum; i++) {
for(int j = 0; j < G->verNum; j++) {
G->edge[i][j] = 0;
}
}
//初始化边信息
G->edge[0][2] = 1;
G->edge[0][4] = 1;
G->edge[1][2] = 1;
G->edge[1][5] = 1;
G->edge[2][0] = 1;
G->edge[2][1] = 1;
G->edge[2][3] = 1;
G->edge[2][5] = 1;
G->edge[3][2] = 1;
G->edge[3][5] = 1;
G->edge[4][0] = 1;
G->edge[4][5] = 1;
G->edge[5][1] = 1;
G->edge[5][2] = 1;
G->edge[5][3] = 1;
G->edge[5][3] = 1;
printf("该图的邻接矩阵为:\n");
for(int i = 0; i < G->verNum; i++) {
for(int j = 0; j < G->verNum; j++) {
printf("%d\t", G->edge[i][j]);
}
printf("\n");
}
}
//i为指定的开始顶点 下标
void BFSTraverse(Graph G, int i) {
//声明并初始化一个遍历顶点用的辅助队列
Queue Q;
initQueue(&Q);
//设访问标志为FALSE
for(int k = 0; k < G.verNum; k++) {
visited[k] = FALSE;
}
//如果该结点未被访问过就进行相应处理
if(!visited[i]) {
//设置当前结点访问标志
visited[i] = TRUE;
printf("%c ", G.vertex[i]);
enQueue(&Q, i);
while(!isEmpty(Q)) {
deQueue(&Q, &i);
//依次访问与该顶点有边相连的邻接顶点
for(int j = 0; j < G.verNum; j++) {
if(G.edge[i][j] == 1 && !visited[j]) {
visited[j] = TRUE;
printf("%c ", G.vertex[j]);
enQueue(&Q, j);
}
}
}
}
}
int main(void) {
Graph G;
createGraph(&G);
printf("\n广度遍历:");
BFSTraverse(G, 0);
}