图的广度优先遍历BFS实现--邻接矩阵p143

源程序:

#include <stdio.h>   

#include <stdlib.h>  

#define MAXSIZE 9 /* 存储空间初始分配量 */

const int vnum = 20;

typedef struct gp

{

char vexs[vnum]; /* 顶点表 */

int arc[vnum][vnum];/* 邻接矩阵,可看作边表 */

int vexnum, arcnum; /* 图中当前的顶点数和边数 */

}Graph;

/* 循环队列的顺序存储结构 */

typedef struct

{

int data[MAXSIZE];

int front;    /* 头指针 */

int rear; /* 尾指针,若队列不空,指向队列尾元素的下一个位置 */

}Queue;

/* 初始化一个空队列Q */

int InitQueue(Queue *Q)

{

Q->front = 0;

Q->rear = 0;

return  1;

}

/* 若队列Q为空队列,则返回TRUE,否则返回FALSE */

int QueueEmpty(Queue Q)

{

if (Q.front == Q.rear) /* 队列空的标志 */

return 1;

else

return 0;

}

/* 若队列未满,则插入元素e为Q新的队尾元素 */

int EnQueue(Queue *Q, int e)

{

if ((Q->rear + 1) % MAXSIZE == Q->front) /* 队列满的判断 */

return 0;

Q->data[Q->rear] = e; /* 将元素e赋值给队尾 */

Q->rear = (Q->rear + 1) % MAXSIZE;/* rear指针向后移一位置, */

  /* 若到最后则转到数组头部 */

return  1;

}

/* 若队列不空,则删除Q中队头元素,用e返回其值 */

int OutQueue(Queue *Q, int *e)

{

if (Q->front == Q->rear) /* 队列空的判断 */

return 0;

*e = Q->data[Q->front]; /* 将队头元素赋值给e */

Q->front = (Q->front + 1) % MAXSIZE; /* front指针向后移一位置, */

/* 若到最后则转到数组头部 */

return  1;

}

void CreateGraph(Graph *G)

{

int i, j;

G->arcnum = 6;

G->vexnum = 5;

/* 读入顶点信息,建立顶点表 */

G->vexs[0] = 'A';

G->vexs[1] = 'B';

G->vexs[2] = 'C';

G->vexs[3] = 'D';

G->vexs[4] = 'E';

//G->vexs[5] = 'F';

//G->vexs[6] = 'G';

//G->vexs[7] = 'H';

//G->vexs[8] = 'I';

for (i = 0; i < G->vexnum; i++)/* 初始化图 */

{

for (j = 0; j < G->vexnum; j++)

{

G->arc[i][j] = 0;

}

}

G->arc[0][1] = 1;

G->arc[0][3] = 1;

G->arc[0][4] = 1;

G->arc[1][0] = 1;

G->arc[1][2] = 1;

G->arc[2][1] = 1;

G->arc[2][3] = 1;

G->arc[2][4] = 1;

G->arc[3][0] = 1;

G->arc[3][2] = 1;

G->arc[4][0] = 1;

G->arc[4][2] = 1;

for (i = 0; i < G->vexnum; i++)

{

for (j = i; j < G->vexnum; j++)

{

G->arc[j][i] = G->arc[i][j];

}

}

}

int visited[vnum]; /* 访问标志的数组 */

/* 邻接矩阵的广度遍历算法 */

void BFS(Graph G)

{

int i, j;

Queue Q;

for (i = 0; i < G.vexnum; i++)

visited[i] = 0;

InitQueue(&Q); /* 初始化一辅助用的队列 */

for (i = 0; i < G.vexnum; i++)  /* 如果是连通图则只有一次循环,因为一次循环下来后visit都为TRUE*/

{

if (!visited[i]) /* 若是未访问过就处理 */

{

visited[i] = 1; /* 设置当前顶点访问过 */

printf("%c ", G.vexs[i]);/* 打印顶点,也可以其它操作 */

EnQueue(&Q, i); /* 将此顶点入队列 */

while (!QueueEmpty(Q)) /* 若当前队列不为空 */

{

OutQueue(&Q, &i); /* 将队对元素出队列,赋值给i */

for (j = 0; j<G.vexnum; j++)

{

/* 判断其它顶点若与当前顶点存在边且未访问过  */

if (G.arc[i][j] == 1 && !visited[j])

{

visited[j] = 1; /* 将找到的此顶点标记为已访问 */

printf("%c ", G.vexs[j]); /* 打印顶点 */

EnQueue(&Q, j); /* 将找到的此顶点入队列  */

}

}

}

}

}

}

int main(void)

{

Graph g;

Graph *pg = &g;

CreateGraph(pg);

//printf(" 深度遍历:");

//DFSTraverse(G);

printf(" 广度遍历:");

BFS(g);

system("pause");

return 0;

}

 运行结果:

原文地址:https://www.cnblogs.com/duanqibo/p/12010441.html