数据结构-图

图是一种n对n关系的数据结构,如下图所示,每一个数据可能有多个前置和多个后置。

数据结构:图的表示_数据结构图

图由顶点和边组成。边也可以是无向的(a到b,b也到a),可以是有向的(a->b,但是b不能到a),有向图例子:

数据结构:图的表示_数据结构图_02

图比线性表和树更加复杂,数据元素之间的关系可以是任意的。也因此应用得很广泛。
图有很多操作,遍历,最短路径,最长路径等等。

图的表示

图通过顶点V以及顶点之间的关系E(也叫边)表示。
每个顶点有degree“度”,即附属于它的边的条数,对有向图来讲,“度”分成in degree入度和out degree出度。
对于有n个顶点的图,如果是无向图,边数最多为n(n-1)/2,有向图边数最多为n(n-1)。有这么多边的图叫完全图。
从一个顶点到另一个顶点,经过一系列的顶点和边的序列,叫做路径p={v1, e1, v2,e2, …, vm-1,em-1,vm},经过的边的长度叫做路径的长度。
如果第一个顶点跟最后一个顶点式同一个顶点,叫做一个环路cycle。
如果从顶点S到顶点T之间存在一条路径,我们叫它S到T可达的/连通的。如果任意两个顶点之间都是连通的,我们叫连通图。非连通图有多个连通分量。
如果边不仅仅有顶点之间的关系,还有相关的值,如距离和消耗,我们把这些信息叫做weight权,这样的图我们叫做权图或者叫做网。
我们看到了,定义一个图,就是抓住它的顶点集合以及这些顶点之间的连接关系即可。我们可以用adjacent matrix邻接矩阵表示图。
比如,对上面所示的无向图,我们可以这么表示:

数据结构:图的表示_数据结构图_03

用1表示两个顶点之间有一条边,空表示没有。可以看出无向图的矩阵是对称的。
对上面所示的有向图,我们可以这么表示:

数据结构:图的表示_数据结构图_04

用1表示两个顶点之间有一条有向的边,空表示没有。
同理,对带权的图也可以同样表示,只不过呢,我们不用1来记录有没有边了,而是记录权值。如下图:

数据结构:图的表示_数据结构图_05

可以用如下的邻接矩阵:

数据结构:图的表示_数据结构图_06

实际存储的时候,我们怎么处理空呢?刚开头的想法是用0表示空,但是考虑权图,把这三种情况统一起来,最后大家觉得用无穷大表示比较好。
通过邻接矩阵,我们很容易看出一个顶点有多少条边,也比较容易算出两个顶点之间是有连通。
而邻接矩阵最大的缺点是占用了太多空间。
另一种表示办法是adjacent list邻接表,一个一维数组记录顶点,每个格子带一个链表记录由这个顶点出发的边。
如对上面所示的无向图,我们这么表示:

数据结构:图的表示_数据结构图_07

邻接表省空间,但是判断两个顶点之间是否有边连通则比较麻烦,删除一条边也比较麻烦。
还有双链表表示,字典表示等等。
总之,不同的数据结构有不同的优缺点。
一个图可能会有多种操作,如遍历所有顶点,求两个顶点之间的路径,最短路径,最长路径等等。