文章出处:极客时间《数据结构和算法之美》-作者:王争。该系列文章是本人的学习笔记。
1 基本概念
顶点、边
微信:A和B是好朋友,B也和A是好朋友,A和B之间有条边。
入度:每个顶点链接的边的个数=每个人好朋友的个数。
微博:A关注B,B不用关注A。从A到B有条边,边是有方向的。这样的图是有向图。入度:有多条边指向这个节点。出度:从这个顶点出发,有几条边。
QQ亲密度:两个人经常聊天,那亲密度高。这就是带权重的边。
2 图的存储方式
2.1 邻接矩阵
用二维数组存储图。
优点:表示简单;存取速度快;便于做矩阵运算。
缺点:在无向图中,只需要一半的空间即可,浪费空间。在稀疏图中,节点数量很多,每个节点的边的数量却很少,造成空间浪费。
2.2 邻接表
邻接表很像一张哈希表。链表的部分可以使用高效的动态数据结构:红黑树、跳表、散列表、有序动态数组(数据有序排列的动态数组)。
3 微信如何存储关系数据
我们先考虑一下微信用户关系,我们希望有的操作是:
1 判断用户A是否是用户B的好朋友。
2 能够按照首字母排序用户A的好朋友,且分页获取。
3 用户A删除用户B为好友,同时B的好友列表中也没有A。
首先用邻接表存储微信用户关系。因为这是一个稀疏图。微信用户几亿,每个人的好友最多也就500。
用户A:用户B->用户C->用户X
用户B:用户A->用户H->用户Z
…
判断用户A是不是用户B的好朋友,只需要在用户A的好友列表查找一下即可。好友列表可以用跳表存储。因为跳表可以按照首字母排序。排序好的好友列表也可以提高查询速度。第2个要求满足了。
用户A删除好友用户B,需要同时在用户A的好友列表删除B、用户B的好友链表删除A。跳表删除操作时间复杂度O(logn)。
对于数据量小的情况可以存储在内存。当用户量多的时候,一台机器就解决不了。可以使用哈希计算,将用户好友列表分别存储在不同的服务器。也可以使用外部存储(关系型数据库)存储数据。
4 BFS and DFS
广度优先搜索BFS和深度优先搜索DFS是最基本的搜索算法。
BFS是以起始点为圆心,一层一层由近及远的访问节点,形状像波纹。
DFS是以起始点开始,一头道走到目的地,然后再返回上一层选择另外一条路,形状像折线,像迷宫。