数据结构——图

  • 图的定义和基本术语
  • 图的类型定义
  • 图的存储结构
    • 数组(邻接矩阵表示法)
    • 网(即有权图)的邻接矩阵表示法
    • 邻接表
      • 邻接表表示法(链式)
      • 图的邻接表存储表示
      • 采用邻接表表示法创建无向网
      • 邻接矩阵与邻接表表示法的关系
    • 十字链表——用于有向图
    • 邻接多重表(无向图的另一种链式存储结构)

图的定义和基本术语


图:G=(V,E)  Grapg = (Vertex, Edge)
  V:顶点(数据元素)的有穷非空集合;
  E:边的有穷集合

无向图:每条边都是无方向的
有向图:每条边都是有方向的

完全图:任意两点都有一条边相连

稀疏图:有很少边或弧的图(e < nlogn
稠密图:有较多边或弧的图
网:  边/弧带权的图
邻接: 有边/弧相连的两个顶点之间的关系
    存在(vi,vj),则称vi和vj互为邻接点;
    存在<vi,vj>,则称vi邻接到vj,vj邻接于vi
关联(依附):边/弧与顶点之间的关系
顶点的度:与该顶点相关联的边的数目,记为TD(v)
在有向图中,顶点的度等于该顶点的入度与出度之和
顶点 v 的入度是以 v 为重点的有向边的条数,记作 ID(v)
顶点 v 的出度是以 v 为始点的有向边的条数,记作 OD(v)

路径:接续的边构成的顶点序列
路径长度:路径上边或弧的数目/权值之和
回路(环):第一个顶点和最后一个顶点相同的路径
简单路径:除路径起点和终点相同外,其余顶点均不相同的路径

连通图(强连通图)
  有无(有)向图G =(V,{E})中,若对任何两个顶点 v、u 都存在从 v 到 u 的路径,则称G是连通图(强连通图)

权与网:
  图中边或弧所具有的的相关数称为权,表明从一个顶点到另一个顶点的距离或耗费;带权的图称为网

子图:
  设G =(V,{E})、G1 =(V1,{E1}),若V1⊆ V,E1⊆E,则称G1是G的子图

连通分量(强联通分量)

  • 无向图G的极大连通子图称为G的连通分量
    极大连通子图意思是:该子图是G连通子图,将G的任何不在该子图中的顶点加入,子图不再连通

  • 有向图G的极大强连通子图称为G的强连通分量
    极大强连通子图意思是:该子图是G的强连通子图,将D的任何不在该子图中的顶点加入,子图不再是强连通的

极小连通子图:该子图是G的连通子图,在该子图中删除任何一条边,子图不再连通
生成树:包含无向图G 所有顶点的极小连通图
生成森林:对非连通图,由各个连通分量的生成树的集合


图的类型定义


图的抽象数据类型定义如下:

ADT Graph{
  数据对象V:具有相同特性的数据元素的集合,称为顶点集
  数据关系R:R = {VR}
  VR = {<v,w>|<v,w>| v,w∈V ^ p(v,w),
  <v,w>表示从v到w的弧,p(v,w)定义了弧<v,w>的信息
  }
  CreateGraph(&G, V, VR)
    初始条件:V是图的顶点集,VR是图中弧的集合
    操作结果:按V和VR的定义构造图G
  DFSTraverse(G)
    初始条件:图G存在
    操作结果:按图进行深度优先遍历
  BFSTraverse(G)
    初始条件:图G存在
    操作结果:对图进行广度优先遍历
}ADT Graph

图的存储结构


图的逻辑结构:多对多

数组(邻接矩阵表示法)

  • 建立一个顶点表(记录各个顶点信息)和一个邻接矩阵(表示各个顶点之间关系)

    • 设图 A = (V,E)有n个顶点,则
    • 图的邻接矩阵是一个二维数组 A.arcs[n][n],定义为:


分析1:无向图的邻接矩阵是对称的
分析2:顶点i的度 = 第 i 行(列)中 1 的个数
特别:完全图的邻接矩阵中,对角元素为0,其余为1



注:在有向图的邻接矩阵中,
  第 i 行含义:以结点vi为尾的弧(即出度边)
  第 i 列含义:以结点vi为头的弧(即入度边)

分析1:有向图的邻接矩阵可能是不对称的
分析2:顶点的出度 = 第 i 行元素之和
     顶点的入度 = 第 i 列元素之和
     顶点的度 = 第 i 行元素之和 + 第 i 列元素之和

网(即有权图)的邻接矩阵表示法



邻接矩阵的存储表示:用两个数组分别存储顶点表和邻接矩阵

#define MaxInt 32767 //表示极大值,即∞
#define MVNum 100       //最大顶点数
typedef char VerTexType;    //设顶点的数据类型为字符型
typedef int ArcType;    //假设边的权值类型为整型typedef struct{VerTexType vexs[MVNum];     //顶点表ArcType arcs[MVNum][MVNum];        //邻接矩阵int vexnum, arcnum;       //图的当前点数和边数
}AMGraph;   // Adjacency Matrix Graph


