昨天学校连夜组织做核酸,西安的夜晚确实挺冷的,所以今天起的有点晚了,刚刚外面还在冒着雪花,
好了,闲话不多扯,开始介绍今天的主角—图的广度搜索遍历.
关于图的存储(邻接矩阵的方法)我在上一篇博文里面已经有介绍了.大家没有看的可以看看我的上一篇博文.
首先说一下他的原理吧:
基本思想:
从图的某个顶点V0出发,首先访问V0.
依次访问V0各个未被访问的邻接点.
分别从这些邻接点出发,依次访问他们的各个未被访问的邻接点.访问时应该保证:如果Vi和Vk为当前端结点,且Vi和Vk在之前未被访问,则Vi的所有未被访问的邻接点应在Vk所有未被访问的邻接点之前访问.重复
上述过程,直到所有端结点均没有未被访问过的邻接点为止.
注意:每个顶点设置一个标志用于检查是否访问过,
即设置数组visited[n],visited[i]=0 未访问
visited[i]=1 已访问
需要辅助队列Q,以便实现访问时应保证的一点.
1.访问出发点V0并置访问标志,然后将V0入队.
2.只要队不空,则重复下述处理.
a.队头结点V出队;
b.对V的所有邻接点W,如果W未被访问,则访问W并置访问标志,然后w入队.
我推荐大家看一下西安邮电大学的慕课,里面王春梅老师讲这个讲的很清楚.
那么了解了思路以后就直接上代码吧.
所以首先定义队列的结
typedef struct Squeue{
int data[MAXSIZE];//队列内元素的最大长度
int front;//队头
int rear;//队尾
}Squeue;
相较于深度遍历,广度遍历较难实现.我们需要借助队列实现.
//初始化队列
void InitQueue(Squeue *Q)
{
Q->front = Q->rear = 0;
}
//判断队列是否为空
int isQueueEmpty(Squeue *qu)
{
if(qu->front == qu->rear)
{
return 1;
}
else
{
return 0;
}
}
//元素入队操作
int EnQueue(Squeue *qu,int x)
{
if((qu->rear + 1) % MAXSIZE == qu->front)
{
return 0;
}
qu->rear = (qu->rear + 1) % MAXSIZE;
qu->data[qu->rear] = x;
return 1;
}
下面呢是完整代码:
#include#include #define MAX 100 //定义最大数 #define INFINITY 0//定义无穷大 #define MAXSIZE 20 //定义队列元素的最大长度 typedef struct { char vexs[MAX];//存储顶点信息 int arc[MAX][MAX];//存储边信息 int numVertexes;//定义顶点数 int numEdges;//定义边数 int type; //定义图的类型 }MGraph; typedef struct Squeue{ int data[MAX];//队列内元素的最大长度 int font;//队头指针 int rear;//队尾指针 }Squeue; void InitQueue(Squeue * Q)//初始化队列 { Q->font = Q->rear = 0; } int Empty(Squeue * Q)//判队空 { if(Q->font == Q->rear) { return 1; } else { return 0; } } int InQueue(Squeue * Q,int v)//入队函数 { if((Q->rear+1)%MAXSIZE == Q->font ) { return 0; } Q->rear = (Q->rear+1)%MAXSIZE; Q->data[Q->rear] = v;//对元素入队 return 1; } int deleQueue( Squeue * Q,int *v)//出队函数 { if(Q->font == Q->rear)//如果队空则无法出队 { return 0; } Q->font = (Q->font+1)%MAXSIZE; *v = Q->data[Q->font]; return 1; } void Create(MGraph * G) { int i,j,k,w; printf("请输入图的顶点数和边数"); scanf("%d %d",&(G->numVertexes),&(G->numEdges)); fflush(stdin); for(i=0;i numVertexes;++i) { printf("请输入No.%d个顶点: ",i+1); scanf("%c",&G->vexs[i]); getchar(); } for(i=0;i numVertexes;++i) { for(j=0;j numVertexes;++j) { G->arc[i][j]=INFINITY; } } for(k=0;k numEdges;++k) { printf("输入边(Vi,Vj)的上下标i,j和权w(空格隔开):"); scanf("%d %d %d",&i,&j,&w); G->arc[i][j]=w; // if(G->type==0) // { // G->arc[j][i]=G->arc[i][j]; // } } } void BFS(MGraph * G) { int i,f,r; int w,v; int visited[G->numVertexes]; Squeue Q; InitQueue(&Q);//初始化队列 for(i=0;i numVertexes;++i) { visited[i]=0;//初始化标记数列 } for(v=0;v numVertexes;++v) { if(!visited[v]) { visited[v]=1;//已经访问,则标记为1 printf("%c->",G->vexs[v]); InQueue( &Q, v); while(!Empty(&Q)) { int u; deleQueue( &Q, &u); for(i=0;i numVertexes;++i) { if(G->arc[u][i]&&visited[i]==0) { visited[i]=1; printf("%c->",G->vexs[i]); InQueue(&Q,G->vexs[i]); } } } } } } void Output(MGraph * G) { int i,j,count=0; for(i=0;i numVertexes;++i) { printf("t%c",G->vexs[i]); } printf("n"); for(i=0;i numVertexes;++i) { printf("%4c",G->vexs[i]); for(j=0;j numVertexes;++j) { printf("t%d",G->arc[i][j]); count++; if(count%G->numVertexes==0) { printf("n"); } } } } int main() { MGraph G; Create(&G); BFS(&G); printf("n输入的邻接矩阵如下:n"); Output( &G); }
好了,今天这个任务完成了,感谢大家观看,
希望有不对的地方大家可以指出,一起进步.



