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

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

有下面这张图:
《图的邻接表表示及其BFS遍历》

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

遍历结果应为:

    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.执行结果

整个目录文件如下:

《图的邻接表表示及其BFS遍历》
执行make,生成可执行文件,然后运行程序:
《图的邻接表表示及其BFS遍历》
可见程序运行结果和分析得到的结果是一致的。

代码下载:https://github.com/zkangHUST/DataStructure/tree/master/Graph

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/ww1473345713/article/details/52162244
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