广度优先搜索——邻接矩阵
需要了解的是,图的广度搜索遍历类似于二叉树的层次遍历,用到了队的操作
代码如下
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXVEX 100
typedef int DataType; /*设置队数据类型,可修改*/
typedef int VexType;
typedef int EdgeType;
typedef struct{
DataType data[MAXVEX];
int front;
int rear;
}Queue; /*定义栈结构体*/
typedef struct{
VexType ves[MAXVEX]; /*顶点表*/
EdgeType edge[MAXVEX][MAXVEX]; /*边表*/
int v; /*结点数*/
int e; /*边数*/
}MGraph; /*邻接矩阵*/
void Ini_Queue(Queue *Q){ /*创建队*/
Q->front=Q->rear=0;
}
int In_Queue(Queue *Q,DataType e){ /*入队*/
if(Q->front!=(Q->rear+1)%MAXVEX){
Q->data[Q->rear]=e;
Q->rear=(Q->rear+1)%MAXVEX;
return OK;
}
else return FALSE;
}
int Empty_Queue(Queue Q){ /*判队空*/
if(Q.front==Q.rear) return TRUE;
else return FALSE;
}
int Out_Queue(Queue *Q,DataType *e){ /*出队*/
if(Empty_Queue(*Q)) return FALSE;
else {
*e=Q->data[Q->front];
Q->front=(Q->front+1)%MAXVEX;
}
return TRUE;
}
int Creat_MGraph(MGraph *M){ /*创建邻接矩阵*/
int i,j,k;
printf("请输入结点个数和边数(v,e):");
scanf("%d%d",&(M->v),&(M->e)); /*输入顶点数与边数*/
printf("键入结点表信息:\n");
for(i=0;i<M->v;i++) /*创建顶点表*/
scanf("%d",&(M->ves[i]));
for(i=0;i<M->v;i++)
for(j=0;j<M->v;j++)
M->edge[i][j]=0; /*初始化边表全为0*/
printf("键入边表信息(格式:i,j,范围(1-n):\n");
for(k=0;k<M->e;k++){ /*创建边表*/
scanf("%d%d",&i,&j);
M->edge[i-1][j-1]=1; /*填充edge[i][j]上的边*/
M->edge[j-1][i-1]=1; /*填充edge[i][j]上的边*/
}
return OK;
}
void Mprint(MGraph M){ //打印邻接矩阵
for(int i=0;i<M.v;i++)
{
printf("________________________________________\n");
for(int j=0;j<M.v;j++)
printf("|%-3d|",M.edge[i][j]);
printf("\n");
}
printf("________________________________________\n");
}
int visit[MAXVEX]={FALSE}; /*visit数组标记顶点访问情况*/
int BFSM(MGraph M,DataType V){ /*广度优先遍历算法*/
int i;
DataType k=V;
for(i=0;i<M.v;i++) /*将标记数组置为false*/
visit[i]=FALSE;
Queue Q;
Ini_Queue(&Q); /*初始化队*/
In_Queue(&Q,k); /*入队开始结点的序号*/
while(!Empty_Queue(Q)){
Out_Queue(&Q,&k); /*先出队一个顶点序号*/
printf("%d ",M.ves[k-1]);
visit[k-1]=TRUE; /*将已经访问的顶点标记为true*/
for(i=0;i<M.v;i++) /*将已被访问的顶点的未被访问的邻接点入队*/
if(!visit[i]&&M.edge[k-1][i]==1)
In_Queue(&Q,i+1);
}
return OK; /*当队中不在有元素,则遍历结束*/
}
测试代码
int main(){ /*测试*/
MGraph M;
DataType V;
Creat_MGraph(&M);
Mprint(M);
while(1){
printf("\n请输入一个开始结点的序号:(范围1--结点数,超过该范围退出程序):");
scanf("%d",&V);
if(V>M.v)return 0; /*大于结点数退出程序*/
BFSM(M,V);
}
return 0;
}
/*
样例输入:
5 4
1 2 3 4 5
1 3
2 3
2 5
2 4
以第三个结点开始: 3
得到 3 1 2 4 5
*/