图的邻接矩阵:
一、广度优先
![](https://i-blog.csdnimg.cn/blog_migrate/26619ed39a643c6e9d62d5e258a9ca8a.jpeg)
bool IsEdge(MGraph Graph,Vertex V,Vertex W)
{
return Graph->G[V][W]<INFINITY?true:false;
}
void Visit(Vertex V)
{
printf("正在访问顶点%d\n",V);
}
void BFS(MGraph Graph,Vertex S,void (*Visit)(Vertex))
{
//以S为出发点对邻接矩阵存储的图进行广度优先
Queue Q;
Vertex V,W;
Q=CreateQueue(MaxVertexNum);
Visit(S);
AddQ(Q,S);
while(!IsEmpty(Q)){
V=DeleteQ(Q);
for(W=1;W<Graph->Nv ;W++)//访问图中的每一个顶点W
//如果W是V的邻接点并且未访问过
if(!Visited[W]&&IsEdge(Graph,V,W)){
//访问顶点W
Visit(W);
Visited[W]=true;
AddQ(Q,W); //W入队
}
}
}
二、完整代码
//邻接矩阵存储的有向图
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MaxVertexNum 100 //最大顶点数
#define INFINITY 65535 //∞设为双字节无符号整型的最大值65535
bool Visited[100]={false};
typedef int Vertex; //用顶点下标表示顶点,为整型
typedef int WeightType; //边的权值设为整型
typedef char DataType; //顶点存储的数据类型为字符型
/*-----------图的定义-------------*/
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv;//顶点数
int Ne; //边数
WeightType G[MaxVertexNum][MaxVertexNum]; //邻接矩阵
DataType Data[MaxVertexNum];//存顶点的数据
};
typedef PtrToGNode MGraph; //以邻接矩阵存储的图的类型
/*-----------边的定义-------------*/
typedef struct ENode *PtrToENode;
struct ENode{
Vertex V1,V2;//有向边<V1,V2>
WeightType Weight; //权值
};
typedef PtrToENode Edge;
/*-----------创建-------------*/
MGraph CreateGraph(int VertexNum)
{//创建一个包含全部顶点的无边图
Vertex V,W;
MGraph Graph;
Graph=(MGraph)malloc(sizeof(struct GNode));
Graph->Nv =VertexNum;
Graph->Ne =0;
//初始化邻接矩阵
//顶点编号从0-Graph->Nv-1
for(V=0;V<Graph->Nv;V++)
for(W=0;W<Graph->Nv;W++)
Graph->G[V][W]=INFINITY;//都为∞
// PrintResult(Graph);
return Graph;
}
/*-----------插入-------------*/
void InsertEdge(MGraph Graph,Edge E)
{//逐条插入边
//插入边<V1,V2>
Graph->G [E->V1 ][E->V2 ]=E->Weight ;
//若是无向图,还需要插入边<V2,V1>
Graph->G [E->V2 ][E->V1 ]=E->Weight ;
}
/*-----------读入数据创建图-------------*/
MGraph BuildGraph()
{
MGraph Graph;
Edge E;
Vertex V;
int Nv,i;
printf("请输入图的顶点数:");
scanf("%d",&Nv);
Graph=CreateGraph(Nv);//初始化有Nv个顶点但没有边的图
printf("请输入边的个数:");
scanf("%d",&(Graph->Ne));
if(Graph->Ne !=0){//有边
//插入边的起点,终点,权值
printf("请输入%d个边的起点 终点 权值:\n",Graph->Ne );
E=(Edge)malloc(sizeof(struct ENode));//开辟空间
for(i=0;i<Graph->Ne ;i++){
printf("第%d条:",i+1);
scanf("%d %d %d",&E->V1,&E->V2 ,&E->Weight );
InsertEdge(Graph,E);
}
}
//如果顶点有数据的话,读入数据
//for(V=0;V<Graph->Nv ;V++)
// scanf("%c",&(Graph->Data[V]));
return Graph;
}
/*-----------队列-------------*/
typedef int Position;
typedef int ElementType;
typedef struct QNode *PtrToQNode;
struct QNode{
ElementType *Data;//存储元素的数组
Position Front,Rear;//队列的头、尾
int MaxSize;//队列最大容量
};
typedef PtrToQNode Queue;
//1.创建
Queue CreateQueue(int MaxSize)
{
Queue Q=(Queue)malloc(sizeof(struct QNode));
Q->Data =(ElementType *)malloc(MaxSize*sizeof(ElementType));
Q->Front =Q->Rear =0;
Q->MaxSize =MaxSize;
return Q;
}
//2.插入
bool IsFull(Queue Q)
{
return ((Q->Rear +1 )%Q->MaxSize ==Q->Front );
}
bool AddQ(Queue Q,ElementType X)
{
if(IsFull(Q)){
printf("队列满\n");
return false;
}else {
Q->Rear =(Q->Rear +1)%Q->MaxSize ;//队尾向后移一个位置
Q->Data [Q->Rear ]=X;
return true;
}
}
//3.删除
bool IsEmpty(Queue Q)
{
return (Q->Front ==Q->Rear);
}
#define ERROR -1//ERROR为队列不可能取到的值
ElementType DeleteQ(Queue Q)
{
if(IsEmpty(Q)){
printf("队列空\n");
return ERROR;
}else {
Q->Front =(Q->Front +1)%Q->MaxSize ;//头向后移一个位置
return Q->Data [Q->Front ];
}
}
/*-----------广度优先算法-------------*/
bool IsEdge(MGraph Graph,Vertex V,Vertex W)
{
return Graph->G[V][W]<INFINITY?true:false;
}
void Visit(Vertex V)
{
printf("正在访问顶点%d\n",V);
}
void BFS(MGraph Graph,Vertex S,void (*Visit)(Vertex))
{
//以S为出发点对邻接矩阵存储的图进行广度优先
Queue Q;
Vertex V,W;
Q=CreateQueue(MaxVertexNum);
Visit(S);
AddQ(Q,S);
while(!IsEmpty(Q)){
V=DeleteQ(Q);
for(W=1;W<Graph->Nv ;W++)//访问图中的每一个顶点W
//如果W是V的邻接点并且未访问过
if(!Visited[W]&&IsEdge(Graph,V,W)){
//访问顶点W
Visit(W);
Visited[W]=true;
AddQ(Q,W); //W入队
}
}
}
void PrintResult(MGraph Graph)
{
int V,W;
for(V=0;V<Graph->Nv ;V++){
for(W=0;W<Graph->Nv ;W++){
if(Graph->G[V][W]==INFINITY)printf("∞ ");
else printf("%d ",Graph->G[V][W]);
}
printf("\n");
}
}
int main()
{
MGraph Graph;
Graph=BuildGraph();
//BFS
BFS(Graph,0,Visit);
PrintResult(Graph);
return 0;
}
三、运行
![](https://i-blog.csdnimg.cn/blog_migrate/e345defc00e5ac50db52b15626c4f09d.png)