• 图的邻接表表示及其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!
    ");
    	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())=='
    '||c==' '); //排除空格和'
    '
    		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

  • 相关阅读:
    Opaque data type--不透明类型
    swift class的动态派发
    swift class的虚函数表
    swift class的虚函数表、扩展、@objc修饰、虚函数的派发方式研究
    swift语言混编--语言交互的接口
    CPU指令分类
    CPU的内部架构和工作原理-原文
    cpu的组成及分工
    简单介绍 CPU 的工作原理
    php7开启强类型模式
  • 原文地址:https://www.cnblogs.com/zhengkang/p/5753035.html
Copyright © 2020-2023  润新知