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

图的邻接表表示及其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

posted @ 2016-08-09 14:13  zkang  阅读(3800)  评论(0编辑  收藏  举报