采用邻接矩阵表示法创建无向网

算法思想:

  1. 输入总顶点数和总边数
  2. 依次输入点的信息存入顶点表中
  3. 初始化邻接矩阵,使每个权值初始化为极大值
  4. 构造邻接矩阵
//采用邻接矩阵表示法,创建无向网G
Status CreateUDN(AMGraph &G){cin >> G.vexnum >> G.arcnum;   //输入总顶点数,总边数for(i = 0; i < G.vexnum; ++i)cin >> G.vexs[i];           //依次输入点的信息for(i = 0; i < G.vexnum; ++i)   //初始化邻接矩阵for(j = 0; j < G.vexnum; ++j)G.arcs[i][j] = MaxLnt;     //边的权值均置为极大值//构造邻接矩阵for(k = 0; k < G.arcnum; ++k){cin >> v1 >> v2 >> w;     //输入一条边所依附的顶点及边的权值i = LocateVex(G, v1);j = LocateVex(G ,v2);      //确定v1和v2在G中的位置G.arcs[i][j] = w;           //边<v1, v2>的权值置为wG.arcs[j][i] = G.arcs[i][j];        //置<v1, v2>的对称边<v2, v1>的权值为w}return OK;
}//CreateUDN

补充算法:在图中查找顶点

//在图G中查找顶点u,存在则返回顶点表中的下标;否则返回-1
int LocateVex(AMGraph G, VertexType u){int i;for(i = 0; i < G.vexnum; ++i)if(u == G.vexs[i])    return i;return -1;
}





邻接表

邻接表表示法(链式)
  • 顶点:按编号顺序将顶点数据存储在一维数组中
  • 关联同一顶点的边(以顶点为尾的弧):用线性链表存储

无向图


特点:

  • 邻接表不唯一
  • 若无向图中有n个顶点、e条边,则其邻接表需n个头结点和2e个表结点。适宜存储稀疏图
  • 无向图中顶点vi的度为第i个单链表中的结点数

有向图

特点:

  • 顶点vi出度为第 i 个单链表中的结点个数
  • 顶点vi入度为整个单链表中邻接点域值是 i - 1 的结点个数(需要遍历整个链表)


特点:

  • 顶点vi入度为第 i 个单链表中的结点个数
  • 顶点vi出度为整个单链表中邻接点域值是 i - 1 的结点个数(需要遍历整个链表)


图的邻接表存储表示

typedef struct VNode{VerTexType data;        //顶点信息ArcNode * firstarc;       //指向第一条依附该顶点的边的指针
}VNode, AdjList[MVNum]      //AdjList表示邻接表类型

说明: 例如 AdjList v;    相当于:VNode v[MVNum];

#define MVNum 100                //最大顶点数
typedef struct ArcNode{         //边结点int adjvex;                    //该边所指向的顶点的位置       struct ArcNode * nextarc;   //指向下一条边的指针OtherInfo info;              //信息域;存储和边相关的信息
}ArcNode;

