【数据结构】图论基础

文章目录
- 图的概念
- 图的基本概念
- 图的类型
- 图的表示方法
- 图的相关基本概念
- 1. 路径(Path)
- 2. 连通性(Connectivity)
- 3. 图的度(Degree)
- 4. 子图(Subgraph)
- 5. 生成树(Spanning Tree)
- 6. 二分图(Bipartite Graph)
- 7. 拓扑排序(Topological Sort)
- 8. 欧拉图和哈密顿图
- 实现图
- 邻接矩阵实现图
- 邻接矩阵的基本框架
- 核心接口
- 邻接表实现图
- 邻接表实现图的基本框架
- 核心接口
- 总结
图的概念
图(Graph)是离散数学中的一种重要数据结构,用于描述对象(称为顶点,或节点)之间的关系(称为边)。图可以表示各种事物之间的连接关系,比如网络中的路由器、社交网络中的用户、城市之间的道路等。
图的基本概念
-
顶点(Vertex):
- 图中的基本单位,也称为节点(Node)。一个图通常由若干个顶点组成,用来表示实体或对象。
-
边(Edge):
- 顶点之间的连接关系称为边。边可以是有方向的(有向图)或无方向的(无向图)。在无向图中,边表示双向关系;在有向图中,边表示单向关系。
-
有向图(Directed Graph, Digraph):
- 在有向图中,边是有方向的,表示从一个顶点指向另一个顶点的单向连接。通常用有向边表示诸如“影响”或“依赖”的关系。

- 在有向图中,边是有方向的,表示从一个顶点指向另一个顶点的单向连接。通常用有向边表示诸如“影响”或“依赖”的关系。
-
无向图(Undirected Graph):
- 无向图中的边没有方向,表示两个顶点之间的对称关系,如“相邻”或“连接”。

- 无向图中的边没有方向,表示两个顶点之间的对称关系,如“相邻”或“连接”。
-
邻接(Adjacency):
- 如果两个顶点之间有一条边连接,这两个顶点称为邻接的。
-
度(Degree):
- 一个顶点的度是连接到该顶点的边的数目。在有向图中,区分入度(In-degree)和出度(Out-degree),分别表示进入该顶点和从该顶点发出的边的数量。
图的类型
-
稀疏图(Sparse Graph):
- 边的数量远远少于顶点数量的平方(E << V²),大部分顶点之间没有边连接。
-
稠密图(Dense Graph):
- 边的数量接近顶点数量的平方(E ≈ V²),大多数顶点之间有边连接。
-
加权图(Weighted Graph):
- 图中的每条边带有一个权重,用来表示顶点之间的某种度量,如距离、成本或容量。
-
连通图(Connected Graph):
- 对于无向图,若任意两个顶点之间都有路径相连,则称为连通图。有向图中则需区分强连通和弱连通。
-
简单图(Simple Graph):
- 不包含自环和多重边的图。自环是指从顶点到自身的边,多重边是指两个顶点之间存在多条边。
-
完全图(Complete Graph):
- 图中任意两个顶点之间都有边相连,通常表示为 K n K_n Kn,其中 n n n 是顶点数。
图的表示方法
-
邻接矩阵(Adjacency Matrix):
- 使用一个二维矩阵来表示顶点之间的连接关系,矩阵中的元素表示边的存在性或权重。
-
邻接表(Adjacency List):
- 对每个顶点,维护一个链表(或数组)来存储与之相邻的顶点列表,适合稀疏图。
-
边集列表(Edge List):
- 直接列出图中所有的边,用边的起点和终点来描述,适合图的遍历或算法中的具体操作。
图的相关基本概念
在理解图的结构和操作时,有一些与图密切相关的概念有助于更好地分析和处理图的算法和应用。
1. 路径(Path)
路径是在图中从一个顶点到另一个顶点的行进序列,它由一系列边和顶点组成。根据图的类型和要求,路径可以分为几类:
- 简单路径(Simple Path):路径中的顶点不重复出现。
- 回路(Cycle):路径的起点和终点是同一个顶点,且路径中的其他顶点不重复。

2. 连通性(Connectivity)
图的连通性描述了图中顶点与顶点之间的可达性。
- 连通图(Connected Graph):对于无向图,如果从任意一个顶点能到达其他所有顶点,则图是连通的。
- 强连通图(Strongly Connected Graph):对于有向图,如果任意两个顶点之间都有路径相通,则图是强连通的。
- 弱连通图(Weakly Connected Graph):对于有向图,如果将其所有边看作无向边,能够使整个图连通,则图是弱连通的。

