- 图的基本操作
- 查找函数(LocateVex查找坐标)
- 构建无向图(Undirected Graph)
- 输出邻接矩阵(print)
- 循环队列基本操作
- 入队(EnQueue)
- 出队(DeQueue)
- 判断队是否为空(QueueEmpty)
- 广度优先遍历:
- 广度优先查找(BFS)
- 广度优先遍历(BFSTraverse)
广度优先遍历基本步骤
- 设置全局变量visited数组并初始化为全0,代表所有节点均未被访问
- 设置起始点:包括对起始点进行输出、标记成已访问、入队
- 对后续结点进行操作:由起始点开始,对后续结点进行操作(输出、标记成已访问、入队)
(步骤2-3为广度优先搜索) - 循环重复2-3的操作避免有“孤岛”结点被遗漏。
(步骤4 循环执行广度优先搜索避免遗漏“孤岛”结点,就是广度优先遍历)
广度优先算法分析
- 设定好起始点后,将起始点入队。(下代码第7-10行)
- 然后就是对队列进行操作了:每一个元素出队,就要将它的所有邻接点依次入队,每出一次队,就对出队元素进行操作(操作表示找到与该端点有边的端点,进行“输出,设置成已访问,入队”)直到队列为空。
void BFS(MGraph *G,int i)
{
int j;
CyQueue q;
create(&q);
printf("%c",G->Vertex[i]);
visited[i]=1;
EnQueue(&q,i);
while(!QueueEmpty(&q))
{
DeQueue(&q,&i);
for(j=0;j<G->vexnum;j++)
{
if(G->AdjMatrix[i][j]==1&&visited[j]==0)
{
printf("%c",G->Vertex[j]);
visited[j]=1;
EnQueue(&q,j);
}
}
}
}
完整源代码
1.邻接矩阵
#include <stdio.h>
#include <stdlib.h>
#define VertexMax 100
#define Maxsize 100
typedef char VertexType;
typedef int dataType;
typedef struct
{
VertexType Vertex[VertexMax];
int AdjMatrix[VertexMax][VertexMax];
int vexnum,arcnum;
}MGraph;
typedef struct
{
dataType *base;
int front;
int rear;
}CyQueue;
int LocateVex(MGraph *G,VertexType v)
{
int i;
for(i=0;i<G->vexnum;i++)
{
if(v==G->Vertex[i])
{
return i;
}
}
printf("No Such Vertex!\n");
return -1;
}
void CreateUDG(MGraph *G)
{
int i,j;
printf("输入顶点个数和边数:\n");
printf("顶点数 n=");
scanf("%d",&G->vexnum);
printf("边 数 e=");
scanf("%d",&G->arcnum);
printf("\n");
printf("\n");
printf("输入顶点元素(无需空格隔开):");
scanf("%s",G->Vertex);
printf("\n");
for(i=0;i<G->vexnum;i++)
for(j=0;j<G->vexnum;j++)
{
G->AdjMatrix[i][j]=0;
}
int n,m;
VertexType v1,v2;
printf("请输入边的信息:\n");
for(i=0;i<G->arcnum;i++)
{
printf("输入第%d条边信息:",i+1);
scanf(" %c%c",&v1,&v2);
n=LocateVex(G,v1);
m=LocateVex(G,v2);
if(n==-1||m==-1)
{
printf("NO This Vertex!\n");
return;
}
G->AdjMatrix[n][m]=1;
G->AdjMatrix[m][n]=1;
}
}
void print(MGraph G)
{
int i,j;
printf("\n-------------------------------");
printf("\n 邻接矩阵:\n\n");
printf("\t ");
for(i=0;i<G.vexnum;i++)
printf(" %c",G.Vertex[i]);
printf("\n");
for(i=0;i<G.vexnum;i++)
{
printf("\t%c",G.Vertex[i]);
for(j=0;j<G.vexnum;j++)
{
printf(" %d",G.AdjMatrix[i][j]);
}
printf("\n");
}
}
void create(CyQueue *q)
{
q->base=(dataType *)malloc(Maxsize*sizeof(dataType));
if(!q->base)
{
printf("Space allocation failed!\n");
return;
}
q->front=q->rear=0;
return;
}
void EnQueue(CyQueue *q,dataType value)
{
if((q->rear+1)%Maxsize==q->front)
{
printf("Cyclic Queue is Full!\n");
return;
}
q->base[q->rear]=value;
q->rear=(q->rear+1)%Maxsize;
return;
}
void DeQueue(CyQueue *q,dataType *value)
{
if(q->front==q->rear)
{
printf("Cyclic Queue is Empty!\n");
return;
}
*value=q->base[q->front];
q->front=(q->front+1)%Maxsize;
return;
}
int QueueEmpty(CyQueue *q)
{
if (q->front==q->rear)
{
return 1;
}
return 0;
}
int visited[VertexMax];
void BFS(MGraph *G,int i)
{
int j;
CyQueue q;
create(&q);
printf("%c",G->Vertex[i]);
visited[i]=1;
EnQueue(&q,i);
while(!QueueEmpty(&q))
{
DeQueue(&q,&i);
for(j=0;j<G->vexnum;j++)
{
if(G->AdjMatrix[i][j]==1&&visited[j]==0)
{
printf("%c",G->Vertex[j]);
visited[j]=1;
EnQueue(&q,j);
}
}
}
}
void BFSTraverse(MGraph *G)
{
int i;
for(i=0;i<G->vexnum;i++)
{
visited[i]=0;
}
for(i=0;i<G->vexnum;i++)
{
if(visited[i]==0)
{
BFS(G,i);
}
}
}
int main()
{
MGraph G;
CreateUDG(&G);
print(G);
printf("\n\n广度优先遍历:");
BFSTraverse(&G);
return 0;
}
2.邻接表:
#include <stdio.h>
#include <stdlib.h>
#define VertexMax 20
#define Maxsize 100
typedef char VertexType;
typedef int dataType;
typedef struct ArcNode
{
int adjvex;
struct ArcNode *next;
}ArcNode;
typedef struct VNode
{
VertexType vertex;
struct ArcNode *firstarc;
}VNode;
typedef struct
{
VNode AdjList[VertexMax];
int vexnum,arcnum;
}ALGraph;
typedef struct
{
dataType *base;
int front;
int rear;
}CyQueue;
int LocateVex(ALGraph *G,VertexType v)
{
int i;
for(i=0;i<G->vexnum;i++)
{
if(v==G->AdjList[i].vertex)
{
return i;
}
}
printf("No Such Vertex!\n");
return -1;
}
void CreateUDG(ALGraph *G)
{
int i,j;
printf("输入顶点个数和边数:\n");
printf("顶点数 n=");
scanf("%d",&G->vexnum);
printf("边 数 e=");
scanf("%d",&G->arcnum);
printf("\n");
printf("\n");
printf("输入顶点元素(无需空格隔开):");
for(i=0;i<G->vexnum;i++)
{
scanf(" %c",&G->AdjList[i].vertex);
G->AdjList[i].firstarc=NULL;
}
printf("\n");
int n,m;
VertexType v1,v2;
ArcNode *p1,*p2;
printf("请输入边的信息:\n\n");
for(i=0;i<G->arcnum;i++)
{
printf("输入第%d条边信息:",i+1);
scanf(" %c%c",&v1,&v2);
n=LocateVex(G,v1);
m=LocateVex(G,v2);
if(n==-1||m==-1)
{
printf("NO This Vertex!\n");
return;
}
p1=(ArcNode *)malloc(sizeof(ArcNode));
p1->adjvex=m;
p1->next=G->AdjList[n].firstarc;
G->AdjList[n].firstarc=p1;
p2=(ArcNode *)malloc(sizeof(ArcNode));
p2->adjvex=n;
p2->next=G->AdjList[m].firstarc;
G->AdjList[m].firstarc=p2;
}
}
void print(ALGraph G)
{
int i;
ArcNode *p;
printf("\n-------------------------------");
printf("\n图的邻接表表示:\n");
for(i=0;i<G.vexnum;i++)
{
printf("\n AdjList[%d]%4c",i,G.AdjList[i].vertex);
p=G.AdjList[i].firstarc;
while(p!=NULL)
{
printf("-->%d",p->adjvex);
p=p->next;
}
}
printf("\n");
}
void create(CyQueue *q)
{
q->base=(dataType *)malloc(Maxsize*sizeof(dataType));
if(!q->base)
{
printf("Space allocation failed!\n");
return;
}
q->front=q->rear=0;
return;
}
void EnQueue(CyQueue *q,dataType value)
{
if((q->rear+1)%Maxsize==q->front)
{
printf("Cyclic Queue is Full!\n");
return;
}
q->base[q->rear]=value;
q->rear=(q->rear+1)%Maxsize;
return;
}
void DeQueue(CyQueue *q,dataType *value)
{
if(q->front==q->rear)
{
printf("Cyclic Queue is Empty!\n");
return;
}
*value=q->base[q->front];
q->front=(q->front+1)%Maxsize;
return;
}
int QueueEmpty(CyQueue *q)
{
if (q->front==q->rear)
{
return 1;
}
return 0;
}
int visited[VertexMax];
void BFS(ALGraph *G,int i)
{
int j;
struct ArcNode *p;
CyQueue q;
create(&q);
printf("%c",G->AdjList[i].vertex);
visited[i]=1;
EnQueue(&q,i);
while(!QueueEmpty(&q))
{
p=G->AdjList[i].firstarc;
DeQueue(&q,&i);
while(p!=NULL)
{
if(visited[p->adjvex]==0)
{
printf("%c",G->AdjList[p->adjvex].vertex);
visited[p->adjvex]=1;
EnQueue(&q,p->adjvex);
}
p=p->next;
}
}
}
void BFSTraverse(ALGraph *G)
{
int i;
for(i=0;i<G->vexnum;i++)
{
visited[i]=0;
}
for(i=0;i<G->vexnum;i++)
{
if(visited[i]==0)
{
BFS(G,i);
}
}
}
int main()
{
ALGraph G;
CreateUDG(&G);
print(G);
printf("\n\n广度优先遍历:");
BFSTraverse(&G);
return 0;
}
执行结果
- 邻接矩阵
- 邻接表