图的表示法
2016-06-13 21:58
246 查看
要表示一个图G=(V,E)(注:V:vertex、E:edge),有两种方法,即邻接表和邻接矩阵。这两种方法既可以用于有向图,也可以用于无向图。
若G是一个无向图,则所有邻接表的长度之和为 2|E|。
无论有向图还是无向图,邻接表需要的存储空间为O(V+E)。
设G=(V,E)是一个加权函数为w的加权图。对每一条边(u,v)且(u,v)属于E,权值为w(u,v)和顶点v一起存储在u的邻接表中。
无向图的邻接矩阵A就是它自己的转置矩阵:A=A^T。在某些应用中只需要存储临街觉着呢的对角线及对角线以上的部分,图所占的存储空间几乎可以减少一半。
邻接矩阵的也可以用来表示加权图。矩阵中相应的元素可以存储边的权值,如果边不存在就用0或无限大的值来表示权值。
如果一个图不是加权的,邻接矩阵的每个元素只用一个二进制位,而不必用一个字的空间。
// 图1,无向图 1 ----- 2 | | \ | | / 3 5 ----- 4
邻接表
邻接表表示法通常表示稀疏图(图中 |E| 远小于 |V|^2)比较紧凑。// 邻接表数据结构表示无向图 // 定义图中最多100个节顶点 #define MAX 100 // 邻接表中的顶点定义 typedef struct Vertex { int v; struct Vertex *next; } Vertex; // 邻接表 Vertex Adj[MAX]; // 创建顶点 Vertex* makeVertex(int v) { Vertex *pVertex = (Vertex*) malloc(sizeof(Vertex)); pVertex->v = v; pVertex->next = NULL; return pVertex; } // 删除顶点 void destroyVertex(Vertex *pVertex) { free(pVertex); }
// 完整代码 #include <stdio.h> #include <malloc.h> #define MAX 100 typedef struct Vertex { int v; struct Vertex *next; } Vertex; Vertex Adj[MAX]; Vertex* makeVertex(int v) { Vertex *pVertex = (Vertex*) malloc(sizeof(Vertex)); pVertex->v = v; pVertex->next = NULL; return pVertex; } void destroyVertex(Vertex *pVertex) { free(pVertex); } // 初始化图 void initGraph() { printf("input edges:\nlike 1,2\n-1,-1\n"); int v1 = 0, v2 = 0; while (1){ scanf("%d,%d", &v1, &v2); // 输入-1,-1表示输入结束 if (v1 == -1 && v2 == -1) break; Adj[v1].v = v1; Vertex *pVertex = &Adj[v1]; while ( pVertex->next ) { pVertex = pVertex->next; } pVertex->next = makeVertex(v2); } } // 打印当前图 void printGraph(int n) { for (int i = 1; i <= n; i++) { printf("%d", Adj[i].v); Vertex *pVertex = Adj[i].next; while (pVertex) { printf("--%d", pVertex->v); pVertex = pVertex->next; } printf("\n"); } } // 销毁图中的节点 void uninitGraph(int n) { for (int i = 1; i <= n; i++) { Vertex *pVertex = Adj[i].next; Adj[i].next = NULL; while (pVertex) { Vertex *pTemp = pVertex->next; destroyVertex(pVertex); pVertex = pTemp; } printf("destroy vertex[%d]\n", i); } } int main() { int n = 0; printf("input vertex's number\n"); scanf("%d", &n); initGraph(); printGraph(n); uninitGraph(n); printGraph(n); return 0; } // 执行方式 input vertex's number 5 1,2 1,5 ... -1,-1 // 结束输入
邻接表的长度
若G是一个有向图,则所有邻接表的长度之和为 |E|。若G是一个无向图,则所有邻接表的长度之和为 2|E|。
无论有向图还是无向图,邻接表需要的存储空间为O(V+E)。
加权图
图的每条边有着相应权值。设G=(V,E)是一个加权函数为w的加权图。对每一条边(u,v)且(u,v)属于E,权值为w(u,v)和顶点v一起存储在u的邻接表中。
typedef struct Vertex { int v; // 顶点 int w; // 加权值 struct Vertex *next; } Vertex;
邻接矩阵
邻接矩阵表示法通常用于表示稠密图(图中|E| 接近于 |V|^2)或必须很快判别两个顶点是否存在连接边时使用。// 邻接矩阵表示无向图 #define MAX 100 int G[MAX][MAX] = {0};
// 完整代码 #include <stdio.h> #define MAX 100 int G[MAX][MAX] = {0}; // 初始化图 void initGraph() { printf("input edges:\nlike 1,2\n"); int v1 = 0, v2 = 0; while (1){ scanf("%d,%d", &v1, &v2); if (v1 == -1 && v2 == -1) break; G[v1][v2] = 1; G[v2][v1] = 1; } } // 打印图 void printGraph(int n) { for (int i = 1; i <= n; i++) { printf("%d", i); for (int j = 1; j <= n; j++) { if (G[i][j] == 1) { printf("--%d", j); } } printf("\n"); } } int main() { int n = 0; printf("input vertex's number\n"); scanf("%d", &n); initGraph(); printGraph(n); return 0; }
邻接矩阵的特点
一个图的邻接矩阵表示需要占用O(V^2)的存储空间,它与图中的边数多少是无关的。无向图的邻接矩阵A就是它自己的转置矩阵:A=A^T。在某些应用中只需要存储临街觉着呢的对角线及对角线以上的部分,图所占的存储空间几乎可以减少一半。
邻接矩阵的也可以用来表示加权图。矩阵中相应的元素可以存储边的权值,如果边不存在就用0或无限大的值来表示权值。
如果一个图不是加权的,邻接矩阵的每个元素只用一个二进制位,而不必用一个字的空间。
相关文章推荐
- zookeeper+kafka安装以及kafka+spark streaming 的简单整合
- Java基础03——比较运算符和逻辑运算符
- PHP访问数据库专项练习题
- JAVA中的变量----实例变量和类变量
- HTML5内联SVG
- leetcode字符串处理经典
- ubuntu 简单日常命令
- Leetcode 87. Scramble String
- Ajax与JSON的一些总结
- linux网络编程模型
- 天干地支象法
- android中的消息机制--浅谈Handler的原理及使用
- maven学习(一)
- Android入门-SayHello实现页面跳转
- UML系列图--用例图
- redis系列--set操作
- 常见的Linux内核中内存分配
- 飛飛(六十七)文件的应用 数数
- android之文件权限问题
- 我的JavaEE学习路线图