【基础知识】| 作者 / Edison Zhou

这是恰童鞋骚年的第216篇原创文章


前面已经介绍了线性表和树两类数据结构,线性表中的元素是“一对一”的关系,树中的元素是“一对多”的关系,本章所述的图结构中的元素则是“多对多”的关系。图(Graph)是一种复杂的非线性结构,在图结构中,每个元素都可以有零个或多个前驱,也可以有零个或多个后继,也就是说,元素之间的关系是任意的。现实生活中的很多事物都可以抽象为图,例如世界各地接入Internet的计算机通过网线连接在一起,各个城市和城市之间的铁轨等等。

1图的基本概念

多对多的复杂关系

现实中人与人之间关系非常复杂,比如我认识的朋友,可能他们之间也互相认识,这不是简单的一对一、一对多、研究人际关系很自然会考虑多对多的情况。图是一种较线性表和树更加复杂的数据结构。在图形结构中,结点之间的关系可以是任意的,图中任意两个数据元素之间都可能相关。

定义:图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合。

在图中需要注意的是:

(1)线性表中我们把数据元素叫元素,树中将数据元素叫结点,在图中数据元素,我们则称之为顶点(Vertex)。

(2)线性表可以没有元素,称为空表;树中可以没有节点,称为空树;但是,在图中不允许没有顶点(有穷非空性)。

(3)线性表中的各元素是线性关系,树中的各元素是层次关系,而图中各顶点的关系是用边来表示(边集可以为空)。

纷繁冗多的术语

图的基本术语有很多,本文只挑选几个特别重要的来说明,其余的请阅读相关教材。

(1)无向图

如果图中任意两个顶点之间的边都是无向边(简而言之就是没有方向的边),则称该图为无向图(Undirected graphs)。

(2)有向图

如果图中任意两个顶点之间的边都是有向边(简而言之就是有方向的边),则称该图为有向图(Directed graphs)。

(3)完全图

① 无向完全图:在无向图中,如果任意两个顶点之间都存在边,则称该图为无向完全图。(含有n个顶点的无向完全图有(n×(n-1))/2条边)如下图所示:

② 有向完全图:在有向图中,如果任意两个顶点之间都存在方向互为相反的两条弧,则称该图为有向完全图。(含有n个顶点的有向完全图有n×(n-1)条边)如下图所示:

PS:当一个图接近完全图时,则称它为稠密图(Dense Graph),而当一个图含有较少的边时,则称它为稀疏图(Spare Graph)。

(4)顶点的度

顶点Vi的度(Degree)是指在图中与Vi相关联的边的条数。对于有向图来说,有入度(In-degree)和出度(Out-degree)之分,有向图顶点的度等于该顶点的入度和出度之和。

(5)邻接

① 若无向图中的两个顶点V1和V2存在一条边(V1,V2),则称顶点V1和V2邻接(Adjacent);

② 若有向图中存在一条边,则称顶点V3与顶点V2邻接,且是V3邻接到V2或V2邻接直V3;

PS:无向图中的边使用小括号“()”表示,而有向图中的边使用尖括号“<>”表示。

(6)路径

在无向图中,若从顶点Vi出发有一组边可到达顶点Vj,则称顶点Vi到顶点Vj的顶点序列为从顶点Vi到顶点Vj的路径(Path)。

(7)连通

若从Vi到Vj有路径可通,则称顶点Vi和顶点Vj是连通(Connected)的。

(8)权

有些图的边或弧具有与它相关的数字,这种与图的边或弧相关的数叫做权(Weight)。

2图的存储结构

图的存储结构除了要存储图中的各个顶点本身的信息之外,还要存储顶点与顶点之间的关系,因此,图的结构也比较复杂。

常用的图的存储结构有邻接矩阵和邻接表等。

邻接矩阵表示法

图的邻接矩阵(Adjacency Matrix)存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(称为邻接矩阵)存储图中的边或弧的信息。

(1)无向图:

