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

62 阅读2分钟

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

本题要求实现对图的广度优先遍历,并输出结点信息,采用邻接矩阵表示方法。

题目思路:

首先,明确邻接矩阵的概念:
邻接矩阵的逻辑结构分为两部分:V和E集合,其中,V是顶点,E是边。用一个一维数组存放图中所有顶点数据;用一个二维数组存放边(或弧)的数据,这个二维数组称为邻接矩阵。

下图展示了邻接矩阵的结构图。

image.png

其次,需要知道图的存储方式。图存储最为基本的方式主要分为两种,一种是邻接矩阵(利用二维数组实现图的存储);邻接表(利用数组+链表实现图的存储)。

题目代码:

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