漫画:什么是 “图”?

2019 年 3 月 19 日 算法与数据结构

来自:程序员小灰(微信号:chengxuyuanxiaohui)




图的概念


究竟什么是图呢?大家先来想一想咱们常用的互联网产品。


举个栗子,大家一定都用过微信,假设你的微信朋友圈中有若干好友:张三、李四、王五、赵六、七大姑、八大姨。




而你七大姑的微信号里,又有若干好友:你、八大姨、Jack、Rose。




微信中,许许多多的用户组成了一个多对多的朋友关系网,这个关系网就是数据结构当中的图(Graph)


再举一个栗子,咱们在用百度地图的时候,常常会使用导航功能。比如你在地铁站A附近,你想去的地点在地铁站F附近,那么导航会告诉你一个最佳的地铁线路换乘方案。



这许许多多地铁站所组成的交通网络,也可以认为是数据结构当中的图。


图,是一种比树更为复杂的数据结构。树的节点之间是一对多的关系,并且存在父与子的层级划分;而图的顶点(注意,这里不叫节点)之间是多对多的关系,并且所有顶点都是平等的,无所谓谁是父谁是子。




图的术语


下面我们来介绍一下图的基本术语:



在图中,最基本的单元是顶点(vertex),相当于树中的节点。顶点之间的关联关系,被称为边(edge)


在有些图中,每一条边并不是完全等同的。比如刚才地铁线路的例子,从A站到B站的距离是3公里,从B站到C站的距离是5公里......这样就引入一个新概念:边的权重(Weight)。涉及到权重的图,被称为带权图(Weighted Graph)


还有一种图,顶点之间的关联并不是完全对称的。还拿微信来举例,你的好友列表里有我,但我的好友列表里未必有你。







这样一来,顶点之间的边就有了方向的区分,这种带有方向的图被称为有向图




相应的,在QQ当中,只要我把你从好友里删除,你在自己的好友列表里也就看不到我了。(貌似是这样)


因此,QQ的好友关系可以认为是一个没有方向区分的图,这种图被称为无向图



图的表示




邻接矩阵


拥有n个顶点的图,它所包含的连接数量最多是n(n-1)个。因此,要表达各个顶点之间的关联关系,最清晰易懂的方式是使用二维数组(矩阵)。


具体如何表示呢?我们首先来看看无向图的矩阵表示:




如图所示,顶点0和顶点1之间有边关联,那么矩阵中的元素A[0][1]与A[1][0]的值就是1;顶点1和顶点2之间没有边关联,那么矩阵中的元素A[1][2]与A[2][1]的值就是0。


像这样表达图中顶点关联关系的矩阵,就叫做邻接矩阵


需要注意的是,矩阵从左上到右下的一条对角线,其上的元素值必然是0。这样很容易想明白:任何一个顶点与它自身是没有连接的。


同时,无向图对应的矩阵是一个对称矩阵,V0和V1有关联,那么V1和V0也必定有关联,因此A[0][1]和A[1][0]的值一定相等。


那么,有向图的邻接矩阵又是什么样子呢?



从图中可以看出,有向图不再是一个对称矩阵。从V0可以到达V1,从V1却未必能到达V0,因此A[0][1]和A[1][0]的值不一定相等。


邻接矩阵的优点是什么呢?简单直观,可以快速查到一个顶点和另一顶点之间的关联关系。


邻接矩阵的缺点是什么呢?占用了太多的空间。试想,如果一个图有1000个顶点,其中只有10个顶点之间有关联(这种情况叫做稀疏图),却不得不建立一个1000X1000的二维数组,实在太浪费了。


邻接表和逆邻接表


为了解决邻接矩阵占用空间的问题,人们想到了另一种图的表示方法:邻接表。


在邻接表中,图的每一个顶点都是一个链表的头节点,其后连接着该顶点能够直接达到的相邻顶点。



很明显,这种邻接表的存储方式,占用的空间比邻接矩阵要小得多。


要想查出从顶点0能否到达顶点1,该怎么做呢?很简单,我们从顶点0开始,顺着链表的头节点向后遍历,看看后继的节点中是否存在顶点1。


要想查出顶点0能够到达的所有相邻节点,也很简单,从顶点0向后的所有链表节点,就是顶点0能到达的相邻节点。


那么,要想查出有哪些节点能一步到达顶点1,又该怎么做呢?这样就麻烦一些了,我们要遍历每一个顶点所在的链表,看看链表节点中是否包含节点1,最后发现顶点0和顶点3可以到达顶点1。



像这种逆向查找的麻烦,该如何解决呢?我们可以是用逆邻接表来解决。




