图的广度搜索(C语言版)

来源:互联网 发布:培训交互设计师知乎 编辑:程序博客网 时间:2024/05/01 11:12



图的广度搜索,明确是无向图,根据提示示例,分析下列代码:


  1.首先给出程序示例输入输出:


2.然后贡献详细代码

#include<stdio.h>#include<stdlib.h>#define MAX 100int visited[MAX]={0};//定义一个访问标志数组 typedef struct       //定义一个结构体代表顺序队列 {int front;int rear;int data[MAX];}Queue;typedef struct      //定义一个结构体代表图的邻接矩阵 {int vexs[MAX];int arcs[MAX][MAX];int vexnum,arcnum;}Graph;                   void InitQueue(Queue *q);//队列的初始化 int EmptyQueue(Queue *q);//判断队列非空 int DeQueue(Queue *q);//出队 void EnQueue(Queue *q,int data);//入队 void CreateUDN(Graph &G);//创建图的邻接矩阵 int LocateVex(Graph G,int v);//确定顶点数组的下标 void BFS(Graph G,int v);//图的广度搜索 int FirstAdjVex(Graph G,int v);//选定点的第一个临接点 int NextAdjVex(Graph G,int v,int w);//相对于第一个选定点的下一个临接点,w大于等于0代表存在临接点 main(){Graph G;//创建图G CreateUDN(G);//  对图G进行初始化,以此确定图G的结构 int i;scanf("%d",&i);//输入从哪一个点进行图的广度搜索 BFS(G,i);//对图G进行广度搜索 }void InitQueue(Queue *q) { q->front=q->rear=0;  //初始化队列,置空 }int EmptyQueue(Queue *q){if(q->rear==q->front) //若队列头位置等于队列尾位置,代表队列为空 return 1;        else       return 0;}void EnQueue(Queue *q,int data)  {  if((q->rear+1)%MAX==q->front)//若环形队列队满,退出 exit(0);q->data[q->rear]=data;//元素入队 q->rear=(q->rear+1)%MAX;//队头向前移位(这里是环形队列的创建,不多解释) }int DeQueue(Queue *q)  {  int data;if(q->front==q->rear)   //若队列为空,无法出队 return 0;data=q->data[q->front];    //队列不为空,出对尾元素,即先出先进来的元素 q->front=(q->front+1)%MAX;  //环形队列 对尾向前移位 return data;}void CreateUDN(Graph &G){scanf("%d%d",&G.vexnum,&G.arcnum);  //输入图的节点数和边数 int i,j,k;for(i=0;i<G.vexnum;i++){     //输入所有节点值 scanf("%d",&G.vexs[i]);}for(i=0;i<G.vexnum;i++)      //为图创建邻接矩阵 {for(j=0;j<G.vexnum;j++){G.arcs[i][j]=0;     //初始化邻接矩阵为0 }}for(k=0;k<G.arcnum;k++){int v1,v2,w;scanf("%d%d%d",&v1,&v2,&w);   //输入边的起始点和终点,并赋权值 i=LocateVex(G,v1);            //确定起始点在邻接矩阵中的下标表示 j=LocateVex(G,v2);            //确定终点在邻接矩阵中的下标表示 G.arcs[i][j]=w;G.arcs[j][i]=G.arcs[i][j];    //无向图对称 }}int LocateVex(Graph G,int v)      //确定某点在邻接矩阵中下标的具体方法 {int i=0;while ((v!=G.vexs[i])&&(i<G.vexnum)) i++;return i;} void BFS(Graph G,int v){printf("%d",v);      //首先输出起始遍历的点 visited[v]=1;        //对起始点进行标记,表示已经访问过v点,以后不用再次访问 int w;int u;Queue Q;             //创建队列Q,用来对已访问点做标记 InitQueue(&Q);       //初始化队列 EnQueue(&Q,v);       //元素v入队 while(!EmptyQueue(&Q))   //队列不为空,执行while循环 {u=DeQueue(&Q);       //元素出队 for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w))//依次检查u的所有临接点(按程序往下看,可以读懂,不多解释) {if(!visited[w]) //若没有访问过此点,即此点数组值为0,进行打印输出 {printf("%d",w);      //打印第一次访问的点 visited[w]=1;        //对访问的这个点做标记,对数组值赋一,表示已经遍历此点 EnQueue(&Q,w);       //将访问的此点入队 ,进入下次循环,找此点另外没有访问过的临接点 }}}}int FirstAdjVex(Graph G,int v)        //自己按示例数据分析此方法,不多解释 {int i=0;while((i<G.vexnum)&&(G.arcs[v][i]==0)) i++;if (i==G.vexnum) return -1;else return i;}int NextAdjVex(Graph G,int v,int w)    {int i=0;for(i=w+1;(i<G.vexnum)&&((G.arcs[v][i]==0));i++)   //这里循环找临接点,循环内部不需要执行任何代码,和上边找第一个点中的while类似 {}if (i==G.vexnum) return -1;else return i;}



原创粉丝点击