图是一种非线性表数据结构。

图中的元素我们就叫作顶点(vertex)。
一个顶点可以与任意其他顶点建立连接关系,这种建立的关系叫作(edge)。
跟顶点相连接的边的条数,叫作顶点的(degree)。

无向图

边没有方向的图就叫作“无向图”。
【数据结构】图的表示与存储方法 邻接表 邻接矩阵

有向图

边有方向的图叫作“有向图”。
【数据结构】图的表示与存储方法 邻接表 邻接矩阵
有向图中,把度分为入度(In-degree)和出度(Out-degree)。

顶点的入度,表示有多少条边指向这个顶点;
顶点的出度,表示有多少条边是以这个顶点为起点指向其他顶点。

带权图

带权图中,每条边都有一个权重 (weight),可以通过这个权重来表示 QQ 好友间的亲密度。
【数据结构】图的表示与存储方法 邻接表 邻接矩阵

存储方法

邻接矩阵 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,对角线上下两部分相等,浪费一半空间;
其次,存储的矩阵大都是稀疏矩阵,比如微信有好几亿的用户,对应到图上就是好几亿的顶点。但矩阵中绝大部分都是0。

邻接表 Adjacency List

结构类似于散列表,每个顶点对应一条链表,链表中存储的是与这个顶点相连接的其他顶点。
【数据结构】图的表示与存储方法 邻接表 邻接矩阵
对于无向图类似,不过每个顶点的链表中存储的,是跟这个顶点有边相连的顶点。

这种方法节省空间,但是使用起来就比较耗时间。

若想判断是否存在一条从顶点 2 到顶点 4 的边,就要遍历 顶点 2 对应的那条链表,看链表中是否存在顶点 4。

可以将链表改成红黑树或跳表,以增加查找速度。

逆邻接表

以微博关注为例,
使用邻接表查找某个用户关注了哪些用户容易(某个顶点指向哪些其他顶点),
但是如果想知道某个用户都被哪些用户关注了,也就是用户的粉丝列表,是非常困难的。

这时,需要一个逆邻接表,来存储指向这个顶点的顶点。
【数据结构】图的表示与存储方法 邻接表 邻接矩阵

本文是极客时间王争 数据结构与算法 课程的笔记,推荐此课,喜欢可以购买课程。

相关文章: