您的位置:首页 > 其它

图的邻接表表示及其BFS遍历

2016-08-09 14:11 225 查看

图的邻接表表示及其BFS遍历

有下面这张图:



假设该图为有向图,边的指向均为小序号指向大序号。那么对该图的BFS遍历如下(假设从序号0的节点开始遍历):



遍历结果应为:

a b f c g i d e h


BFS遍历类似于树的层序遍历,需要用到队列。下面是程序代码:

1.队列定义和相关操作

文件1 queue.h

//1.queue.h
#ifndef QUEUE_H
#define QUEUE_H
#include<stdio.h>
#define MAX 100
typedef int MyType;    //可以修改为用户需要的数据类型
typedef struct
{
MyType node[MAX];
int  s;
int  e;
}queue;
MyType pop(queue* a);
void push(queue* a,MyType b);
void initQueue(queue* a);
int isEmpty(queue* a);
#endif


文件2 queue.c

//2.queue.c
#include "queue.h"
MyType pop(queue* a)
{
MyType tmp ;
tmp = a->node[a->s];
a->s++;
return tmp;
}
void push(queue* a,MyType b)
{
if(a->e==MAX)
fprintf(stderr,"ERROR:the queue is full,can not push again!\n");
else
{
a->node[a->e]=b;
a->e++;
}
}
void initQueue(queue* a)
{
a->s = 0;
a->e = 0;
}
int isEmpty(queue* a)
{
if(a->e == a->s)
return 1;
return 0;
}


2.图的邻接表表示及其遍历操作

文件3 graph.h

//graph.h
#ifndef GRAPH_H
#define GRAPH_H
#include<stdio.h>
#include<stdlib.h>
#include "queue.h"
#define MAXVEX 100
#define true 1
typedef char VertexType;
typedef int EdgeType;
typedef struct EdgeNode  /*边表结点*/
{
int adjvex; //存储顶点下标
EdgeType weight;
struct EdgeNode* next;
}EdgeNode;
typedef struct VertexNode   /*顶点表节点*/
{
VertexType data;
EdgeNode* firstedge;
}VertexNode,AdjList[MAXVEX];
typedef struct
{
AdjList adjList;
int numVertexes,numEdges;
}GraphAdjList;
void CreatGraph(GraphAdjList *g);
void DFS(GraphAdjList *g,int i);
void DFSTravel(GraphAdjList *g);
void BFSTravel(GraphAdjList *g);
#endif


文件4 graph.c

#include "graph.h"
int visited[MAXVEX]={0};
void CreatGraph(GraphAdjList *g)
{
int i,j,k;
EdgeNode *e;
scanf("%d%d",&g->numVertexes,&g->numEdges);
char c;
//gettchar();
for(i=0;i<g->numVertexes;i++)
{
while((c=getchar())=='\n'||c==' '); //排除空格和'\n'
g->adjList[i].data = c;
//  scanf("%c",&g->adjList[i].data);

g->adjList[i].firstedge = NULL;
}
for(k=0;k<g->numEdges;k++)
{
scanf("%d%d",&i,&j);
e=(EdgeNode*)malloc(sizeof(EdgeNode));
e->adjvex = j;
e->next = g->adjList[i].firstedge;
g->adjList[i].firstedge= e;
/*e=(EdgeNode*)malloc(sizeof(EdgeNode));如果图为无向图,则需要加上这段代码
e->adjvex = i;
e->next = g->adjList[j].firstedge;
g->adjList[j].firstedge= e;*/

}
}
void DFS(GraphAdjList *g,int i)
{
EdgeNode *p;
visited[i]=1;
printf("%c ",g->adjList[i].data);
p = g->adjList[i].firstedge;
while(p)
{
if(visited[p->adjvex]==0)
DFS(g,p->adjvex);
p=p->next;
}
}
void DFSTravel(GraphAdjList *g)
{
int i;
for(i=0;i<g->numVertexes;i++)
{
if(!visited[i])
DFS(g,i);   //主要是为了处理非连通图,如果为连通图,那么DFS函数执行一次即可遍历全部节点
}
}
void BFSTravel(GraphAdjList *g)
{
int i;
int tmp;
EdgeNode *p;
queue q;
for(i=0;i<g->numVertexes;i++)
visited[i]= 0;
initQueue(&q);
for(i=0;i<g->numVertexes;i++)
{
if(!visited[i])
{
visited[i]=1;
printf("%c ",g->adjList[i].data);
push(&q,i);
while(!isEmpty(&q))
{
tmp  = pop(&q);
p = g->adjList[tmp].firstedge;
while(p)
{
if(!visited[p->adjvex])
{
visited[p->adjvex]=1;
printf("%c ",g->adjList[p->adjvex].data);
push(&q,p->adjvex);
}
p = p->next;
}
}
}
}
}


3.main.c文件

main.c文件非常简单

文件5 main.c

#include<stdio.h>
#include"graph.h"
int main()
{
GraphAdjList g;
CreatGraph(&g);
BFSTravel(&g);
return 0;
}


4.makefile文件

为了方便编译,写一个简单的makefile文件

文件6 makefile

OBJ = main.o queue.o graph.o
TARGET = main.out
${TARGET}:${OBJ}
gcc -o ${TARGET} ${OBJ}
main.o:main.c
gcc -c main.c
queue.o:queue.c
gcc -c queue.c
graph.o:graph.c
gcc -c graph.c
clean:
rm -rf ${TARGET} ${OBJ}


5.执行结果

整个目录文件如下:



执行make,生成可执行文件,然后运行程序:



可见程序运行结果和分析得到的结果是一致的。

代码下载:https://github.com/zkangHUST/DataStructure/tree/master/Graph
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: