[数据结构与算法]16 什么,图这种数据结构把你难住了?!_还把你难住了呀-程序员宅基地

技术标签: 数据结构与算法  

你是不是和我一样,在学习数据结构与算法时,了解了一下图这种数据结构之后,根本不知道它的用武之地在哪里?
在我查了资料之后,现在我可以跟你讲讲,图可以这么用!

概念介绍

先来了解一下什么是图.
图,是一种非线性表数据结构.
那么你可能会问了,什么是线性表结构哇,我怎么区别一种数据结构是线性的,还是非线性的呢.
哈哈,还好我机智,在这篇文章之前就写了一篇文章来介绍,如果还有疑问,楼上雅座请: [数据结构与算法]14 搞不懂线性结构,非线性结构?

在图中元素叫做顶点( vertex ),图中的一个顶点可以和其他任意顶点建立连接关系,这种建立的关系叫做边( edge )

无向图

在这里插入图片描述
上面给出的是无向图.看到这里你可能就觉得比较疑惑,这个无向图看起来没啥呀,怎么会有这种数据结构呢?
不知道你是怎么想的,我刚开始学的时候就有这种疑问,这是什么神仙数据结构哇,还会有应用场景?
在这里插入图片描述
既然有疑惑,那就给个应用场景:
假设,现在你和我是微信好友,那是不是应该你的好友列表里面有我,我的好友里面有你,这样咱们才是好友对不对~
那在数据库中如何表示呢?吼~这个时候无向图就登场了
你和我是微信好友,那就在咱俩之间来条线,表示咱俩之间有关系,一条线就解决了问题,真是完美至极啊
假设,(怎么又是假设,哈哈哈)上图中表示的就是 A,B,C,D,E,F 之间的关系,那你可能就发现问题了,有的顶点线比较多,比如 D 有四条线,有的就相对少一些,比如 B 有两条线.这些线就表示顶点的度( degree ).这个概念有啥用?
能一眼看出来谁的好友多!那这个功能有啥用?(好吧,这个功能好像是有点儿鸡肋,不过也算是一个应用场景

有向图

看到上面的无向图,基础不错的小伙伴肯定会说了,我还知道有向图呢!
呦呵,不错,有向图就是下面这个样子:
在这里插入图片描述
在无向图中,咱们知道一个顶点有多少条边,就说它的度为多少.
在有向图中呢,有指向顶点的,也有从顶点指出去的,基于无向图的概念,咱们把从这个顶点指出去的边称为出度,指向该顶点的边称为入度.
那么有向图会应用在哪些场景呢?微信好友这个场景是不太可以了
那么微博呢?
微博和微信有什么不一样呢?微信是你和我是好友,那么咱们的好友列表里一定是要有彼此的,拉黑或者删除彼此了,那就不能互相发送消息了.
但是微博呢?你关注了我,并不代表我就要关注你对吧?看到这里有没有一种豁然开朗的感觉~
那么我关注了多少人就是出度,多少人关注了我就是入度.
这样带入理解是不是会比较好一点儿?(我可真是个天才,哈哈哈

带权图

看完了无向图,有向图,相信就有人说,我还见过带权图!(陈独秀给我坐下!
带权图长啥样呢?就下面这个样子:
在这里插入图片描述
懵逼了,这每条边上的数字是个什么鬼呦
别急,咱们来个场景:大家都玩 QQ 嘛?(别跟我说不玩,配合一下嘛…
玩 QQ 的话,一定知道有 QQ 空间,然后空间里面有个「谁在意我」「我在意谁」的功能,就是下图:
在这里插入图片描述
那么有没有好奇过呢? QQ 怎么知道我在意谁,谁在意我呢?
就是通过带权图哇
你访问了一个人的空间,这条边的权重就增加一点儿;别人访问了你的空间,那这条边的权重就增加一点儿;这段时间你们两个人聊天聊得比较频繁,来个小火花,顺便在你们两者之间的边权重增加一点儿.然后根据这些边的权重从大到小排序就得出了「谁在意我」「我在意谁」

到这里,上面的一切理解都还 OK ?
那咱们继续.图是怎么表示的呢?
图这种数据结构,再怎么画顶点,画边,到最后在物理结构上是怎么存储的呢?
别急,你所疑惑的,我都帮你想到了

图的存储方法

图的存储方法主要有以下两种:

  • 邻接矩阵

邻接矩阵的底层依赖一个二维数组.对于无向图来说,如果 i 与 j 之间有边,那就将 A[i][j] 和 A[j][i] 标记为 1 ;对于无向图来说,如果 i 指向 j ,那么 A[i][j] 值为 1 ,如果 j 指向 i ,那么 A[j][i] 值为 1 ;对于带权图来说, A[i][j] 存储的值就不是 1 了,而是对应的权重值.所以这是图最直观的一种存储方法.
啥,你跟我说这还不直观?该不会是没有看下图吧:
在这里插入图片描述
但是你发现问题了嘛,这样看起来确实是直观了很多,但是很浪费空间有没有!比如无向图,如果 A[i][j] 为 1 ,那么 A[j][i] 肯定也是 1 ,多存储 A[j][i] 根本没啥必要.就像买东西,明明一块钱能买到的东西,为啥非要花两块钱?
所以如果使用邻接矩阵来表示的话,一定要清楚它的缺点.

但这并不是说,使用邻接矩阵来存储就没啥优点.这天底下哪儿有那么绝对的事情呢.
首先,邻接矩阵的存储方式简单,直接,所以当我们需要获取两个顶点之间的关系时,相信我没有比这种存储结构更高效的了.
还有就是使用邻接矩阵存储图的另外一个优点就是方便计算,因为可以将很多图的运算转换成矩阵之间的运算.

  • 邻接表

先来看图:
在这里插入图片描述
乍一看,这不是散列表嘛!每个顶点对应一条链表,链表中存储的是与这个顶点相连接的其他顶点.
嘿嘿,直觉超棒!

如果你对散列表熟悉的话,应该知道,在散列表中,如果链太长了,会导致冲突概率增大,复杂度也蹭的一下升高.而且吧,链表的存储方式你也知道,不是连续的,所以相对于数组来说, CPU 读取就会慢一些,相对于邻接矩阵的存储方式,在邻接表中查询两个顶点之间的关系就没那么高效了.
所以在实际开发中要注意遇到这种情况该如何处理,或者在刚开始的时候就直接设计好实现方式.比如可以将邻接表中的链表改为平衡二叉树,或者红黑树.

我觉得对于数据结构来说,没有最好的,只有最合适的~

参考

  • 极客时间—<数据结构与算法之美>

以上,就是想要分享的内容了
感谢您的阅读哇

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zll_0405/article/details/105209800

智能推荐

Python输出时出现乱码“�밴���������. . . ”的解决方案-程序员宅基地

文章浏览阅读3.2k次,点赞6次,收藏4次。输出时出现“�밴���������. . . ”乱码解决方案左上角File下点击Setting...点击File Encodings修改Global Encoding为GBK重新运行程序不再出现乱码_. . .

Unity3D研究院之mac上从.ipa中提取unity3D游戏资源(六十六)-程序员宅基地

文章浏览阅读1.9k次。http://www.xuanyusong.com/archives/2584感谢今天某大神(既然是大神名子我当然要保密喽)告诉我Disunity更新了,不然我还不知道。以前很多人都说用Disunity提取出了Unity3D资源,但是我在Mac上从来没有成功过,一直在报错。https://github.com/ata4/disunity/releases 在这里可以看到Disu

到底怎样的程序员能称为架构师?-程序员宅基地

文章浏览阅读197次。我曾问过很多自称热爱代码的程序员的发展规划,大多都回答说期望成为一名架构师。而在招聘一方,有的团队会过滤掉多次提起架构一词而一点不提具体内容的简历。可见,虽然在大多数程序员眼里,架构师是神圣的,但又不得不承认事实是:“架构”和“架构师”是最常被滥用的。那些写能 PPT 而不能写代码的人,只做和事佬而不考虑软件快、稳、便捷的人,都称不上做“架构”更别提“架构师”。那么什么样的人可以称为“架构师”..._程序员中最厉害是架构师吗

基于QT4的TCP/UDP客户端程序设计_qt4 tcp-程序员宅基地

文章浏览阅读851次。文章转自: http://blog.sina.com.cn/s/blog_705adafb0101g00d.html设计一个基于QT的客户端程序,该程序使用tcp和udp与服务器端通讯,应用层协议为iec103协议,客户端与服务器端建立tcp连接,交互通讯流程采用tcp方式,定时报文传输采用udp方式,本客户端处理tcp和udp通讯,对应用层数据报文解析后提供回调接口供应用使用,并提供接口供应用..._qt4 tcp

maven项目:重新编译生成class文件_maven重新编译-程序员宅基地

文章浏览阅读1.3w次。原因:由于误删或更新了内容,且不能自动编译时,手动调节。解决步骤:手动clean-maven项目:项目==》右键:run as ==》maven clean 手动输入clean-maven命令:项目==》右键:run as ==》maven build ==》Goals:clean intall package ==》Apply Runclass文件重新生成:OK!..._maven重新编译

前端面试题集锦(一)-程序员宅基地

文章浏览阅读160次。温馨提示:经常看一些面试题,能够很好的对自己进行查缺补漏,检验自己的能力。1、写出transform中2D转换的几大属性及其作用:答:①translate():根据坐标原点,浏览器左上角(0,0)进行X轴、     Y轴上的位置移动    ②rotate():根据X轴进行旋转,正值时为顺时针,负值时为逆时针。(deg单位)    ③scale(parm1,parm2):根据原大小对其进行放大缩小功能,参数一二对应width和height,和X轴、Y轴。    ④skew(parm1,parm

随便推点

[Python数据分析] 5-挖掘建模(监督学习)_name = column_list[i]-程序员宅基地

文章浏览阅读764次。# I.理论部分:机器学习是过程,模型是这个过程的结果# 1)机器学习和建模# i.学习:通过接收到的数据,归纳提取相同与不同# ii.机器学习:让计算机以数据为基础,进行归纳和总结# iii.模型:数据解释现象的系统# 2)数据集:通常来说各部分占比:训练集6:验证集2:测试集2# i.训练集:训练拟合模型# ii.验证集:通过训练集训练出多个模型后,使用验证集数据纠正或比较预测..._name = column_list[i]

springboot gradle 使用过程中遇到的问题小结(6)_android expected a single classpath entry, found: -程序员宅基地

文章浏览阅读194次。1. 报错:Cannot deserialize instance of java.lang.String out of START_OBJECT token,我这里报这个错的原因是传递的json数据类型不对,修正后即可2. 使用JsonFormat引起的时间比正常时间慢8小时,@JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GM..._android expected a single classpath entry, found: []

16.忽略大小写的字符串比较_16:忽略大小写的字符串比较-程序员宅基地

文章浏览阅读4.3k次。描述一般我们用strcmp可比较两个字符串的大小,比较方法为对两个字符串从前往后逐个字符相比较(按ASCII码值大小比较),直到出现不同的字符或遇到'\0'为止。如果全部字符都相同,则认为相同;如果出现不相同的字符,则以第一个不相同的字符的比较结果为准(注意:如果某个字符串遇到'\0'而另一个字符串还未遇到'\0',则前者小于后者)。但在有些时候,我们比较字符串的大小时,希望忽略字母的大小_16:忽略大小写的字符串比较

使用labelme制作自己的语义分割数据集_使用labelme训练自己的语义分割流程-程序员宅基地

文章浏览阅读1.4k次,点赞2次,收藏24次。安装labelme在cmd中激活我们使用的python环境,然后使用pip命令安装labelme,命令如下:pip install labelme==3.16.7注意:如果安装最新版本的 labelme,就无须指定版本号(3.16.7就是版本号)打开labelme在cmd中激活我们使用的python环境,然后使用下面的命令,就可以打开labelme软件:labelme界面如下图:使用labelme对数据集进行标注标注之前我们可以先设置一下自动保存:file——>Sav_使用labelme训练自己的语义分割流程

跟随小破站学习java web第十五天_小破站的学习陪伴-程序员宅基地

文章浏览阅读262次。file_upload.jsp<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><h..._小破站的学习陪伴

java解析定长文件入库_java-当直到运行时才知道记录布局时,使用哪种方法来解析具有固定长度记录的文件?...-程序员宅基地

文章浏览阅读392次。我想基于另一个文件中提供的记录布局来解析文件.基本上会有一个定义文件,它是一个用逗号分隔的字段及其各自长度的列表.其中会有很多,每次我运行程序时都会加载一个新的.firstName,text,20middleInitial,text,1lastName,text,20salary,number,10然后,我将显示一个带有提供的列标题的空白表,以及一个通过单击按钮或其他方式添加数据的选项-我尚未决定..._java 文本文件定长记录

推荐文章

热门文章

相关标签