图的结构定义:

typedef struct{AdjList vertices;     //vertices--vertex的复数int vexnum, arcnum;        //图的当前顶点数和弧数
}ALGraph;



采用邻接表表示法创建无向网

算法思想:

  1. 输入总顶点数和总边数
  2. 建立顶点表
    依次输入点的信息存入顶点表中
    使每个表头结点的指针域初始化为NULL
  3. 创建邻接表
    依次输入每条边依附的两个顶点
    确定两个顶点的序号 i 和 j,建立边结点
    将此边结点分别插入到vi和vj对应的两个边链表的头部
//采用邻接表表示法,创建无向图G
Status CreateUDG(ALGraph &G){cin >> G.vexnum >> G.arcnum;       //输入总顶点数、总边数for(i = 0; i < G.vexnum; ++i){        //输入各点,构造表头结点表cin >> G.vertices[i].data;       //输入顶点值G.vertices[i].firstarc = NULL;  //初始化表头结点的指针域}//forfor(k = 0; k < G.arcnum; ++k){     //输入各边,构造邻接表cin >> v1 >> v2;             //输入一条边依附的两个顶点i = LocateVex(G, v1);j = LocateVex(G, v2);p1 = new ArcNode;                //生成一个新的边结点*p1p1 -> adjvex = j;             //邻接点序号为jp1 -> nextarc = G.vertices[i].firstarc;G.vertices[i]firstarc = p1;        //将新结点*p1插入顶点vi的边表头部p2 = new ArcNode;              //生成另一个对称的新的边结点*p2p2 -> adjvex = i;             //邻接点序号为ip2 -> nextarc = G.vertices[j].firstarc;G.vertices[j].firstarc = p2;   //将新结点*p2插入顶点vj的边表头部}//forreturn OK;
}



邻接矩阵与邻接表表示法的关系

  1. 联系:邻接表每个链表对应于邻接矩阵中的一行,链表中结点个数等于一行中非零元素的个数
  2. 区别:
    ① 对于任一确定的无向图,邻接矩阵是唯一的(行列号与顶点编号一致),但邻接表不唯一(链接次序与顶点编号无关)
    ② 邻接矩阵的空间复杂度为O(n2),而邻接表的空间复杂度为O(n+e)
  3. 用途:邻接矩阵多用于稠密图;而邻接表多用于稀疏图


十字链表——用于有向图


  十字链表(Orthogonal List)是有向图的另一种链式存储结构,可以将它看成有向图的邻接表和逆邻接表结合起来形成的一种链表

  有向图中的每一条弧对应十字链表中的一个弧结点,同时有向图中的每个顶点在十字链表中对应有一个结点,叫做顶点结点




邻接多重表(无向图的另一种链式存储结构)

邻接表优点:容易求得顶点和边的信息
   缺点:某些操作不方便(如:删除一条边需找表示此边的两个结点)

邻接多重表:

