数据结构与算法 ~ 图 ~ 图的遍历 ~ 广度优先搜索
/* graph ------adjacency List */
#include<stdlib.h>
#include<stdio.h>
#define MAX 20
struct ArcNode{ /*弧结点信息*/
int adjvex; /*该弧所指向的顶点的信息*/
struct ArcNode *nextarc; /*指向下一条弧的指针*/
};
struct VexNode{
int data; /*顶点信息*/
int flag;
struct ArcNode *firstarc;/*指向第一条依附于该顶点的弧的指针*/
};
struct VexNode head[MAX]; /*顶点数组*/
int vexnum=-1;
int graphtype;
int formatlist(){
printf("\n1---创建无向图:");
printf("\n2---创建有向图:");
printf("\n0---退出");
printf("\n请输入你的选择:");
scanf("%d",&graphtype);
return graphtype;
}
void constr(struct VexNode *head,int source, int destination){
int max;
struct ArcNode *newNode,*pointer;
newNode=(struct ArcNode*)malloc(sizeof(struct ArcNode));/*分配空间*/
if (newNode==NULL){
printf("发生错误!");
exit(0);
}else{
/*生成弧结点*/
newNode->adjvex=destination;
newNode->nextarc=NULL;
if ( head[source].firstarc==NULL)/*头结点没有邻接点*/
head[source].firstarc=newNode;
else{
pointer=head[source].firstarc ;/*头结点已有邻接点*/
while ((pointer->adjvex!=destination)&&(pointer->nextarc!=NULL) )
pointer=pointer->nextarc; /*找到最后一个邻接点*/
if (pointer->adjvex==destination){
printf("\nthe input is duplicate!");
free(newNode);
}else{
pointer->nextarc=newNode;/*接入*/
/*确定顶点的最大值*/
max=(source>destination)?source:destination;
if (vexnum<max)
vexnum=max;
}/*else*/
}/*ifelse*/
}/*ifelse*/
}/*constr*/
void create_graph(struct VexNode *head){
int i,max,cost;
int source,destination;
struct ArcNode *newNode,*pointer;
for(i=1;i<MAX;++i){
head[i].data=i;
head[i].firstarc=NULL;
}
while(1){
printf("\n请输入弧的信息(起点 终点 退出输入-1):");
scanf("%d%d",&source,&destination,&cost);
if (source==-1)
break;
if (source==destination)
printf("\n起点和终点相同!");
else{
constr(head,source,destination);
if (graphtype==1)
constr(head,destination,source);
}
}/*while*/
}/*create_graph*/
void Print(struct VexNode * head){
int i,j;
struct ArcNode *pointer;
printf("\n=====当前图是=====\n");
for (i=1;i<=vexnum;++i){
printf( " head[%d]: ",i);
pointer=head[i].firstarc ;
while (pointer!=NULL){
printf("[%d]=>", pointer->adjvex);
pointer=pointer->nextarc;
}/*while*/
printf("\n");
}/*for*/
printf("\n===图形输出结束===\n");
}/*Print*/
int selectvex(){
int startvex;
printf("\n请输入遍历的起始结点(exit for -1):");
scanf("%d",&startvex);
return startvex;
}
/*广度优先遍历图,queue数组为遍历过程中使用的队列*/
void BFS(struct VexNode * head){
int queue[20];
int i,j,startvex,cur,pd;
struct ArcNode *pointer;
printf("\n====the BFS======\n");
startvex=selectvex(); /*用户输入遍历的起始点*/
while (startvex!=-1){
if (startvex<0||startvex>vexnum){
printf("输入错误!");
exit(0);
}else {
int rear=0,front=0;
/*设置所有顶点为均未访问*/
for(i=0;i<=vexnum;++i)
head[i].flag=0;
/*队列清空*/
for(i=0;i<20;i++)
queue[i]=0;
printf("\nBFS:");
/*起始点入队列*/
queue[rear++]=head[startvex].data;
/*标识起始点为已访问*/
head[startvex].flag=1;
while (front!=rear){
cur=queue[front];
pointer=head[cur].firstarc;
/*当邻接点存在*/
while(pointer!=NULL){
/*如果未被访问过*/
if (head[pointer->adjvex].flag==0){
queue[rear++]=pointer->adjvex; /*顶点入队列*/
head[pointer->adjvex].flag=1; /*标识此点为已访问*/
}
/*继续探访下一个邻接点*/
pointer=pointer->nextarc;
}/*while*/
printf("[%d]==>",queue[front++]); /*输出并删除队头元素*/
}/*while*/
}/*if else*/
printf("the BFS end\n");
printf("\n====the BFS======\n");
startvex=selectvex();
}/*while*/
}/*BFS*/
int main(){
int answer,search;
answer=formatlist();
switch(answer){
case 1:
case 2: create_graph(head);break;
case 0: exit(0);
default:{ printf("\n你的输入错误,请重新选择\n");
answer=formatlist();}
}/*switch*/
Print(head);
BFS(head);
system("pause");
exit(0);
}
运行结果是:
1---创建无向图:
2---创建有向图:
0---退出
请输入你的选择:1
请输入弧的信息(起点 终点 退出输入-1):1 2
请输入弧的信息(起点 终点 退出输入-1):1 3
请输入弧的信息(起点 终点 退出输入-1):2 4
请输入弧的信息(起点 终点 退出输入-1):2 5
请输入弧的信息(起点 终点 退出输入-1):4 8
请输入弧的信息(起点 终点 退出输入-1):5 8
请输入弧的信息(起点 终点 退出输入-1):3 6
请输入弧的信息(起点 终点 退出输入-1):3 7
请输入弧的信息(起点 终点 退出输入-1):6 7
请输入弧的信息(起点 终点 退出输入-1):-1 -1
=====当前图是=====
head[1]: [2]=>[3]=>
head[2]: [1]=>[4]=>[5]=>
head[3]: [1]=>[6]=>[7]=>
head[4]: [2]=>[8]=>
head[5]: [2]=>[8]=>
head[6]: [3]=>[7]=>
head[7]: [3]=>[6]=>
head[8]: [4]=>[5]=>
===图形输出结束===
====the BFS======
请输入遍历的起始结点(exit for -1):1
BFS:[1]==>[2]==>[3]==>[4]==>[5]==>[6]==>[7]==>[8]==>the BFS end
====the BFS======
请输入遍历的起始结点(exit for -1):2
BFS:[2]==>[1]==>[4]==>[5]==>[3]==>[8]==>[6]==>[7]==>the BFS end
====the BFS======
请输入遍历的起始结点(exit for -1):3
BFS:[3]==>[1]==>[6]==>[7]==>[2]==>[4]==>[5]==>[8]==>the BFS end
====the BFS======
请输入遍历的起始结点(exit for -1):4
BFS:[4]==>[2]==>[8]==>[1]==>[5]==>[3]==>[6]==>[7]==>the BFS end
====the BFS======
请输入遍历的起始结点(exit for -1):5
BFS:[5]==>[2]==>[8]==>[1]==>[4]==>[3]==>[6]==>[7]==>the BFS end
====the BFS======
请输入遍历的起始结点(exit for -1):6
BFS:[6]==>[3]==>[7]==>[1]==>[2]==>[4]==>[5]==>[8]==>the BFS end
====the BFS======
请输入遍历的起始结点(exit for -1):7
BFS:[7]==>[3]==>[6]==>[1]==>[2]==>[4]==>[5]==>[8]==>the BFS end
====the BFS======
请输入遍历的起始结点(exit for -1):8
BFS:[8]==>[4]==>[5]==>[2]==>[1]==>[3]==>[6]==>[7]==>the BFS end
====the BFS======
请输入遍历的起始结点(exit for -1):