逆邻接表顾名思义,和邻接表是正好相反的。逆邻接表每一个顶点作为链表的头节点,后继节点所存储的是能够直接达到该顶点的相邻顶点。


这样一来,要想查出有哪些节点能一步到达顶点1就容易了,从顶点1向后的所有链表节点,就是能一步到达顶点1的节点。


因此,我们可以根据实际需求,选择使用邻接表还是逆邻接表。




十字链表


十字链表长什么样呢?用最直观的表示,是下面这样:



如图所示,十字链表的每一个顶点,都是两个链表的根节点,其中一个链表存储着该顶点能到达的相邻顶点,另一个链表存储着能到达该顶点的相邻节点。


不过,我们没有必要把链表的节点都重复存储两次,所以简化后的十字链表如下:



图中蓝色箭头指向某顶点可到达的相邻顶点,橙色箭头指向可到达某顶点的相邻顶点,看起来可能有些乱。



总结


1.我们这一次介绍了图的定义和分类。根据图的边是否有方向,可分为有向图无向图。根据图的边是否有权重,可分为带权无权图。当然,也可以把两个维度结合起来描述,比如有向带权图,无向无权图等等。


2.图的表示方法有很多种。包括邻接矩阵、邻接表、逆邻接表、十字链表。(还有一种邻接多重表,有兴趣的小伙伴可以自学下)






—————END—————


●编号873,输入编号直达本文

●输入m获取文章目录

推荐↓↓↓

程序员求职面试

更多推荐25个技术类公众微信

涵盖:程序人生、算法与数据结构、黑客技术与网络安全、大数据技术、前端开发、Java、Python、Web开发、安卓开发、iOS开发、C/C++、.NET、Linux、数据库、运维等。

登录查看更多
0

相关内容

【2020新书】从Excel中学习数据挖掘,223页pdf
专知会员服务
90+阅读 · 2020年6月28日
最新《自动微分手册》77页pdf
专知会员服务
100+阅读 · 2020年6月6日
【实用书】流数据处理,Streaming Data,219页pdf
专知会员服务
76+阅读 · 2020年4月24日
【图神经网络(GNN)结构化数据分析】
专知会员服务
115+阅读 · 2020年3月22日
麻省理工学院MIT-ICLR2020《神经网络能推断出什么?》
专知会员服务
50+阅读 · 2020年2月19日
图解NumPy,这是理解数组最形象的一份教程了
机器之心
6+阅读 · 2019年7月12日
胶囊网络,是什么?
人工智能头条
32+阅读 · 2019年1月2日
干货 | 受限玻尔兹曼机基础教程
机器学习算法与Python学习
7+阅读 · 2018年3月27日
漫画: 什么是人工智能?
大数据技术
4+阅读 · 2018年1月19日
如何简单形象又有趣地讲解神经网络是什么?
算法与数据结构
5+阅读 · 2018年1月5日
神经网络中的「注意力」是什么?怎么用?
北京思腾合力科技有限公司
17+阅读 · 2017年10月28日
漫画:什么是Bitmap算法?
程序猿
3+阅读 · 2017年8月19日
Arxiv
4+阅读 · 2018年10月31日
Arxiv
5+阅读 · 2018年4月30日
Arxiv
13+阅读 · 2018年4月6日
Arxiv
3+阅读 · 2018年3月29日
VIP会员
相关VIP内容
【2020新书】从Excel中学习数据挖掘,223页pdf
专知会员服务
90+阅读 · 2020年6月28日
最新《自动微分手册》77页pdf
专知会员服务
100+阅读 · 2020年6月6日
【实用书】流数据处理,Streaming Data,219页pdf
专知会员服务
76+阅读 · 2020年4月24日
【图神经网络(GNN)结构化数据分析】
专知会员服务
115+阅读 · 2020年3月22日
麻省理工学院MIT-ICLR2020《神经网络能推断出什么?》
专知会员服务
50+阅读 · 2020年2月19日
相关资讯
图解NumPy,这是理解数组最形象的一份教程了
机器之心
6+阅读 · 2019年7月12日
胶囊网络,是什么?
人工智能头条
32+阅读 · 2019年1月2日
干货 | 受限玻尔兹曼机基础教程
机器学习算法与Python学习
7+阅读 · 2018年3月27日
漫画: 什么是人工智能?
大数据技术
4+阅读 · 2018年1月19日
如何简单形象又有趣地讲解神经网络是什么?
算法与数据结构
5+阅读 · 2018年1月5日
神经网络中的「注意力」是什么?怎么用?
北京思腾合力科技有限公司
17+阅读 · 2017年10月28日
漫画:什么是Bitmap算法?
程序猿
3+阅读 · 2017年8月19日
Top
微信扫码咨询专知VIP会员