今天想练习一下图算法,有些图算法的基础数据结构是邻接表,于是想着用C实现一下,虽说wiki上有一个邻接表的实现,但是自己还是想练一下手,在网上也搜到了别人的邻接表实现,发现大同小
异,然后就在别人的基础上修改了一下得到了这个版本,记录一下,供以后练习使用。
1.邻接表概念
一张图,如果不考虑空间占用问题的话,用邻接矩阵存储是最方便的了,但有时候,图很稀疏,用矩阵存储就不划算了,这时候可以考虑用邻接表来实现,另外,有些算法用邻接表比较合适。
邻接表的图示如下():
关于邻接表的概念,要清晰易懂的话上面的链接就很好,要详尽的话看wiki就好了,我的代码是在下面的基础上修改的。
2.邻接表需注意的点
- 一般需要一个顶点数组来保存顶点信息
- 每个顶点数组后面跟着一个单链表,表示与该顶点直接相连的顶点
- 顶点数组中保存有一个指向单链表头部的指针,以及顶点信息的相应描述
3.邻接表的实现
头文件:
/* by areslipan@163.com filename: adjlist.h */ #ifndef _ADJLIST_ #define _ADJLIST_ #includeusing namespace std; #define MAXVEX 100 /* 最大顶点数,应由用户定义 */ typedef int VertexType; /* 顶点类型应由用户定义 */ typedef int EdgeType; /* 边上的权值类型应由用户定义 */ typedef struct EdgeNode/* 边表结点 */ { int adjvex;/* 邻接点域,存储该顶点对应的下标 */ EdgeType weight;/* 用于存储权值,对于非网图可以不需要 */ struct EdgeNode *next; /* 链域,指向下一个邻接点 */ } EdgeNode; typedef struct VextexNode/* 顶点表结点 */ { VertexType data;/* 顶点域,存储顶点信息 */ EdgeNode *firstedge;/* 边表头指针 */ } VextexNode, AdjList[MAXVEX]; typedef struct { AdjList adjList; int numNodes, numEdges; /* 图中当前顶点数和边数 */ } GraphAdjList; void create_adjlist_graph(GraphAdjList *Gp); void show_adjlist_graph(GraphAdjList *Gp); void destroy_adjlist_graph(GraphAdjList *Gp); #endif 实现文件:
/* by areslipan@163.com filename : adjlist.cpp */ #include "adjlist.h" void create_adjlist_graph(GraphAdjList *Gp) { int i, j, k,w; EdgeNode *pe; cout << "输入顶点数和边数(空格分隔):" << endl; cin >> Gp->numNodes >> Gp->numEdges; cout << "输入顶点信息:" << endl; for (i = 0 ; i < Gp->numNodes; i++) { cin >> Gp->adjList[i].data; Gp->adjList[i].firstedge = NULL;/* 将边表置为空表 */ } for (k = 0; k < Gp->numEdges; k++)/* 建立边表 */ { cout << "输入边(vi,vj,w)的顶点序号i,j(空格分隔):" << endl; cin >> i >> j >> w; pe = (EdgeNode *)malloc(sizeof(EdgeNode)); pe->adjvex = j;/* 邻接序号为j */ pe->weight = w; /* 将pe的指针指向当前顶点上指向的结点 */ pe->next = Gp->adjList[i].firstedge; Gp->adjList[i].firstedge = pe;/* 将当前顶点的指针指向pe */ //如果是无向图可以加上下面这段代码 /* pe = (EdgeNode *)malloc(sizeof(EdgeNode)); pe->adjvex = i; pe->next = Gp->adjList[j].firstedge; Gp->adjList[j].firstedge = pe;*/ } cout<<"有向图的邻接表创建成功..."<numNodes == 0 || Gp->numEdges == 0)cout<<"The adjlist is empty!"< numNodes;++v) { cout<<"V"< <<":"; if(Gp->adjList[v].firstedge==NULL)cout<<"NULL"< adjList[v].firstedge; while(cur!=NULL) { cout<<"V"< adjvex<<"("< weight<<")"<<" "; cur=cur->next; } cout< numNodes == 0 || Gp->numEdges == 0)return ; else { for(int v=0;v numNodes;++v) { while(Gp->adjList[v].firstedge!=NULL) { EdgeNode *cur=Gp->adjList[v].firstedge; Gp->adjList[v].firstedge=cur->next; free(cur); } } } cout<<"邻接表销毁成功..."<
测试文件:
/* by areslipan@163.com filename : test.cpp */ #include "adjlist.h" using namespace std; int main() { GraphAdjList g; create_adjlist_graph(&g); show_adjlist_graph(&g); destroy_adjlist_graph(&g); show_adjlist_graph(&g); system("pause"); }