图的常见存储结构及各自的优缺点
以下说法均建立在简单图上,即无环无重复边的图。
本文将介绍图的常见存储结构及各自的优缺点
- 邻接矩阵
- 邻接表
- 十字链表
- 邻接多重表
- 边集数组
邻接矩阵
用两个数组来表示图:一个一维数组存储图中顶点信息,一个二维数组(称为邻接矩阵)存储图中边(无向图)或弧(有向图)的信息
若图有n个顶点,则邻接矩阵则为一个n*n的方阵
定义为:
eg:
根据定义,可知对角线的值无论是无向图还是有向图均为0。
对于无向图,邻接矩阵是对称的,但有向图并无该特性。
优点:
容易获得每个顶点的度,特别是对于有向图,获得顶点i的出度,只需遍历第i行,即arc[i]的值,入度也只需遍历第i列,即arc[][i]。
缺点:
对于边数相对顶点较少的图,浪费了极大的存储空间。
邻接表
如上所述,顺序存储可能造成存储空间浪费的问题,所以就引出了链式存储结构。
- 对于顶点数组,每个数据元素需要存储指向第一个邻接点的指针。
- 每个顶点Vi的所有邻接点构成一个线性表,并用单链表存储;无向图称为顶点Vi的边表,有向图称为顶点Vi为弧尾的出边表
如图 - 顶点表的各个结点由data跟firstedge两个域表示。
data是数据域,存储顶点的信息,firstedge是指针域,指向此顶点的第一个邻接点。 - 边表结点由adjvex和next两个域组成。
adjvex是邻接点域,存储某顶点的邻接点在顶点中的下标,next则存储指向边表中下一个结点的指针。
但正如定义,对于有向图,邻接表只存储了各顶点相应的出边,若要便利地获得入度,则可以同理建立一个逆邻接表:对每个顶点都建立一个链接为Vi为弧头的表
缺点:
对于有向图,出度入度是不兼得的,要两样都获得就只能分别建立、遍历对应的邻接表和逆邻接表。空间利用率和效率也不高。
十字链表
把邻接表和逆邻接表结合起来,就得到了十字链表。所以十字链表也是专门为有向图设计的。
重新定义顶点表结点结构为:
firstin、firstout 分别指向入边表、出边表中的第一个结点重新定义边表结点结构为:
注意 tail、head分别指弧尾、弧头,不要混乱。
tailvex、headvex分别指弧起点(即弧尾)、弧终点(即弧头)在顶点表中的下标。
headlink是指入边表指针域,指向终点相同的下一条边(即弧头相同,所以命名为headlink);
taillink是指出边表指针域,指向起点相同的下一条边(即弧尾相同,所以命名为taillink)
当然了,并不是说十字链表一定比邻接表好,也是看实际需求是否需要同时访问出入度。
邻接多重表
既然十字链表是有向图的优化存储结构,那邻接表对于无向图有没有什么缺点呢?答案是肯定的。
若我们关注的重点是顶点,那邻接表自然是不错的选择;
但如果更关注边的操作,比如删除边(V0,V2)
我们就需要删除图中的两个阴影结点,显然是比较麻烦的。
所以邻接多重表就应运而生了。
- 重新定义边表结点结构为:
其中ivex、jvex是与某条边依附的两个顶点在顶点表中的下标,
ilink指向依附顶点 ivex的下一条边,同理,
jlink指向依附顶点 jvex的下一条边。
当然,因为是无向图,所以ivex跟jvex是什么顺序都是无所谓的,但为了绘图方便,此处将ivex值设置得与一旁顶点下标相同。
邻接多重表和邻接表的差别,仅仅在于同一条边在邻接表中用两个结点表示,而在邻接多重表中只有一个结点。
所以上述的删除(V0,V2)边,只需要把图中浅蓝色的边对应的链接指向改成^即可。
边集数组
邻接表关注的是顶点,十字链表则是对有向图的优化,但关注的重点仍然是顶点;邻接多重表则是对无向图的优化,关注重点是边。
那缺了什么了?没错,就是有向图的关注边的操作时所用的结构,就是本节所说的边集数组。
边集数组由两个一维数组构成。
一个存储顶点的信息(即顶点数组),
另一个是存储边的信息:边数组的每个数据元素由一条边的起点下表(begin)、终点下标(end)组成。
人如其名,边集数组关注的是边的集合。在边集数组中查找一个顶点的度需要扫描整个边数组,效率并不高。因此更适合与边相关的操作,而不适合对顶点相关的操作。
汇总
结构 | 优点 | 缺点 | 关注点 |
---|---|---|---|
邻接矩阵 | 通用性强 | 需求空间大 | |
邻接表 | 节省空间 | 对有向图无法兼备出度入度 | 顶点 |
十字链表 | 对有向图兼得出度入度 | 有向图、顶点 | |
邻接多重表 | 无向图边操作简单 | 无向图、边 | |
边集数组 | 有向图边操作简单 | 有向图、边 |
缺点为空并不代表没有缺点,关注点一列的对应的其实就是优点,反之则是缺点。
参考内容:《大话数据结构》
若有误欢迎指出。
图的常见存储结构及各自的优缺点相关推荐
- 图解图库JanusGraph系列-一文知晓“图数据“底层存储结构(JanusGraph data model)
图解图库JanusGraph系列-一文知晓"图数据"底层存储结构(JanusGraph data model) 大家好,我是洋仔,JanusGraph图解系列文章,实时更新 图数据 ...
- java对象底层原存储结构图解_图解图库JanusGraph系列-一文知晓“图数据“底层存储结构...
大家好,我是洋仔,JanusGraph图解系列文章,实时更新~ 图数据库文章总目录: 转载文章请保留以下声明: 一:存储模式 留言或私信我,邀请你加入"图数据库交流"微信群! 1. ...
- janusgraph整合mysql_图解图库JanusGraph系列-一文知晓“图数据“底层存储结构
527-7.jpg 大家好,我是洋仔,JanusGraph图解系列文章,实时更新~ 图数据库文章总目录: 版本:JanusGraph-0.5.2 转载文章请保留以下声明: 一:存储模式 留言或私信我, ...
- 图解图库Janusgraph系列-一文知晓图数据底层存储结构
Python实战社群 Java实战社群 长按识别下方二维码,按需求添加 扫码关注添加客服 进Python社群▲ 扫码关注添加客服 进Java社群▲ 作者丨匠心Java 来源丨匠心Java(code-t ...
- 图的邻接矩阵存储结构
如上图,我们能够把v0标记为0,v1标记为1.... 并把联通的2点权值全设置为1,那么能够用邻接矩阵(右图)来表示 概念解析: 第一个邻接顶点: 我们以vo为例,第一个邻接顶点为V1(事实上也能够使 ...
- 14 图的基础知识-几种常用的存储结构
时间有点紧 没时间接着更了..考完研回头再写吧 一.邻接矩阵 1.描述:用一维数组存储图顶点的信息 用二维数组存储图边的信息 2.特点: ①无向图的邻接矩阵: 是唯一的对称矩阵,可以压缩存储(仅存储 ...
- 图的存储结构(邻接矩阵和邻接表)
图的存储结构(邻接矩阵和邻接表) 前言: 前面我们学习图的有些定义和术语,对图这个数据结构有了新的见解和认知,让我们理解图结构的知识,今天我们学习图的存储结构,图的存储结构比较多,我们今天主要是学习邻 ...
- 图——基本的图算法(一)图的存储结构
图--基本的图算法(一)图的存储结构 1. 图的存储结构概述 对于图G=(V, E)来说,可以有两种标准的表示方法,一个是邻接矩阵,另一个是邻接链表,这两种方法都可以表示有向图和无向图.除此之外,图的 ...
- 数据结构-树存储结构
目录 1.介绍 2.相关概念 树的结点: (1)树的结点: (2)父节点(双亲结点): (3)子节点(孩子结点): (4)兄弟结点: (5)堂兄弟结点: (6)树的根结点: (7)树的叶子结点: 子树 ...
最新文章
- 奶粉运营,跑数据三个模板。
- 2020-12-09 深度学习 卷积核/过滤器、特征图(featue map)、卷积层
- Spring Cloud的架构
- OI生涯回忆录(二)
- C++基础18-抽象类-电脑组装练习
- bes2300 tws配对_tws 耳机春天来了!
- 物联网(IoT)的11大云平台:AWS、Azure、谷歌云、Oracle、
- busybox的使用
- mysql性能优化金字塔法则 下载_千金良方:MySQL性能优化金字塔法则 pdf版
- Android 使用低功耗蓝牙简单介绍
- SpringBoot 拦截器和过滤器区别及应用
- 关于清华大学C语言门事件
- figma对比sketch有什么优势和不足?
- Android——TextView指定字符串颜色高亮,实现类似微信、支付宝搜索结果中搜索字段高亮的效果
- 今晚直播 | 泰坦尼克号经典案例分析
- 【解决方案】STM32L152单片机驱动段码LCD屏,执行HAL_LCD_Init函数失败返回HAL_TIMEOUT,长时间卡在LCD_FLAG_RDY的while循环里面的解决办法
- negroni-gzip源代码分析
- Quartus-II 13 安装
- PhpSpreadsheet 学习和使用
- 清华教授三个小故事,讲透经济学