第三十节-图的表示

2018-12-10  本文已影响20人  wean_a23e

邻接矩阵存储方法

图最直观的一种存储方法就是,邻接矩阵 (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。对于带权图,数组中存储的就是相应的权重。

邻接矩阵存储法的优点是,直观,简单,可以利用 CPU 的缓存机制。缺点是,浪费空间。

对于无向图来说,一条边要重复存储两个位置,浪费了一半空间。对于稀疏图来说,,很多顶点之间并没有联系,他们相关的边的标记位的空间就浪费了。

但邻接矩阵简单的存储方式也使得在此基础上的算法都实现起来比较简单。比如:

邻接表存储方法

邻接表 (Adjacency List) 最简单的实现方式如下:

如图可以看到,每个顶点对应一条链表,链表中存储的是这个顶点出发的边。

与邻接矩阵相反,邻接表存储起来比较节省空间,但是计算起来比较耗时。不过有办法对邻接表进行优化。

常见的邻接表存储方式的优化操作有:

如何存储微博用户关系?

数据结构是为特定算法服务的,具体选择那种储存方法,与期望支持的操作有关系。假设针对微博用户关系,假设我们需要支持以下操作:

  1. 那在存储方式上,因为社交网络是一张稀疏图,所以我们选择用邻接表来存储。
  2. 因为要查询用户被关注的列表,仅用邻接图是非常浪费效率的,所以我们再增加一张逆邻接图,存储用户的被关注关系。加快获取粉丝列表的速度。
  3. 基础的邻接表查找一个用户是否在另一个用户的关注列表中,速度不够快,所以我们选择对邻接表进行优化。
  4. 因为要按首字母排序获取用户的关注列表,所以我们选择用跳表来代替邻接表中的链表。
  5. 假设用户规模比较大,一台机器装不下一整个表,我们可以用哈希分片的方式在不同的机器上存储这个表。
  6. 假设表的大小需要扩容,可以把哈希分片方式升级为一致性哈希分片。

假设数据需要持久性保存,可以用关系数据库保存。并在表上建立索引。

假设数据海量,可以使用专业的图数据库。

上一篇 下一篇

猜你喜欢

热点阅读