作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

图(graph)是一种比较松散的数据结构。它有一些节点(vertice),在某些节点之间,由边(edge)相连。节点的概念在树中也出现过,我们通常在节点中储存数据。边表示两个节点之间的存在关系。在树中,我们用边来表示子节点和父节点的归属关系。树是一种特殊的图,但限制性更强一些。

这样的一种数据结构是很常见的。比如计算机网络,就是由许多节点(计算机或者路由器)以及节点之间的边(网线)构成的。城市的道路系统,也是由节点(路口)和边(道路)构成的图。地铁系统也可以理解为图,地铁站可以认为是节点。基于图有许多经典的算法,比如求图中两个节点的最短路径,求最小伸展树等。

图的经典研究是柯尼斯堡七桥问题(Seven Bridges of Königsberg)。柯尼斯堡是现今的加里宁格勒,城市中有一条河流过,河中有两个小岛。有七座桥桥连接河的两岸和两个小岛。送信员总想知道,有没有一个办法,能不重复的走过7个桥呢?

(这个问题在许多奥数教材中称为"一笔画"问题)

欧拉时代的柯尼斯堡地图

柯尼斯堡的可以看作由7个边和4个节点构成的一个图:

这个问题最终被欧拉巧妙的解决。七桥问题也启发了一门新的数学学科——图论(graph theory)的诞生。欧拉的基本思路是,如果某个节点不是起点或者终点,那么连接它的边的数目必须为偶数个(从一个桥进入,再从另一个桥离开)。对于柯尼斯堡的七桥,由于4个节点都为奇数个桥,而最多只能有两个节点为起点和终点,所以不可能一次走完。

图的定义

严格的说,图G=(V,E)是由节点的集合V和边的集合E构成的。一个图的所有节点构成一个集合V。一个边可以表示为(v1,v2),其中v1,v2∈V,即两个节点。如果(v1,v2)有序,即(v1,v2)与(v2,v1)不同,那么图是有向的(directed)。有序的边可以理解为单行道,只能沿一个方向行进。如果(v1,v2)无序,那么图是无向的(undirected)。无序的边可以理解成双向都可以行进的道路。一个无序的边可以看作连接相同节点的两个反向的有序边,所以无向图可以理解为有向图的一种特殊情况。

(七桥问题中的图是无向的。城市中的公交线路可以是无向的,比如存在单向环线)

图的一个路径(path)是图的一系列节点w1,w2,...,wn,且对于1≤i<n,有(wi,wi+1)∈E。也就是说,路径是一系列的边连接而成,路径的两端为两个节点。路径上边的总数称为路径的长度。乘坐地铁时,我们会在选择某个路径,来从A站到达B站。这样的路径可能有不止一条,我们往往会根据路径的长度以及沿线的拥挤状况,来选择一条最佳的路线。如果存在一条长度大于0的路径,该路径的两端为同一节点,那么认为该图中存在环路(cycle)。很明显,上海的地铁系统中存在环路。

找到一条环路

如果从每个节点,到任意一个其它的节点,都有一条路径的话,那么图是连通的(connected)。对于一个有向图来说,这样的连通称为强连通(strongly connected)。如果一个有向图不满足强连通的条件,但将它的所有边都改为双向的,此时的无向图是连通的,那么认为该有向图是弱连通(weakly connected)。

如果将有火车站的城市认为是节点,铁路是连接城市的边,这样的图可能是不连通的。比如北京和费城,北京有铁路通往上海,费城有铁路通往纽约,但北京和费城之间没有路径相连。

图的实现

一种简单的实现图的方法是使用二维数组。让数组a的每一行为一个节点,该行的不同元素表示该节点与其他节点的连接关系。如果(u,v)∈E,那么a[u][v]记为1,否则为0。比如下面的一个包含三个节点的图:

可以简单表示为

a 1 2 3
1 0 1 1
2 0 0 0
3 0 1 0

这种实现方式所占据的空间为O(|V|2),|V|为节点总数。所需内存随着节点增加而迅速增多。如果边不是很密集,那么很多数组元素记为0,只有稀疏的一些数组元素记为1,所以并不是很经济。

更经济的实现方式是使用邻接表(adjacency list),即记录每个节点所有的相邻节点。对于节点m,我们建立一个链表。对于任意节点k,如果有(m,k)∈E,就将该节点放入到对应节点m的链表中。邻接表是实现图的标准方式。比如下面的图,

可以用如下的数据结构实现:

左侧为一个数组,每个数组元素代表一个节点,且指向一个链表。该链表包含有该数组元素所有的相邻元素。

总体上看,邻接表可以分为两部分。邻接表所占据的总空间为O(|V|+|E|)。数组部分储存节点信息,占据|V|)的空间,即节点的总数。链表存储边的信息,占据|E|的空间,即边的总数。在一些复杂的问题中,定点和边还可能有其他的附加信息,我们可以将这些附加信息储存在相应的节点或者边的位置。

下面为具体的C代码:

/* By Vamei */
#include <stdio.h>
#include <stdlib.h>#define NUM_V 5typedef struct node *position;/* node */
struct node {int element;position next;
};/* * operations (stereotype)*/
void insert_edge(position, int, int);
void print_graph(position graph, int nv);/* for testing purpose */
void main()
{struct node graph[NUM_V];int i;// initialize the verticesfor(i=1; i<NUM_V; i++) {(graph+i)->element = i;(graph+i)->next    = NULL;}// insert edgesinsert_edge(graph,1,2);insert_edge(graph,1,4);insert_edge(graph,3,2);insert_edge(graph,4,2);insert_edge(graph,4,3);print_graph(graph,NUM_V);
}/* print the graph */
void print_graph(position graph, int nv) {int i;position p;for(i=1; i<nv; i++) {p = (graph + i)->next;printf("From %3d: ", i);while(p != NULL) {printf("%d->%d; ", i, p->element);p = p->next;}printf("\n");}
}/** insert an edge*/
void insert_edge(position graph,int from, int to)
{position np;position nodeAddr;np = graph + from;nodeAddr = (position) malloc(sizeof(struct node));nodeAddr->element = to;nodeAddr->next    = np->next;np->next = nodeAddr;
}

运行结果:

From   1: 1->4; 1->2; 
From   2: 
From   3: 3->2; 
From   4: 4->3; 4->2;

上面的实现主要基于链表,可参考纸上谈兵: 表 (list) 。

总结

图是一种很简单的数据结构。图的组织方式比较松散,自由度比较大,但也造成比较高的算法复杂度。我将在以后介绍一些图的经典算法。

纸上谈兵: 图 (graph)相关推荐

  1. 从图(Graph)到图卷积(Graph Convolution):漫谈图 神经⽹络模型 (⼀)

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 作者最近看了一些图与图卷积神经网络的论文,深感其强大,但一些Sur ...

  2. 数据结构--图(Graph)详解(四)

    数据结构–图(Graph)详解(四) 文章目录 数据结构--图(Graph)详解(四) 一.图中几个NB的算法 1.普里姆算法(Prim算法)求最小生成树 2.克鲁斯卡尔算法(Kruskal算法)求最 ...

  3. 数据结构--图(Graph)详解(三)

    数据结构–图(Graph)详解(三) 文章目录 数据结构--图(Graph)详解(三) 一.深度优先生成树和广度优先生成树 1.铺垫 2.非连通图的生成森林 3.深度优先生成森林 4.广度优先生成森林 ...

  4. 数据结构--图(Graph)详解(二)

    数据结构–图(Graph)详解(二) 文章目录 数据结构--图(Graph)详解(二) 一.图的存储结构 1.图的顺序存储法 2.图的邻接表存储法 3.图的十字链表存储法 4.图的邻接多重表存储法 二 ...

  5. 数据结构--图(Graph)详解(一)

    数据结构–图(Graph)详解(一) 文章目录 数据结构--图(Graph)详解(一) 一.图的基本概念 1.图的分类 2.弧头和弧尾 3.入度和出度 4.(V1,V2) 和 < V1,V2 & ...

  6. python加载模型文件进行图片分类_tensorflow通过模型文件,使用tensorboard查看其模型图Graph方式...

    Google提供了一个工具,TensorBoard,它能以图表的方式分析你在训练过程中汇总的各种数据,其中包括Graph结构. 所以我们可以简单的写几行Pyhton,加载Graph,只在logdir里 ...

  7. 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络 (二)

    在从图(Graph)到图卷积(Graph Convolution): 漫谈图神经网络 (一)中,我们简单介绍了基于循环图神经网络的两种重要模型,在本篇中,我们将着大量笔墨介绍图卷积神经网络中的卷积操作 ...

  8. 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (一)

    本文属于图神经网络的系列文章,文章目录如下: 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (一) 从图(Graph)到图卷积(Graph Convolutio ...

  9. 数据结构与算法(python):图(Graph)的基本概念及应用

    参考自 MOOC数据结构与算法Python版 本章代码: https://github.com/HuiFang-hub/-/tree/main. 目录 一.图Graph的概念 1.1 互联网 1.2 ...

最新文章

  1. a onclick 未响应_深大李冰石教授、港科大唐本忠院士:在多重刺激响应性材料领域取得最新进展...
  2. MySQL数据库:完整性约束
  3. 打算尝试瑜伽,看是否能解决长期困扰的胃痛问题
  4. 途家网获3亿美元融资,PMCAFF放送100元途家优惠券(途家内部员工专用)
  5. 2011-05-20
  6. 本人开源项目 Lu-Rpc
  7. 关于流控器件和压控器件
  8. go将服务器图片响应给客户端,Go中来自客户端和服务器的RPC
  9. 数据结构----归并排序
  10. 安卓机用久了仍会卡?来看看两年前的小米6
  11. 性能为王:SQL标量子查询的优化案例分析
  12. JavaScript-闭包closure
  13. AUTOCAD——坐标引线标注
  14. PDF解密工具—Cisdem PDF Password Remover
  15. 别再用mybatis了,mybatis-plus 这个神级工具一发入魂
  16. 浅谈到底什么是系统集成(弱电)和项目管理?
  17. CST2019电磁工作室的简单使用
  18. 浅尝Pytorch自动混合精度AMP
  19. 健康地奋斗着——程序员自己的养生书
  20. android学习心得【安卓入门一】

热门文章

  1. 递归求最大素因数(java)
  2. 微信支付企业付款的php开发实例
  3. 回调函数举例ajax,通过回调函数的理解来进一步理解ajax及其注意的用法
  4. 正则表达式(附匹配手机号和HTML标签)
  5. zara小程序怎么付款_能扫码付款并且可以打折的微信小程序怎么做?
  6. 使用python爬取中国电影票房数据并写入csv文件
  7. 彩色日志,教你配置颜色分明的日志输出。
  8. 可变参数传递与不可变参数传递
  9. 如何禁止WordPress主题纯英文评论教程
  10. Flink的背压机制