3. 图的度(Degree)
图中一个顶点的度表示与该顶点连接的边的数量。
- 入度(In-degree):有向图中指向该顶点的边的数量。
- 出度(Out-degree):有向图中从该顶点发出的边的数量。

4. 子图(Subgraph)
子图是从原始图中选取部分顶点和边构成的图。常见的子图类型包括:
- 生成子图(Spanning Subgraph):包含图的所有顶点,但边可能有所删减。
- 诱导子图(Induced Subgraph):包含图中某些顶点及这些顶点之间的所有边。

5. 生成树(Spanning Tree)
生成树是无向图的一个子图,包含图中的所有顶点,且是一个树形结构(无环、连通)。
- 最小生成树(Minimum Spanning Tree, MST):在加权图中,生成树的边权和最小的生成树。
生成树:

最小生成树:

6. 二分图(Bipartite Graph)
二分图是一种特殊的图,可以将顶点集合分为两个不相交的子集,且所有边都连接两个不同子集中的顶点,而子集中没有内部连接。

7. 拓扑排序(Topological Sort)
对于有向无环图(DAG),拓扑排序是一种将顶点按依赖关系线性排序的算法,通常用于解决调度、依赖管理等问题。
8. 欧拉图和哈密顿图
- 欧拉路径(Eulerian Path):经过图中每条边一次且仅一次的路径。如果这样的路径是闭合的,即路径的起点和终点相同,则称为欧拉回路(Eulerian Circuit)。
- 哈密顿路径(Hamiltonian Path):经过图中每个顶点一次且仅一次的路径。如果这样的路径是闭合的,则称为哈密顿回路(Hamiltonian Circuit)。
实现图
邻接矩阵实现图

如果是无向图的话,那么邻接矩阵就是沿着对角线对称的。

