和深搜不同,广搜在访问一个节点之后会访问这个节点周围的所有节点
然后扩散出去:
这里要用到队列,所以把先前的队列代码直接拿来就用。。。
#include<stdio.h> #include<stdlib.h> #include<string.h> #define number 20 typedef int QElemType; typedef int Status; typedef struct node { int info; //图的节点存放的信息,可随时变动 }GraphNode; typedef struct { GraphNode matrix[number+1][number+1]; //构造邻接矩阵 int vexs[number+1]; //顶点向量 int vertex,edge; //顶点个数、弧个数 }Graph; //构造队列的数据结构 typedef struct QNode { QElemType data; struct QNode *next; }QNode,*QueuePtr; typedef struct { QueuePtr front; QueuePtr rear; }LinkQueue; //队列基本操作 Status InitQueue(LinkQueue *Q); Status DestroyQueue(LinkQueue *Q); Status ClearQueue(LinkQueue *Q); Status QueueEmpty(LinkQueue *Q); Status QueueLength(LinkQueue *Q); Status GetHead(LinkQueue *Q); Status EnQueue(LinkQueue *Q,QElemType data); Status DeQueue(LinkQueue *Q); Status QueueTraverse(LinkQueue *Q); int visited[number+1]; Status InitQueue(LinkQueue *Q) { Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode)); if(! Q->front)exit(1); Q->front->next = NULL; return 1; } Status DestroyQueue(LinkQueue *Q) { while(Q->front) { Q->rear = Q->front->next; free(Q->front); Q->front = Q->rear; } return 1; } Status ClearQueue(LinkQueue *Q) { Q->front = Q->rear = NULL; return 1; } Status QueueEmpty(LinkQueue *Q) { return ((Q->front == Q->rear)? 1:0); } Status QueueLength(LinkQueue *Q) { int flag=0; QueuePtr temp = Q->front; while(temp->next) { Q->rear = temp->next; flag++; temp = Q->rear; } return flag; } Status GetHead(LinkQueue *Q) { if(Q->front == Q->rear) { printf("Queue Handle Error.\n"); exit(1); } return Q->front->next->data; } Status EnQueue(LinkQueue *Q,QElemType data) { QueuePtr tmp; tmp = (QueuePtr)malloc(sizeof(QNode)); tmp->data = data; tmp->next = NULL; Q->rear->next = tmp; Q->rear = tmp; return 1; } Status DeQueue(LinkQueue *Q) { QueuePtr temp; if (Q->front == Q->rear) { printf("error.\n"); return 0; } temp = Q->front->next; Q->front->next = temp->next; if(Q->rear == temp)Q->rear = Q->front; //如果删除的是队列最后一个元素,要将队尾指针重新赋值 free(temp); return 1; } //创建图 void CreatGraph(Graph *G) { int i,k; int x,y,data; int vertex,edge; printf("输入图的顶点个数和边的个数.\n"); scanf("%d%d",&vertex,&edge); G->vertex = vertex;G->edge = edge; printf("输入图的每个顶点.\n"); for(i=1;i<=vertex;i++) scanf("%d",&G->vexs[i]); for(i=1;i<=vertex;i++) for(k=1;k<=vertex;k++) G->matrix[i][k].info = 0; printf("请输入 %d 条边的横坐标、纵坐标、数值.\n",edge); for(i=1;i<=edge;i++) { scanf("%d%d%d",&x,&y,&data); G->matrix[x][y].info=data; G->matrix[y][x].info=data; } } //找出给定顶点的位置 int LocateVex(Graph *G,int V) { int i; for(i=1;i<=G->vertex;i++) if(G->vexs[i] == V) return i; return -1; //失败返回-1 } //将指定顶点的数值改变 void PutVex(Graph *G,int V,int value) { int temp; if((temp =LocateVex(G,V)) == -1)return; else G->vexs[temp] = value; } //向图中插入一个顶点 int InsertVex(Graph *G,int V) { int i; G->vertex++; if(G->vertex > number)return 0; G->vexs[G->vertex] = V; for(i=1;i<=G->vertex;i++) G->matrix[G->vertex][i].info = 0; for(i=1;i<G->vertex;i++) G->matrix[i][G->vertex].info = 0; return 1; } //在图中删除一个顶点 int DeleteVex(Graph *G,int V) { int i,temp,k; int count=0; if((temp=LocateVex(G,V)) == -1)return -1; //顶点数组变化 for(i=temp;i<G->vertex;i++) G->vexs[i] = G->vexs[i+1]; //顶点入度变化 for(i=1;i<=G->vertex;i++) { if(G->matrix[i][temp].info)count++; for(k=temp;k<G->vertex;k++) { G->matrix[i][k].info=G->matrix[i][k+1].info; } } //顶点出度变化 for(i=1;i<G->vertex;i++) { for(k=temp;k<G->vertex;k++) G->matrix[k][i].info = G->matrix[k+1][i].info; } G->vertex--; //顶点减一 G->edge -= count; //弧减去对应的个数 return 1; } //在图中插入一条弧 int InsertArc(Graph *G,int v,int w) { int digit; if(v<0||v> G->vertex||w<0||w>G->vertex)return -1; printf("输入弧的权值.\n"); scanf("%d",&digit); G->matrix[v][w].info = G->matrix[w][v].info = digit; return 1; } //在图中删除一条弧 int DeleteArc(Graph *G,int v,int w) { if(v<0||v> G->vertex||w<0||w>G->vertex)return -1; G->matrix[v][w].info = G->matrix[w][v].info = 0; return 1; } //打印图 void DisplayGraph(Graph *G) { int i,k; for(i=1;i<=G->vertex;i++) { for(k=1;k<=G->vertex;k++) printf("%-4d ",G->matrix[i][k].info); printf("\n"); } printf("\n"); } void RecoverGraph(Graph *G) { int i,k; for(i=1;i<=G->vertex;i++) for(k=1;k<=G->vertex;k++) G->matrix[i][k].info=0; memset(G->vexs,0,sizeof(G->vexs)); G->vertex = G->edge = 0; } //找出指定顶点在图中的第一个邻接点 int FirstAdjVex(Graph *G,int V) { int temp,i; if((temp = LocateVex(G,V))==-1) return -1; //失败返回-1 else { for(i=1;i<=G->vertex;i++) if(G->matrix[temp][i].info != 0) return i; } return -1; } int NextAdjVertex(Graph *G,int v,int w) { int temp,i; if((temp=LocateVex(G,v)) == -1)return -1; for(i=w+1;i<=G->vertex;i++) if(G->matrix[temp][i].info)return i; return -1; } void BFS(Graph *G) { int v,w; LinkQueue queue; InitQueue(&queue); //初始化队列 //构造辅助数组 for(v=1;v<=G->vertex;v++) visited[v] = 0; for(v=1;v<=G->vertex;v++) { if(!visited[v]) //顶点v尚未访问 { visited[v]=1;printf("%d ",G->vexs[v]); //访问之 EnQueue(&queue,v); //进入队列 while(QueueEmpty(&queue)!=1) { DeQueue(&queue); //寻找节点的所有邻接节点 for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVertex(G,v,w)) if(!visited[w]) { visited[w]=1;printf("%d ",G->vexs[w]); EnQueue(&queue,w); } //if }//while }//if }//for } int main() { Graph G; CreatGraph(&G); BFS(&G); RecoverGraph(&G); return 0; }