c语言实现图的邻接表存储方式

有向图的邻接表实现

初学图的邻接表存储方式,费了很多的时间去理解它。走了很多弯路,终于用代码上实现了这个存储结构,在这里把的感悟和过程做个总结,希望能帮到和我一样的初学者。

对于以下这个图
在这里插入图片描述
它的邻接表存储结构我相信大部分的朋友肯定是能够理解的,但是大部分的资料讲解都是在画一个邻接表的结构表示图之后直接上代码,然后对代码进行解释。

但对与我这样的初学者来说,这个由理论到代码的中间转换过程其实是最难理解的。我看了很多的博文,图的创建差不多都一样用一个函数进行边节点的不断插入。为了更容易理解这个创建的过程我用一个比较麻烦的方法去实现上图中图的存储

完整代码

#include<stdio.h>
#include<stdlib.h>
#define MAX 10
int visit[MAX]={0};
//以下结构体的创建和大部分资料的相同
typedef struct arcNode{//边节点
    int adjvex;//边指向的顶点编号,从0到4;这个和顶点信息
              //不一样哦        
   
    struct arcNode *next;//用于指向下一个arcnode节点
}arcNode;
typedef struct vNode{/*表头节点,也就是邻接表中每个单链表                       的表头,存储的是每一个顶点*/

    char data;/*这个是顶点信息,比如在其他资料中,这个用来
              表示v0,v1,v2,v3之类的,只是这里举的例子
             刚好是顶点为0,1,2,3,4*/
    arcNode *firstArc;//就是表头指向的第一个边节点
}vNode;
typedef struct graph{
    vNode adjlist[MAX];/*用顺序表来存储每一个表头,从而                         实现图的邻接表存储结构*/
    int e;//图的顶点数目
    int n;//图的顶点数目
}graph;

void createGraph(graph *G){//创建一个图
    int i;
    arcNode *arc[G->e] ;//定义n个边节点
    for(i=0;i<G->n;i++){//图的表头节点初始化
        G->adjlist[i].firstArc = NULL;//置空
        G->adjlist[i].data = '0'+i;//图的顶点信息,不是编号哦
    }
    for(i=0;i<G->e;i++){//初始化n个边节点
        arc[i] = (arcNode*)malloc(sizeof(arcNode));
    }
    //接下来开始手动一个搭建一个图
    //第一条链表,以adjlist[0]为表头
    G->adjlist[0].firstArc = arc[0];//arc[0]为表头节点0的第一条边,也就是0->1
    arc[0]->adjvex = 1;
    arc[0]->next =arc[1];//arc[0]边节点指向下一条边节点,也就是0->1->3
    arc[1]->adjvex = 3;
    arc[1]->next = arc[2];//同理0->1->3->4
    arc[2]->adjvex = 4;
    arc[2]->next = NULL;
    //第二条链表,以adjlist[1]为表头
    G->adjlist[1].firstArc = arc[3];//arc[3]成为表头节点1的第一条边,也就是1->
    arc[3]->adjvex = 4;
    arc[3]->next = arc[4];
    arc[4]->adjvex = 2;
    arc[4]->next = NULL;
    //第三条链表,以adjlist[2]为表头
    G->adjlist[2].firstArc = arc[5];
    arc[5]->adjvex = 0;
    arc[5]->next = NULL;
    
    G->adjlist[3].firstArc = arc[6];
    arc[6]->adjvex = 2;
    arc[6]->next = NULL;
    
    G->adjlist[4].firstArc = NULL;
}
void DFS(graph *G,int v){//深度遍历
    arcNode *p ;
    if(visit[v]==0){
    visit[v] = 1;//定义了一个int型数组visit来标记每个顶点是否被遍历过
    printf("%c   ",G->adjlist[v].data);//输出顶点
    p = G->adjlist[v].firstArc;//将每个顶点的下一个边节点赋给p节点
    while(p!=NULL){//循环遍历p所指向的下一个边节点
        if(visit[p->adjvex]==0){
            DFS(G,p->adjvex);
        }
        p=p->next;
    }
    }
}
int main(){
    graph *G = (graph*)malloc(sizeof(graph));
    G->e=7;//这个图的边有7条边
    G->n=5;//5个顶点
    createGraph(G);
    printf("\n");
    DFS(G, 0);
    return 0;
}

以上是我的愚解,如有不当的地方还望多指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章