数据结构——图(存储结构)相关推荐

  1. 数据结构——图——存储结构——邻边矩阵

    数据结构--图--存储结构--邻边矩阵 考虑到图是由顶点和边或弧两部分组成.合在一起比较困难,那就很自然地考虑到分两个结构来分别存储.顶点不分大小.主次,所以用一个一维数组来存储是很不错的选择.而边或 ...

  2. 数据结构——图——存储结构——邻边表

    数据结构--图--存储结构--邻边表 邻接表的处理办法 1.图中顶点用一个一维数组存储,当然,顶点也可以用单链表来存储,不过数组可以较容易地读取顶点信息,更加方便.另外,对于顶点数组中,每个数据元素还 ...

  3. 数据结构图,图存储结构详解

    1. 数据结构的图存储结构 我们知道,数据之间的关系有 3 种,分别是 "一对一"."一对多" 和 "多对多",前两种关系的数据可分别用线性 ...

  4. 图 - 存储结构之邻接表

    对于图来说,邻接矩阵是不错的一种图存储结构,但是我们也发现,对于边数相对顶点较少的图,这种结构是存在对存储空间的极大浪费的.因此我们考虑另外一种存储结构方式:邻接表(Adjacency List),即 ...

  5. 【数据结构与算法】图论基础与图存储结构

    前言 由于后续更新好几篇文章都涉及到 图 这种数据结构,因此打算先普及一下 图 的相关理论支持,如果后面的相关内容有些点不太容易理解,可以查阅此篇文章.本文不建议一口气阅读完毕,可以先浏览一遍,在后续 ...

  6. 图很难理解?看这篇图论基础与图存储结构就够了

    点击上方↑↑↑蓝字关注我们~ 「2019 Python开发者日」,购票请扫码咨询 ↑↑↑ 作者 | 程序员吴师兄 转载自五分钟学算法(ID:CXYxiaowu) 1 前言 打算先普及一下图的相关理论支 ...

  7. pytorch默认初始化_小白学PyTorch | 9 tensor数据结构与存储结构

    [机器学习炼丹术]的学习笔记分享<> 小白学PyTorch | 8 实战之MNIST小试牛刀 小白学PyTorch | 7 最新版本torchvision.transforms常用API翻 ...

  8. 【小白学PyTorch】9.tensor数据结构与存储结构

    [机器学习炼丹术]的学习笔记分享 <<小白学PyTorch>> 小白学PyTorch | 8 实战之MNIST小试牛刀 小白学PyTorch | 7 最新版本torchvisi ...

  9. 数据结构-树存储结构

    目录 1.介绍 2.相关概念 树的结点: (1)树的结点: (2)父节点(双亲结点): (3)子节点(孩子结点): (4)兄弟结点: (5)堂兄弟结点: (6)树的根结点: (7)树的叶子结点: 子树 ...

  10. 数据结构理解——存储结构逻辑结构

    一.存储结构 存储结构就是数据在内存中的存储形式 连续的内存空间存储===>顺序存储结构 不连续的内存空间存储===>链式存储结构 每块内存之间都过保存其他内存地址实现链接起来 二.逻辑结 ...

最新文章

  1. 移除链表元素--虚拟头结点
  2. P7909 [CSP-J 2021] 分糖果 方法二
  3. create-react-app 脚手架工具完善自己所需要的入口文件
  4. Hidden Markov Model
  5. Redis基础(三)——数据类型
  6. python数据可视化字段_python数据爬取及数据可视化分析
  7. 【06月18日】A股滚动市净率PB历史新低排名
  8. 循环结构程序设计学习心得
  9. 富士通Fujitsu DPK700S 打印机驱动
  10. opencv部署onnx,并对jpg图片进行批量检测生成xml重要信息
  11. 阿里云短信服务(解决个人无法申请问题)
  12. 机器学习6:——Pandas——6:高级处理3:数据合并
  13. 对一个公益项目的探究(r8笔记第65天)
  14. 手把手教你学PowerBI数据分析:制作客户分析报告
  15. miniui的学习笔记(四)
  16. 山东超级计算机神威,世界最快超级计算机“神威·太湖之光”获得100多项应用成果...
  17. Python每日一练——第1天:水仙花数
  18. 科普——未知的公共免费WIFI存在的风险及隐患
  19. 看《赢在中国》的感悟
  20. Scrapy实战案例--抓取股票数据并存入SQL数据库(JS逆向)

热门文章

  1. error: command ‘D:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\x86_amd64\\cl.exe‘ f
  2. 在PyCharm中大型数据集indexing...加载缓慢的问题
  3. 构建线上线下一体化解决方案,旺小宝以AI赋能房企数智化营销|爱分析访谈
  4. app,h5落地页实现跳转快应用,可用于抖音,快手,头条投放链接
  5. JS图片img旋转、放大、缩小
  6. C++ VS项目属性的一些配置项的总结
  7. 操作系统相关基础知识
  8. 东华助手 v1.6.5
  9. vue+element-ui文件导出模板及导入xlsx文件
  10. 茂名天源石化宣传“世界急救日”活动 普及急救知识