图的表示:如何存储微博、微信等社交网络中的好友关系?

图的表示:如何存储微博、微信等社交网络中的好友关系?

图的理解(Graph)

非线性表结构,树中的元素称为节点,图中的元素叫做顶点,图中的各个顶点都可以与任意其他顶点建立连接关系,这种建立的关系叫做边

把微信中的每个用户都看作一个顶点,两个用户之间互加好友,就在两者之间建立一个边,其中,每个用户有多少好友,对应在图中,就叫做顶点的度,就是跟顶点连接的边的条数

而微博更复杂,允许单向关注,如果A关注了B,就是一条从A到B的箭头的边,表示边的方向,这种叫有向图,没有方向的图叫做无向图

无向图中有表示一个顶点多少条边的度的概念,有向图中,把度分为入度(In-degree)和出度(Out-degree)顶点的入度,表示有多少条边指向这个顶点;顶点的出度,表示有多少条边以这个顶点为起点指向其他顶点的,以微博为例,入度表示有多少粉丝

QQ中亲密度怎么记录的?

在带权图中,每条边都有一个权重(weight),这个权重可以表示QQ亲密度

邻接矩阵存储方法

图的最直观的存储方式

邻接矩阵的底层依赖一个二维数组,对于无向图来说,如果顶点i和顶点j之间有边,将 A [ I ] [ J ] A[I][J] A [ J ] [ I ] A[J][I] ,都标记为1,对于有向图来说,顶点I和顶点J之间,有一条箭头从I指向J的边,将 A [ I ] [ J ] A[I][J] 标记为1,同理,J指向I,将 A [ J ] [ I ] A[J][I] 标记为1,用邻接矩阵表示一个图,比较浪费存储空间

对于无向图,如果 A [ I ] [ J ] A[I][J] = 1,那么 A [ J ] [ I ] A[J][I] =1,实际上我们存储一个即可,所以无向图的二维数组中,我们将其用对角线划分为上下两部分,只需要利用上面或者下面这样一般的空间足够了

如果存储的是稀疏图,即顶点很多,但每个顶点的边并不多,邻接矩阵的存储方法更加浪费了

但是利用邻接矩阵存储图,可以将很多图的运算转化成矩阵之间的运算,比如求解最短路径时候,利用矩阵循环相称若干次得到结果

邻接表存储方法

每个顶点对应一条链表,链表中存储的是与这个顶点相连接的其他顶点,有向图的邻接表存储方式,每个顶点对应的链表里面,存储的是指向的顶点

使用起来比较耗时间

可以将链表换成更加高效的数据结构,比如平衡二叉查找树

我们可以选用红黑树,可以更加快速的查找两个顶点之间是否存在边

如何存储微博、微信等社交网络中的好友关系?

微博是有向图,微信是无向图

针对微博,支持操作:

  • 判断用户A是否关注B
  • 判断用户A是否是用户B的粉丝
  • 用户A关注用户B
  • 用户A取关B
  • 根据用户名称首字母排序,分页获取用户的粉丝列表
  • 根据用户名称首字母排序,分页获取用户的关注列表

采用邻接表存储图,更是一个逆邻接表,邻接表中存储了用户的关注关系,逆邻接表中存储的是用户的被关注关系,对应图中,邻接表中,每个顶点的链表中存储的是这个顶点指向的顶点,逆邻接表中,每个顶点的链表中存储的是指向这个顶点的顶点,如果查找某个用户关注了哪些用户,可以在邻接表中查找,如果查找某个用户被那些用户关注,从逆邻接表中查找

需要按照用户名称的首字母排序,分页来获取用户的粉丝列表或者关注列表,用跳表,跳表插入、删除、查找非常高效,跳表中存储的数据是有序的

但这只能是小规模的几万、几十万用户,上亿用户得用哈希算法等数据分片方式,将邻接表存储在不同机器上。

一个机器存储顶点1,2,3的邻接表和逆邻接表,机器2存储顶点4,5的邻接表和逆邻接表,当药查询顶点与顶点关系时候,利用同样的哈希算法,定位顶点所在机器,再在响应的机器上查找

1.怎么存储微信这样的无向图?

使用邻接表的方式存世每个人对应的好友列表,为了支持快速查找,可以用红黑树存储

发布了76 篇原创文章 · 获赞 9 · 访问量 9190

猜你喜欢

转载自blog.csdn.net/ywangjiyl/article/details/104433610
今日推荐