我们可以设置两个数组,顶点数组为vertex[4]={v0,v1,v2,v3},边数组arc[4][4]为上图右边这样的一个矩阵。对于矩阵的主对角线的值,即arc[0][0]、arc[1][1]、arc[2][2]、arc[3][3],全为0是因为不存在顶点的边。

(2)有向图:

我们再来看一个有向图样例,如下图所示的左边。顶点数组为vertex[4]={v0,v1,v2,v3},弧数组arc[4][4]为下图右边这样的一个矩阵。主对角线上数值依然为0。但因为是有向图,所以此矩阵并不对称,比如由v1到v0有弧,得到arc[1][0]=1,而v到v没有弧,因此arc[0][1]=0。

不足:由于存在n个顶点的图需要n*n个数组元素进行存储,当图为稀疏图时,使用邻接矩阵存储方法将会出现大量0元素,这会造成极大的空间浪费。这时,可以考虑使用邻接表表示法来存储图中的数据。

邻接表表示法

首先,回忆我们在线性表时谈到,顺序存储结构就存在预先分配内存可能造成存储空间浪费的问题,于是引出了链式存储的结构。同样的,我们也可以考虑对边或弧使用链式存储的方式来避免空间浪费的问题。

邻接表由表头节点和表节点两部分组成,图中每个顶点均对应一个存储在数组中的表头节点。如果这个表头节点所对应的顶点存在邻接节点,则把邻接节点依次存放于表头节点所指向的单向链表中。

(1)无向图:下图所示的就是一个无向图的邻接表结构。

从上图中我们知道,顶点表的各个结点由data和firstedge两个域表示,data是数据域,存储顶点的信息,firstedge是指针域,指向边表的第一个结点,即此顶点的第一个邻接点。边表结点由adjvex和next两个域组成。adjvex是邻接点域,存储某顶点的邻接点在顶点表中的下标,next则存储指向边表中下一个结点的指针。例如:v1顶点与v0、v2互为邻接点,则在v1的边表中,adjvex分别为v0的0和v2的2。

PS:对于无向图来说,使用邻接表进行存储也会出现数据冗余的现象。例如上图中,顶点V0所指向的链表中存在一个指向顶点V3的同事,顶点V3所指向的链表中也会存在一个指向V0的顶点。

(2)有向图:若是有向图,邻接表结构是类似的,但要注意的是有向图由于有方向的。因此,有向图的邻接表分为出边表和入边表(又称逆邻接表),出边表的表节点存放的是从表头节点出发的有向边所指的尾节点;入边表的表节点存放的则是指向表头节点的某个顶点,如下图所示。

(3)带权图:对于带权值的网图,可以在边表结点定义中再增加一个weight的数据域,存储权值信息即可,如下图所示。

3小结

本篇介绍了图的基本概念、重要术语及两种不同的存储结构:邻接表和邻接矩阵。下一篇,我们会用C#代码来实现图的邻接表存储结构的实现(邻接矩阵容易造成空间资源的浪费)。

4参考资料

程杰,《大话数据结构》

