本文已参与「新人创作礼」活动,一起开启掘金创作之路。
本题要求实现对图的广度优先遍历,并输出结点信息,采用邻接矩阵表示方法。
题目思路:
首先,明确邻接矩阵的概念:
邻接矩阵的逻辑结构分为两部分:V和E集合,其中,V是顶点,E是边。用一个一维数组存放图中所有顶点数据;用一个二维数组存放边(或弧)的数据,这个二维数组称为邻接矩阵。
下图展示了邻接矩阵的结构图。
其次,需要知道图的存储方式。图存储最为基本的方式主要分为两种,一种是邻接矩阵(利用二维数组实现图的存储);邻接表(利用数组+链表实现图的存储)。
题目代码:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>//使用INT_MAX宏,指定整数变量不能存储超出此限制的任何值
typedef int DataType;
struct Node
{
DataType data;
struct Node *link;
};
typedef struct Node *PNode;
struct Queue
{
PNode f;
PNode r;
};
typedef struct Queue *LinkQueue;
LinkQueue SetNullQueue_Link(); //创建一个空队列,略
int IsNullQueue_Link(LinkQueue lqueue); //判断队列是否为空,略
void EnQueue_link(LinkQueue lqueue, DataType x); //x入队,略
void DeQueue_link(LinkQueue lqueue); //队首元素出队,略
DataType FrontQueue_link(LinkQueue lqueue); //打印队头元素,略
typedef struct GRAPHMATRIX_STRU
{
int size; // 图中结点的个数
int **graph; //二维数组保存图
}GraphMatrix;
GraphMatrix* InitGraph(int num); //创建图,略
void ReadGraph(GraphMatrix* graphMatrix); //输入顶点和权值,略
/*从结点i开始广度优先遍历 */
void BFS(GraphMatrix* graphMatrix, int * visited, int i)
{
int j;
int tempVex;
LinkQueue waitingQueue = NULL;
waitingQueue = SetNullQueue_Link();
if (!visited[i])
{
visited[i] = 1;
printf("%d ", i);
EnQueue_link(waitingQueue, i);
while (!IsNullQueue_Link(waitingQueue))
{
tempVex = FrontQueue_link(waitingQueue);
DeQueue_link(waitingQueue);
for (j = 0; j<graphMatrix->size; j++)
{
if (graphMatrix->graph[tempVex][j] != INT_MAX && !visited[j])//与i相连且没有访问过的
{
visited[j]=1; //标记被访问
EnQueue_link(waitingQueue, j); //被访问的结点j入队
printf("%d ", j); //打印与i相连的结点j
}
}
}
}
}
void BFSGraphMatrix(GraphMatrix* graphMatrix)
{
int i;
int *visited = (int*)malloc(sizeof(int)* graphMatrix->size);
for (i = 0; i < graphMatrix->size; i++) //设置所有结点都没有被访问,其中1为访问过,0为没有被访问
visited[i] = 0;
for (i = 0; i < graphMatrix->size; i++)
{
BFS(graphMatrix,visited,i); //从0号结点开始进行广度优先遍历
}
}
int main()
{
GraphMatrix *graphMatrix = NULL;
graphMatrix = InitGraph(7); //传入顶点个数7
ReadGraph(graphMatrix);
BFSGraphMatrix(graphMatrix);
return 0;
}