图的邻接表表示及其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
相关文章推荐
- Android 判断下拉菜单spinner选择了哪个选项
- Android Json 解析
- HTML5 语音波形显示,编辑,上传,下载
- Poj(1273),最大流,EK
- installshield 2013注册码
- 浅析Android中的消息机制
- R语言中的data.frame数据索引
- bzoj2049: [Sdoi2008]Cave 洞穴勘测
- 在VC中用CMarkup类操纵XML___
- C#不用ArcEngine,生成Shp文件(一)---------shapefile数据说明
- 分享一个直接加QQ好友的链接或会话的
- Sql Server数据库中char、nchar、varchar、nvarchar区别
- Android中泡泡窗口二级筛选效果
- Android 状态信息的记录onPause和onSaveInstanceState
- 使用Xcode和Instruments调试解决iOS内存泄露
- 欢迎使用CSDN-markdown编辑器
- 刘霞- 布梵剪裁俱乐部创始人 时尚教主 | 到「在行」来约见我
- Vertica 分区表设计(续)
- ASP.NET--常用ORM框架
- kafka安装