陈广,《数据结构(C#语言描述)》

段恩泽,《数据结构(C#语言版)》

数据结构铁轨问题_每天5分钟用C#学习数据结构(20)图 Part 1相关推荐

  1. 数据结构实验之图论九:最小生成树_每天5分钟用C#学习数据结构(25)图 Part 6

    [基础知识]| 作者 / Edison Zhou 这是恰童鞋骚年的第221篇原创文章 上一篇介绍了非连通图如何实现遍历,本篇我们再来看看生成树与最小生成树,以及实现最小生成树的一个算法:Prim算法. ...

  2. 【完整目录】每天5分钟用C#学习数据结构

    [基础知识]| 作者 / Edison Zhou 这是恰童鞋骚年的第250篇原创内容 不知不觉,每天5分钟学习数据结构就更新完了,本篇将该系列所有文章整理起来作为一个目录,方便你的快速阅读. 1线性表 ...

  3. c# 插入数据到 uniqueidentifier_每天5分钟用C#学习数据结构(16)二叉树 Part 2

    [基础知识]| 作者 / Edison Zhou这是恰童鞋骚年的第209篇原创文章 上一篇开始了树与二叉树之旅,本篇会介绍二叉树的基本实现.1二叉树的代码实现 二叉树节点的定义实现 /// /// 二 ...

  4. 郝斌数据结构全套教程高清在线观看和下载-学习数据结构必看

    郝斌数据结构全套共78集 郝斌数据高清在线观看 https://www.bilibili.com/video/av49304765/ 郝斌数据高清在线观看 https://www.bilibili.c ...

  5. 数据结构和算法_零基础入门01

    数据结构和算法_零基础入门01 一.数据结构是什么? 逻辑结构.物理结构 二.算法 算法的五个基本特征 算法设计的要求 b站学习小甲鱼的数据结构与算法,自留笔记. 程序设计=数据结构+算法 一.数据结 ...

  6. JS数据结构与算法_链表

    上一篇:JS数据结构与算法_栈&队列 下一篇:JS数据结构与算法_集合&字典 写在前面 说明:JS数据结构与算法 系列文章的代码和示例均可在此找到 上一篇博客发布以后,仅几天的时间竟然 ...

  7. 学生搭配问题数据结构报告c语言,数据结构课程设计_学生搭配问题.doc

    数据结构课程设计_学生搭配问题 数据结构课程设计 题 目: 学生搭配问题 学 院: 班 级: 学 生 姓 名: 学 生 学 号: 指 导 教 师: 2012 年 12 月 3 日 课程设计任务书 姓名 ...

  8. 数据结构java教学计划编排_数据结构课程设计_教学计划编制问题

    数据结构课程设计_教学计划编制问题 (教学计划编制问题)目 录1.需求分析 -------.3-52.概要设计 -------.6-83.详细设计 ------ 8-134.调试分析 ------ 1 ...

  9. 数据结构稀疏矩阵的加法十字链表_学习数据结构和算法的框架思维

    ----------- 通知:如果本站对你学习算法有帮助,请收藏网址,并推荐给你的朋友.由于 labuladong 的算法套路太火,很多人直接拿我的 GitHub 文章去开付费专栏,价格还不便宜.我这 ...

最新文章

  1. leetcode刷题笔记342 4的幂
  2. TF之CNN:CNN实现mnist数据集预测 96%采用placeholder用法+2层C及其max_pool法+隐藏层dropout法+输出层softmax法+目标函数cross_entropy法+
  3. WuJiuVideoX视频小说图片站群程序开源源码
  4. 一键自动生成数据库文档,炫!(告别CV大法)
  5. SQL JOIN,你想知道的应该都有
  6. 基于CC2430的Zigbee的第一个实验
  7. 2022年11月(下半年)信息系统项目管理师考试-综合知识真题及解析
  8. 香槟分校计算机研究生专业,2019伊利诺伊大学香槟分校计算机专业申请要求
  9. 一个SAP开发人员的双截棍之路
  10. 【QCM2150】WCN3680 WFA认证关于不同带宽配置
  11. Cannot connect:由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。192.168.0.113:22
  12. s3cmd 快速评估RADOSGW的性能
  13. 曾有一个人,爱我如生命(2)
  14. java-net-php-python-java智能会议管理系统计算机毕业设计程序
  15. appium(2)简单的demo、元素定位
  16. LAMMPS后处理以及编程技巧
  17. Macbook上怎么隐藏文件和文件夹
  18. Ubuntu配置全局系统代理(常用工具配置)
  19. 注册表编辑器打开方法
  20. 真·屠龙之术 | 一次SparkSQL性能分析与优化之旅及相关工具小结

热门文章

  1. java代码防止sql注入_动态Java代码注入
  2. java使用泛型后消除泛型_如何以及何时使用泛型
  3. java 排序性能_Java8排序–性能陷阱
  4. Java,JavaFX的流畅设计风格滑块
  5. jvm 性能_JVM性能魔术
  6. 配置Jenkins以连续交付Spring Boot应用程序
  7. github gists_Eclipse中的Github Gists
  8. Spring安全性和密码编码
  9. 返回CompletableFuture:Java 8功能亮点
  10. NetBeans Java EE技巧9:从数据库创建JSF应用程序