Ⅰ 前言
相信大家都用过微信、微博、QQ 这些社交软件中的一个,在微信和QQ中,两个人可以互相加为好友;在微博中,两个人可以互相关注。那么,我们要如何存储微信、微博这些社交网络的好友关系呢?
这就要用到我们这篇文章中要讲的一个数据结构——图。实际上,涉及图的算法有很多,也非常地复杂,比如图的搜索、最短路径、最小生成树、二分图等等等等……
这篇文章我们聚焦在图上,先把图这个数据结构拿下,在后面的文章里,我会详细讲解关于的图的算法。
在我刚开始学图的时候,是很吃力的,主要是学校的教材非常绕,让我一直摸不着头脑,然后很快就放弃了。所以希望这篇文章不要给你们这种感觉,尽量饶有趣味地搞懂这个数据结构。
Ⅱ 如何理解“图”?
在前面的文章里,我讲过一个非线性表数据结构,就是树。图和树一样,也是一种非线性表数据结构,并且更加复杂。
我们知道,树中的元素我们称为节点,图中的元素我们就叫做顶点(vertex)。从下面的图中可以看出,图中的一个顶点可以任意其他顶点建立连接关系。我们把这种建立的关系叫作边(edge)。
我们生活中就有很多符合图这种结构的例子,比如社交网络,就是一个非常典型的图结构。
我们就用微信来举例子,可以把每个用户看作是一个顶点。如果两个用户之间互相加了好友,那就在两者之间建立一条边。所以,整个微信的好友关系就可以用一张图来表示。其中,每个用户有多少好友,对应到图中,就叫做顶点的度(degree),就是跟顶点相连接的边的条数。
然后我们再看微博。微博和微信我们知道好友之间的关系是不一样的,微博可以单向关注,也就是说用户 A 关注了用户 B,但用户 B 可以不关注用户 A,那我们如何来表示这种单向的社交关系呢?
我们可以把上面的图的结构稍微改造一下,引入边的方向的概念。
如果用户 A 关注了用户 B,我们就在图中画一条从 A 到 B 的带箭头的边,来表示边的方向。如果用户 A 和用户 B 互相关注了,那我们就画一条从 A 到 B 的带箭头的边,再画一条从 B 指向 A 的边。我们把这种边有方向的图叫做 “有向图”。那,边没有方向的图就叫做 “无向图”。
前面我们说了 度 这个概念,表示一个顶点有多少条边。在有向图中,我们把度分为 入度(In-degree) 和 出度(Out-degree)。
顶点的入度,表示有多少条边指向这个顶点;
顶点的出度,表示有多少条边是以这个顶点为起点指向其他顶点。
对应到微博的例子,入度就表示有多少粉丝,出度就表示关注了多少人。
说完了微信、微博,我们再来看 QQ。
QQ 中的社交关系要更复杂一点。不知道你有没有留意过,QQ还有个亲密度的功能。QQ 不仅记录了用户之间的好友关系,还记录了两个用户之间的亲密度。如果两个用户经常往来,亲密度就比较高;如果两个用户不经常往来,亲密度就比较低。
我现在已经不怎么用 QQ 了,刚找了一下和我女朋友的亲密度
看来这个算的还是不那么精准。(手动狗头)
回到正题,那我们在图中要如何记录这种好友关系的亲密度呢?
这就要用到另一种图,带权图(weighted graph)。在带权图中,每条边都有一个权重(weight),我们可以通过这个权重来表示 QQ 好友间的亲密度。