如果是无向图的话,那么就可以通过压缩只存储一半。
除了需要一个存储权值的邻接矩阵我们还需要一个vector来存储顶点,如果涉及到邻接矩阵,那么就会涉及到下标,所以我们应该还需要一个顶点映射下标的map。
邻接矩阵的基本框架
// 顶点 weight 有向图/无向图 template<class V, class W, W MAX_W = INT_MAX, bool Direction = false>class Graph{public:private:vector<V> _vertexs; //顶点集合map<V, int> _indexMap; //顶点对应下标的关系(顶点---->下标)vector<vector<W>> _matrix; //邻接矩阵};
}
核心接口
初始化
Graph(const V* a, size_t n)
{// 开辟n个空间_vertexs.resize(n);for (size_t i = 0;i < n;i++){_vertexs[i] = a[i];//顶点----->下标_indexMap[a[i]] = i;}_matrix.resize(n);//权值用MAX_W初始化for (size_t i = 0;i < n;i++) _matrix[i].resize(n, MAX_W);
}
获取顶点的下标
size_t GetVertexIndex(const V& v)
{auto it = _indexMap.find(v);if (it != _indexMap.end()) return it->second;else{// 抛异常出去throw invalid_argument("顶点不存在");// 过编译器逻辑return -1;}
}
通过map的接口find找到v对应的下标,如果it为end(),说明没有这个顶点,直接抛异常,如果存在,则返回对应的下标
添加边
// 原点 目标点 权值
void AddEdge(const V& src, const V& dst, const W& w)
{// 获取原点下标size_t srci = GetVertexIndex(src);size_t dsti = GetVertexIndex(dst);_matrix[srci][dsti] = w;// 无向图添加两个权值if (Direction == false) _matrix[dsti][srci] = w;
}
找到原点和目标点对应的下标,如果是有向图的话,只需要添加原点到目标点的边,如果是无向图的话,就需要反向添加一下目标点到原点的边了。
邻接表实现图
邻接表是图的一种存储表示方法,常用于存储稀疏图(即边数相对较少的图)。它通过每个顶点对应一个链表或数组来记录与其相邻的顶点。邻接表的空间复杂度相对较小,适合存储大规模图。

对于无向图来说不存在入度和出度的概念,所以只需要一个邻接表表示,下标的邻接表就是用来表示边的集合。

拿第一个点为例,这里使用一个结构体来维护的,这个结构体中有指向一下下一个边集的指针,还有一个权值和目标点的下标。
我们说形象一点:

类似于哈希桶的那个做法
邻接表实现图的基本框架
template<class W>
struct Edge
{int _dsti; //目标点的下标W _w; //权值Edge<W>* _next;Edge(int dsti,const W& w):_dsti(dsti),_w(w),_next(nullptr){}
};
// 顶点 weight 有向图/无向图
template<class V, class W,bool Direction = false>
class Graph
{typedef Edge<W> Edge;
public:private:vector<V> _vertexs; //顶点集合map<V, int> _indexMap; //顶点对应下标的关系(顶点---->下标)vector<Edge*> _tables; //邻接表
};
核心接口
初始化
Graph(const V* a, size_t n)
{// 开辟n个空间_vertexs.resize(n);for (size_t i = 0;i < n;i++){_vertexs[i] = a[i];//顶点----->下标_indexMap[a[i]] = i;}_tables.resize(n,nullptr);//给tables开辟n个空间(n个顶点)
}
获取顶点对应下标
size_t GetVertexIndex(const V& v)
{auto it = _indexMap.find(v);if (it != _indexMap.end()) return it->second;else{// 抛异常出去throw invalid_argument("顶点不存在");// 过编译器逻辑return -1;}
}
添加边
void AddEdge(const V& src, const V& dst, const W& w)
{// 获取原点下标size_t srci = GetVertexIndex(src);size_t dsti = GetVertexIndex(dst);//1 --> 2//原点到目标的权值Edge* eg = new Edge(dsti, w);//这里进行头插eg->_next = _tables[srci];_tables[srci] = eg;//无向图进行特殊处理//2 --> 1if (Direction == false){//反向指向Edge* eg = new Edge(srci, w);eg->_next = _tables[dsti];_tables[dsti] = eg;}
}
这个和邻接矩阵就不一样,邻接表中添加边应该先创建一个对应边的结构体,然后将这个结构体头插到原点对应下标的边集的位置上,如果是无向图的话,需要反向添加一条目标点到原点的边。注意:头插之后需要改变头的位置
总结
通过本篇文章的介绍,我们初步了解了图的基本概念、图的表示方法(如邻接矩阵和邻接表)、以及图中的各种基本性质。图论作为计算机科学和数学中的一个重要分支,其应用范围广泛,从网络设计到路径规划,都有着广泛的应用场景。
在接下来的学习中,我们可以进一步探讨更高级的图算法,如最短路径算法(Dijkstra、Bellman-Ford 等)、图的遍历算法(深度优先搜索、广度优先搜索)、以及图的连通性和最小生成树等高级主题。这些内容将为解决更复杂的实际问题提供坚实的理论基础。
图论的世界广阔而有趣,期待你能在之后的学习和实践中不断挖掘其奥秘!
相关文章:
【数据结构】图论基础
文章目录 图的概念图的基本概念图的类型图的表示方法 图的相关基本概念1. 路径(Path)2. 连通性(Connectivity)3. 图的度(Degree)4. 子图(Subgraph)5. 生成树(Spanning Tr…...
HTML5实现好看的唐朝服饰网站模板源码2
文章目录 1.设计来源1.1 网站首页1.2 唐装演变1.3 唐装配色1.4 唐装花纹1.5 唐装文化 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板,程序开发,在线开发,在线沟通 作者:xcLeigh 文章地址:https://blog.csdn.ne…...
golang web笔记-2.请求request
什么是request http消息分为request(请求) 和 response(响应) request:在go中是一个struct,代表了客户段发送的http请求,已可以通过request 的方法访问请求中的cookie、URL、User Agent…...
docker的安装与启动——配置国内Docker源
移除旧版本docker sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 配置docker yum源。 sudo yum install -y yum-utils sudo yum-config-manager –add-repo ht…...
httpsok-v1.17.0-SSL通配符证书自动续签
🔥httpsok-v1.17.0-SSL通配符证书自动续签 介绍 httpsok 是一个便捷的 HTTPS 证书自动续签工具,基于全新的设计理念,专为 Nginx 、OpenResty 服务器设计。已服务众多中小企业,稳定、安全、可靠。 一行命令,一分钟轻…...
相机、镜头参数详解以及相关计算公式
一、工业相机参数 1、分辨率 相机每次采集图像的像素点数,也是指这个相机总共有多少个感光晶片。在采集图像时,相机的分辨率对检测精度有很大的影响,在对同样打的视场成像时,分辨率越高,对细节的展示越明显。 相机像素…...
【微服务】组件、基础工程构建(day2)
组件 服务注册和发现 微服务模块中,一般是以集群的方式进行部署的,如果我们调用的时候以硬编码的方式,那么当服务出现问题、服务扩缩容等就需要对代码进行修改,这是非常不好的。所以微服务模块中就出现了服务注册和发现组件&…...
ESP32微信小程序SmartConfig配网
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 ESP32&微信小程序SmartConfig配网 前言一、SmartConfig是什么?二、使用乐鑫官方的smart_config例子1.运行照片 三、微信小程序总结 前言 本人是酷爱ESP32S3这…...
【PostgreSQL】提高篇——深入了解不同类型的 JOIN(INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL JOIN)应用操作
1. JOIN 的基础概念 在 SQL 中,JOIN 是用于从两个或多个表中组合行的操作。JOIN 允许我们根据某些条件将表中的数据关联在一起。常见的 JOIN 类型包括: INNER JOIN:仅返回两个表中满足连接条件的行。LEFT JOIN(或 LEFT OUTER JO…...
师生健康信息管理:SpringBoot技术突破
第4章 系统设计 4.1 系统体系结构 师生健康信息管理系统的结构图4-1所示: 图4-1 系统结构 登录系统结构图,如图4-2所示: 图4-2 登录结构图 师生健康信息管理系统结构图,如图4-3所示。 图4-3 师生健康信息管理系统结构图 4.2…...
【完-网络安全】Windows注册表
文章目录 注册表启动项及常见作用五个根节点常见入侵方式 注册表 注册表在windows系统的配置和控制方面扮演了一个非常关键的角色,它既是系统全局设置的存储仓库,也是每个用户的设置信息的存储仓库。 启动项及常见作用 快捷键 WinR打开运行窗口&#x…...
车辆重识别(2021NIPS在图像合成方面,扩散模型打败了gans网络)论文阅读2024/10/01
本文在架构方面的创新: ①增加注意头数量: 使用32⇥32、16⇥16和8⇥8分辨率的注意力,而不是只使用16⇥16 ②使用BigGAN残差块 使用Big GAN残差块对激活进行上采样和下采样 ③自适应组归一化层 将经过组归一化操作后的时间步和类嵌入到每…...
掌控物体运动艺术:图扑 Easing 函数实践应用
现如今,前端开发除了构建功能性的网站和应用程序外,还需要创建具有吸引力且尤为流畅交互的用户界面,其中动画技术在其中发挥着至关重要的作用。在数字孪生领域,动画的应用显得尤为重要。数字孪生技术通过精确模拟现实世界中的对象…...
Python从入门到高手4.2节-掌握循环控制语句
目录 4.2.1 理解循环控制 4.2.2 for循环结构 4.2.3 循环结构的else语句 4.2.4 while循环结构 4.2.5 循环结构可以嵌套 4.2.6 国庆节吃好玩好 4.2.1 理解循环控制 我们先来搞清楚循环的含义。以下内容引自汉语词典: 循环意指往复回旋,指事物周而复始地运动或变…...
CSS 中的overscroll-behavior属性
overscroll-behavior 是 CSS 中的一个属性,它用于控制元素在发生滚动时,当滚动范围超出其边界时的行为。这个属性对于改善用户体验特别有用,尤其是在移动端设备上,当用户尝试滚动一个已经达到滚动极限的元素时,可以通过…...
GPT对话知识库——在STM32的平台下,通过SPI读取和写入Flash的步骤。
目录 1,问: 1,答: 步骤概述 步骤 1:SPI 初始化 步骤 2:Flash 初始化(可选) 步骤 3:发送读取命令 示例:发送读取数据命令 步骤 4:读取数据…...
Pytorch基本知识
model.state_dict()、model.parameters()和model.named_parameters()的区别 parameters()只包含模块的参数,即weight和bias(包括BN的)。 named_parameters()返回包含模块名和模块的参数的列表,列表的每个元素均是包含layer name和layer param的元组。layer param就是param…...
vue3使用Teleport 控制台报警告:Invalid Teleport target on mount: null (object)
Failed to locate Teleport target with selector “.demon”. Note the target element must exist before the component is mounted - i.e. the target cannot be rendered by the component itself, and ideally should be outside of the entire Vue component tree main.…...
使用产品前的环境搭建
对于想学习编程的朋友们,使用本产品解决日常功能需求的同时会对自己编程能力具有较大帮助和提升。 目录 环境搭建 前言: 安装python 安装vscode 下载安装Anaconda 通过conda配置python环境 创建虚拟环境 查看环境是否创建成功 激活环境 安装pyt…...
JAVA基础语法 day07
一、final关键字 1.1final的基础知识 用来修饰类,方法,变量 final修饰类,该类被称为终极类,不能被继承了 final修饰方法,该方法称为终极方法,不能被重写了 final修饰变量,该变量仅能被赋值…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
