圖的鄰接表表示及其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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM