[toc]
图
- 图中的元素我们就叫作顶点(vertex)。
- 图中的一个顶点可以与任意其他顶点建立连接关系,这种建立的关系叫作边(edge)。
- 无向图中顶点相连接的边的条数叫作顶点的度(degree)。
- 有向图中,度分为入度(In-degree)和出度(Out-degree):顶点的入度,表示有多少条边指向这个顶点;顶点的出度,表示有多少条边是以这个顶点为起点指向其他顶点。
- 在带权图中,每条边都有一个权重(weight)。
邻接矩阵存储方法
图最直观的一种存储方法就是,邻接矩阵(Adjacency Matrix)。
邻接矩阵的底层依赖一个二维数组。对于无向图来说,如果顶点 i 与顶点 j 之间有边,我们就将 $A[i][j]$ 和 $A[j][i]$ 标记为 1;对于有向图来说,如果顶点 i 到顶点 j 之间,有一条箭头从顶点 i 指向顶点 j 的边,那我们就将 $A[i][j]$ 标记为 1。同理,如果有一条箭头从顶点 j 指向顶点 i 的边,我们就将 $A[j][i]$ 标记为 1。对于带权图,数组中就存储相应的权重。
用邻接矩阵来表示一个图,虽然简单、直观,但是比较浪费存储空间。对于无向图来说,如果 $A[i][j]$ 等于 1,那 $A[j][i]$ 也肯定等于 1。实际上,我们只需要存储一个就可以了。也就是说,无向图的二维数组中,如果我们将其用对角线划分为上下两部分,那我们只需要利用上面或者下面这样一半的空间就足够了,另外一半白白浪费掉了。如果我们存储的是稀疏图(Sparse Matrix),也就是说,顶点很多,但每个顶点的边并不多,那邻接矩阵的存储方法就更加浪费空间了。
- 邻接矩阵的存储方式简单、直接,因为基于数组,所以在获取两个顶点的关系时,就非常高效。
- 用邻接矩阵存储图的另外一个好处是方便计算。这是因为,用邻接矩阵的方式存储图,可以将很多图的运算转换成矩阵之间的运算。
邻接表存储方法
邻接表(Adjacency List)每个顶点对应一条链表,链表中存储的是与这个顶点相连接的其他顶点。
图中画的是一个有向图的邻接表存储方式,每个顶点对应的链表里面,存储的是指向的顶点。对于无向图来说,也是类似的,不过,每个顶点的链表中存储的,是跟这个顶点有边相连的顶点,
邻接表存储起来比较节省空间,但是使用起来就比较耗时间。可以将邻接表中的链表改成平衡二叉查找树。实际开发中,可以选择用红黑树。这样,可以更加快速地查找两个顶点之间是否存在边。二叉查找树也可以换成其他动态数据结构,比如跳表、散列表等。除此之外,还可以将链表改成有序动态数组,可以通过二分查找的方法来快速定位两个顶点之间否是存在边。