#include<stdio.h>
#include<stdlib.h>
//--------------------------------------以下是邻接矩阵部分------------------------------
//第一步骤,边的定义
struct Enode
{
int v1,v2;
int weight;
};
typedef struct Enode* Edge;
//第二步骤,图的定义
struct Gnode
{
int Nv,Ne;
int** GL;
//定义一个二维数组
};
typedef struct Gnode* Graph;
//第三步骤,图的初始化
Graph CreateGraph(int Nv)
{
Graph G;
G=(Graph)malloc(sizeof(struct Gnode));
G->Nv=Nv;
G->Ne=0;
//动态分配一个二维数组
G->GL=(int **)malloc(sizeof(int*)*Nv);
int i,j,k;
for(i=0;i<Nv;i++)
{
G->GL[i]=(int *)malloc(sizeof(int)*Nv);
}
for(j=0;j<Nv;j++)
{ for(k=0;k<Nv;k++)
G->GL[k][j]=0;
}
return G;
}
//第四步骤,单边插入,节点的编号从0开始并且要按总数编
void InsertGraph(Graph G,Edge E)
{
G->GL[(E->v1)][(E->v2)]=E->weight;
//如果是无向图,还需以下的步骤
G->GL[(E->v2)][(E->v1)]=E->weight;
printf("插入成功\n");
}
//第五步骤,建造一个完整的图
Graph BuildGraph(int Nv,int Ne)
{
int i;
Graph G;//--------------------这步绑在起
G=CreateGraph(Nv);//----------两是定一的
if(Ne!=0)
{
printf("正在读取边节点数据\n");
printf("请将有边存在的两个节点数据以及权重在下面一一列出,首位节点间以空格隔开:\n");
for(i=0;i<Ne;i++)
{
Edge E=(Edge)malloc(sizeof(struct Enode));
scanf("%d %d %d",&(E->v1),&(E->v2),&(E->weight));
printf("输入成功\n");
InsertGraph(G,E);
free(E);
}
}
printf("创建成功!!!\n");
return G;
}
//-----------------------------------------以上是邻接矩阵部分--------------------------
//-----------------------------------------以下是顺序队列部分--------------------------
//对一个顺序队列进行初始化
typedef struct Qnode
{
int *Data;
int Front,Rear;
int Max;
} *Queue;
//创建一个空队列
Queue CreateQueue(int max)
{
Queue q=(Queue)malloc(sizeof(struct Qnode));
q->Data=(int *)malloc(sizeof(int));
q->Front=q->Rear=0;
q->Max=max;
return q;
}
//判断这个队列是否是满的
bool isFull(Queue q)
{
if((q->Rear+1)%q->Max==q->Front)
{
printf("本队列已经满了,请先进行出队操作\n");
return true;
}
else
{
printf("队列未满\n");
return false;
}
}
//判断这个队列是否为空
bool isEmpty(Queue q)
{
if(q->Front==q->Rear)
{
printf("本队列为空\n");
return true;
}
else
{
printf("本队列非空,里面有元素\n");
return false;
}
}
//入队
void AddQueue(Queue q,int x)
{
if(isFull(q))
{
printf("入队失败\n");
}
else
{
//这一步主要是为了当他走到数组最后一格的时候可以回到第一格
q->Rear=(q->Rear+1)%q->Max;
q->Data[q->Rear]=x;
printf("入队成功\n");
}
}
//出队
int OutQueue(Queue q)
{
if(isEmpty(q))
{
printf("出队失败\n");
}
else
{
q->Front=(q->Front+1)%q->Max;
printf("出队成功\n");
//以下这一步是为了广度遍历而加上去的
printf("%d\n",q->Data[q->Front]);
return q->Data[q->Front];
}
}
//-------------------------------------------以上是顺序队列部分-----------------------------
//-------------------------------------------以下是图的广度遍历部分------------------------
bool IsEmpty(Graph G,int v,int w)
{
return G->GL[v][w]>0? true:false;
}
int *BFS(Graph G,int s)
{
int visit[100];
int i=0,Max=100;
int v,w;
for(i=0;i<G->Nv;i++)
{
visit[i]=false;
}
Queue Q;
Q=CreateQueue(Max);
visit[s]=true;
//把s入队
AddQueue(Q,s);
//当这个队列不是空的时候
while(!isEmpty(Q))
{
v=OutQueue(Q);
for(w=0;w<G->Nv;w++)//对图当中的第行的所有顶点w
{
if( !visit[w]&&IsEmpty(G,v,w) )//如果GL[v][w]没有被访问过并且是v的邻接点
{
visit[w]=true;
AddQueue(Q,w);
}
}
}
return visit;
//BFS与DFS有所不同,BFS不需要递归调用本身函数,只不过是需要递归的入队罢了;
}
//---------------------------------------------以上是图的广度遍历部分----------------------
int main()
{
int *visit;
int i,Nv,Ne,s;
printf("请输入图节点和边节点数目:\n");
scanf("%d%d",&Nv,&Ne);
Graph G;
G=BuildGraph(Nv,Ne);
printf("现在开始广度遍历,请选择您想最先访问的节点\n");
scanf("%d",&s);
visit=BFS(G,s);
for(i=0;visit[i]==true;i++)
printf("%d\n",visit[i]);
//输出几个true就等于告诉你有几个节点被遍历了
return 0;
}
图的广度优先遍历(邻接矩阵)
最新推荐文章于 2024-05-29 09:25:06 发布