一.先看代码:
/*广度优先遍历*/
# include <stdio.h>
# include <stdlib.h>
# define max 10
//邻接表
typedef struct node
{
int adjvex;
int weight;
struct node *next;
}NODE;
typedef struct{
char data;
NODE * head;
}Vnode;
typedef struct {
int vexnum;
int arcnum;
Vnode array[max];
}ALG;
//队列
typedef struct Qnode{ //链队结点的类型
int data;
struct Qnode *next;
}Que,*QUE;
typedef struct
{
QUE front;
QUE rear;
}LQ;
LQ Q;
void InitQueue(LQ &Q)
{
Q.front=Q.rear=(QUE)malloc(sizeof(Que));
if(!Q.front) exit(1); //存储分配失败
Q.front->next=NULL;
}
void enterQueue(LQ &Q,int e)
{ QUE p;
p=(QUE)malloc(sizeof(Que));
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
}
int empty(LQ &Q)
{
return(Q.front==Q.rear? 1:0);
}
void DeleteQueue(LQ &Q,int &e)
{ QUE p;
if(empty(Q))
{
printf("\n Queue is free!");
exit(1);
}
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.front->next==NULL) Q.rear=Q.front;
free(p);
}
int visited[max];//存放定点是否被访问过的标志
int xiabiao(ALG G, char v)//通过定点的值找到对应的下标
{
int i;
for(i = 0; i<G.vexnum; i++)
{
if(v == G.array[i].data)
return i;
}
if (i==G.vexnum) {printf("Error u!\n");exit(1);}
return 0;
}
ALG creat()//创建一个邻接表
{
ALG G;
int i, k, j;
char enter;
char a,b;
int x;
printf("请输入点数和边数:\n");
scanf("%d%d",&G.vexnum,&G.arcnum);
printf("请输入定点的信息:\n");
for(i = 0; i<G.vexnum; i++)
{
scanf("%c%c",&enter,&G.array[i].data);
G.array[i].head = NULL;
}
printf("输入(a,b,w)\n");
for(i = 0; i<G.arcnum; i++)
{
NODE *p = (NODE *)malloc(sizeof(NODE));
scanf("%c%c",&enter,&a);
scanf("%c%c",&enter,&b);
scanf("%d",&x);
k = xiabiao(G, a);
j = xiabiao(G, b);
printf("%d ",k);
printf("%d ",j);
p->adjvex = j;
p->weight = x;
p->next = G.array[k].head;
G.array[k].head = p;
}
return G;
}
void BFS(ALG G, int v)
{
printf("%c",G.array[v].data);
visited[v] = 1;
NODE *p;
InitQueue(Q);
enterQueue(Q, v);
while(!empty(Q))
{
DeleteQueue(Q, v);
p=G.array[v].head;//头结点
while(p)
{
if(!visited[p->adjvex])
{
printf("%c",G.array[p->adjvex].data);
visited[p->adjvex] = 1;
enterQueue(Q, p->adjvex);
}
p=p->next;
}
}
}
void BFStraverse(ALG G)
{
for(int i = 0; i<G.vexnum; i++)
{
visited[i] = 0;
}
for(int i = 0; i<G.vexnum; i++)
{
if(!visited[i])
BFS(G, i);//连通图只调用一次,而非连通图多次
}
}
int main(void)
{
ALG G = creat();
BFStraverse(G);
return 0;
}
二.基本思想:
1:图的广度优先搜素类似于树的按层次遍历,它是由一个顶点出发,访问此顶点之后,依次访问与它相邻的未被访问的邻接点,之后按照刚才访问邻接点的顺序依次访问他们的邻接点。
2:因为它类似于树的按层次遍历,所以可以用队列来保存以访问过的顶点,在搜索的过程中,每访问一个顶点,就将这个顶点入队,队头元素出队时将队头的邻接点入队,每个顶点入队一次,重复此过程。
A->E->B->C->D