声明:本次写的文章属于系列文章,主要介绍数据结构中的图的使用、应用场景、以及算法实现。本系列文章会围绕下面的结构来写,本篇文章首先介绍《什么是图?》《如何去表述图?》。
什么是图呢?学习过数据结构的童鞋肯定早有耳闻,但是多数又是望而却步。通常大家都会惧怕自己不清楚的知识,直觉的会感觉这个不会的东西会特别复杂,同样,我也不例外。这个时候,谁能抵制住这个直觉,就会先人一步啦。呀呀,怎么开始抒情了,注意…正片开始!!!
直观的理解图的美貌
每个人城里人都有微信,像我这种村里的可能没有 ,闭上眼试想,你的好友 列表里有你的虎妈、严爸、女朋友,你的女朋友的好友列表里有你妈、你爸、你和老王。这样的关系,用线连接在一起,就构成了多对多的朋友关系网,这个关系网就是数据结构当中的图(Graph)。
再比如你去坐地铁,村里人也是坐不上地铁的 ,买卡的时候,你会看到显示器上犬牙交错的地铁线路,这样的交通网络,也是数据结构中的图。
图的基本术语
什么是顶点和边呢?官方说法:在图中,最基本的单元是顶点(vertex),相当于树中的节点。顶点之间的关联关系,被称为边(edge)。如果不理解,你可以这样想,你、你女朋友,还有老王,都作为关系网中的顶点,你女朋友和老王的关系,可以看做边。
什么是带权图、无权图?图的边可以分为有权重的和无权重的,所以,就有了带权图和无权图。那…什么又是权重呢?假如,关系图中亲密度,你和女朋友的亲密度肯定大于你女朋友和老王的亲密度,如果bushi… ,这种亲密度的大小就可以表示权重的大小。
什么是有向图、无向图?顶点之间的关联并不是完全对称的,存在这个关系的方向性的图,就是有向图。比如,你惹你女盆友生气了,你想给他发微信哄哄她,发完亲密的消息怎么有个红色的感叹号,凉凉,你被删了。这种单方面被删了的关系图就是有向图。你的好友列表还有女朋友,然而,人家早把你删了。所以微信的用户关系网就是有向图。这时,你又去QQ好友列表找女朋友,唯一的一个特别关心怎么没有了,凉凉,你也被删了。所以QQ的用户关系网就是无向图。
如何去表示图呢?
图在内存中存储的方式有很多种,包括邻接矩阵、邻接表、逆邻接表、十字链表。
下面,首先用邻接矩阵描述一下无向图,矩阵中的元素表达的是各个顶点之间的关联关系。
无向图中V0和V1相互连通,矩阵中对应位置存储1,V1和V2没有连通,对应位置存储0。像上面这样描述顶点之间关系的矩阵称为邻接矩阵。同时,发现没有,无向图的邻接矩阵还是一个对称矩阵呢。
有向图的邻接矩阵的描述规则和上面是一样的,显然,有向图可能大部分情况下不是对称矩阵了。
仔细观察一下,这个邻接矩阵有什么缺点吗?有时候,是不是比较浪费内存,比如,有1000个女生,和你有关系的就只有你女朋友,其他的你不敢啊 ,这种关系图用邻接矩阵描述的确不妥。
这样,为了解决邻接矩阵占用空间的问题,邻接表和逆邻接表就出现了。
在邻接表中,图的每一个顶点都是一个链表的头结点,后面连接着该顶点可以直接到达的相邻顶点。这样想要查询V0可以直接到所有相邻顶点,就非常方便了。
要是想查询什么顶点可以直接到达V0顶呢?逆邻接表就出现了,同理,逆邻接表的每一个顶点作为链表的头结点,后继顶点连接的是所有直接能到达该顶点的相邻节点。
这里再仔细想想,难道这样就没问题了吗?一个图要维护两个邻接表有点麻烦啊。
为了解决上面这个问题,十字链表又出现了,先驱们一定会注意到这些问题的。十字链表的每一个顶点,都是两个链表的根节点,其中一个链表存储着该顶点能直接到达的相邻顶点,另一个链表存储着能直接到达该顶点的相邻节点。
当然,上图仅是示意图,我们没有必要把链表的结点都重复的存储两次。在优化之后的十字链表中,链表的每一个节点不再是顶点,而是一条边(诸如01、02、23),里面包含着起止顶点的下标。
这里可能有点不好理解,注意力要集中啊,不要再想女朋友和老王了 。图中每一个带有蓝色箭头的链表,存储着从顶点出发的边;每一个带有橙色箭头的链表,存储着进入该顶点的边。仔细揣摩一下。
到这里,正题就写完了,主要讲了什么是图?顶点、边、带权图、有向图、邻接矩阵、邻接表、十字链表等相关的概念,上面的描述方式,带有趣味性,无其他含义。后面会相继介绍,图的深度优先遍历、广度优先遍历、迪杰斯特拉、弗洛伊德等算法。文中的图部分借鉴公众号程序员小灰。
来源:CSDN
作者:白茶-清欢
链接:https://blog.csdn.net/zhao_ke_xue/article/details/104801539