数据结构学习记录——什么是图(抽象数据类型定义、常见术语、邻接矩阵表示法、邻接表表示法)

简介: 数据结构学习记录——什么是图(抽象数据类型定义、常见术语、邻接矩阵表示法、邻接表表示法)

什么是图

表示“多对多”的关系

包含

 

抽象数据类型定义

类型名称:图(Graph)

数据对象集:G(V,E)由一个非空的有限顶点集合V和一个有限边集合E组成。


操作集:对于任意图G属于Graph,以及v属于V,e属于E


  • Graph Create();建立并返回空图
  • Graph InsertVertex(Graph G,Vertex v);将v插入G
  • Graph InsertEdge(Graph G,Edge e);将e插入G
  • void DFS(Graph G,Vertex v);从顶点v出发深度优先遍历图G
  • void BFS(Graph G,Vertex v);从顶点v出发宽度优先遍历图G
  • void ShortestPath(Graph G,Vertex v,int Dist[]);计算图G中顶点v到任意其他顶点的最短距离;
  • void MST(Graph G);计算图G的最小生成树

常见术语

无向图

无向图是由一组节点和连接这些节点的边组成的图形结构,其中边没有方向。

有向图

有向图是由节点和有方向的边组成的图形结构。每条边都有一个指定的方向,从一个节点指向另一个节点。这意味着在有向图中,边表示了节点之间的单向关系。

网络

网络是由节点和边组成的图形结构,其中边具有权值或称为权重。

这些权值可以表示节点之间的距离、成本、容量或其他度量。

邻接点

在图中,邻接点是指与给定节点直接相连的节点。对于无向图,如果两个节点之间有一条边,则它们互为邻接点。对于有向图,只有当一条边从节点 A 指向节点 B 时,节点 B 才是节点 A 的邻接点。

度(出度、入度)

在有向图中,度是指一个节点的边的数量。

而出度是从节点出发的边的数量,表示离开该节点的连接数;

入度是指指向节点的边的数量,表示指向该节点的连接数

稀疏图

稀疏图是指边相对较少的图。

或者说,稀疏图中节点之间的连接较少或边的数量相对较小。

稀疏图通常具有较低的边密度,节点之间的连接相对稀疏。

稠密图、完全图

稠密图是指边相对较多的图。

稠密图中节点之间的连接较多或边的数量相对较大。

稠密图具有较高的边密度,几乎每个节点都与其他节点相连。完全图是一种特殊的稠密图,其中每两个节点之间都存在一条边,也就是说,每个节点都与图中的其他节点直接相连。

边密度

对于无向图,可能的边数是 n(n-1)/2;

对于有向图,可能的边数是 n(n-1),其中 n 是节点数。

我们可以使用以下公式计算图的边密度:

d = m / (n(n-1)/2)

其中 m 是图中的边数,n 是节点数。

如果边密度接近 0,则该图被认为是稀疏图;如果边密度接近 1,则该图被认为是稠密图。

邻接矩阵表示法

用二维数组存储

邻接矩阵G[N] [N]——N个顶点从0到N-1编号

现在试着把下面这个图用邻接矩阵表示法表示出来

得到:

邻接矩阵的表达方式是比较简洁的,很直观地展示了节点之间的关系;

而且对于无向图来说,邻接矩阵是对称的。

用一维数组存储

对于无向图的存储,怎样可以省一半的空间?

我们利用它的对称性,就可以用一个长度为N(N+1)/2的一维数组A存储。

举个例子,假设有一个无向图,有四个节点 A、B、C、D,邻接矩阵如下:

如果我们只存储对角线以上的元素,那么邻接矩阵可以表示为:

数组A为:

 

邻接矩阵的好处

  • 直观、简单、好理解
  • 方便检查任意一对顶点间是否存在边
  • 方便找任一顶点的所有“邻接点”(有边直接相连的顶点)
  • 方便计算任一顶点的“度”

邻接矩阵的坏处

  • 浪费空间——存稀疏图有大量无效元素
  • 对稠密图(特别是完全图)还是十分合算的
  • 浪费时间——统计稀疏图中一共有多少条边

对于稀疏图而言,边的数量相对较少,很多节点之间并没有直接的连接。

因此,遍历整个邻接矩阵或邻接列表来计算边的数量将涉及大量的无效操作,导致时间和计算资源的浪费。

邻接表表示法

指针数组-链表存储

邻接表:G[N]为之指针数组,对应矩阵每行一个链表,只存非0元素

用邻接表表示法表示之前一样的图

对于网络,结构中要增加权重的域。

邻接表的特点

  • 方便找任一顶点的所有“邻接点”
  • 节约稀疏图的空间

需要N个头指针+2E个结点(每个结点至少2个域)

  • 对于无向图来说,方便计算任一顶点的“度”

而对于有向图,只能计算“出度”;需要构造“逆邻接表”(存指向自己的边)来方便计算“入度”

  • 方便检查任意一对顶点间是否存在边

end



目录
相关文章
|
算法 数据可视化 开发者
为什么要学习数据结构与算法
今天,我向大家介绍一门非常重要的课程——《数据结构与算法》。这门课不仅是计算机学科的核心,更是每一位开发者从“小白”迈向“高手”的必经之路。
为什么要学习数据结构与算法
|
存储 算法 C++
【C++数据结构——图】图的邻接矩阵和邻接表的存储(头歌实践教学平台习题)【合集】
本任务要求编写程序实现图的邻接矩阵和邻接表的存储。需掌握带权有向图、图的邻接矩阵及邻接表的概念。邻接矩阵用于表示顶点间的连接关系,邻接表则通过链表结构存储图信息。测试输入为图的顶点数、边数及邻接矩阵,预期输出为Prim算法求解结果。通关代码提供了完整的C++实现,包括输入、构建和打印邻接矩阵与邻接表的功能。
728 10
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
数据结构与算法系列学习之串的定义和基本操作、串的储存结构、基本操作的实现、朴素模式匹配算法、KMP算法等代码举例及图解说明;【含常见的报错问题及其对应的解决方法】你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习(8)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
416 59
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
1058 77
|
编译器 C语言 C++
栈区的非法访问导致的死循环(x64)
这段内容主要分析了一段C语言代码在VS2022中形成死循环的原因,涉及栈区内存布局和数组越界问题。代码中`arr[15]`越界访问,修改了变量`i`的值,导致`for`循环条件始终为真,形成死循环。原因是VS2022栈区从低地址到高地址分配内存,`arr`数组与`i`相邻,`arr[15]`恰好覆盖`i`的地址。而在VS2019中,栈区先分配高地址再分配低地址,因此相同代码表现不同。这说明编译器对栈区内存分配顺序的实现差异会导致程序行为不一致,需避免数组越界以确保代码健壮性。
250 0
栈区的非法访问导致的死循环(x64)

热门文章

最新文章