数据结构-图结构

一、图的定义与本质

• 由 顶点(Vertex) 和 边(Edge) 组成的非线性结构(记为 G = (V, E),V 是顶点集,E 是边集)

• 核心特点:顶点间可多对多连接,无层级/顺序限制,是树结构的泛化(树是无环连通图)

二、图的分类

• 按边的方向:

◦ 无向图:边无方向(如 (u, v) = (v, u),例:社交网络好友关系)

◦ 有向图(Digraph):边有方向(如 <u, v> 表示从 u 到 v,例:交通单向路)

• 按边的权重:

◦ 无权图:边仅表示连接关系,无数值属性

◦ 带权图(网):边附带权重(如距离、成本,例:地图路线规划)

• 按顶点连接程度:

◦ 连通图(无向):任意两顶点间存在路径;非连通图:存在孤立顶点子集

◦ 强连通图(有向):任意两顶点间双向存在路径;弱连通图:忽略方向后连通

• 其他特殊图:

◦ 完全图:无向图中任意两顶点间都有边(n 个顶点有 n(n-1)/2 条边)

◦ 稀疏图:边数远少于完全图;稠密图:边数接近完全图

◦ 有环图/无环图(DAG:有向无环图,如任务调度依赖图)

三、核心概念

• 顶点的度:

◦ 无向图:与顶点相连的边数(记为 deg(v))

◦ 有向图:入度(指向顶点的边数,in-deg(v))+ 出度(从顶点出发的边数,out-deg(v))

• 路径:顶点序列 v0→v1→...→vk,相邻顶点间存在边;路径长度:边的数量

• 回路(环):起点=终点且长度≥1的路径;简单路径:顶点不重复的路径

• 子图:顶点集和边集均为原图子集的图;生成子图:包含原图所有顶点的子图

• 连通分量(无向图):最大连通子图;强连通分量(有向图):最大强连通子图

四、图的存储方式

• 邻接矩阵(Adjacency Matrix):

◦ 原理:用 n×n 二维数组存储,matrix[i][j] 表示顶点 i 与 j 的关系(0/1 无权,权重值 带权)

◦ 优点:查询两顶点是否相邻、获取度效率高(O(1))

◦ 缺点:空间复杂度 O(n²),稀疏图浪费空间

• 邻接表(Adjacency List):

◦ 原理:顶点用数组存储,每个顶点对应一个链表/数组,存储其邻接顶点(及边权重)

◦ 优点:空间复杂度 O(n+e)(e 为边数),适合稀疏图

◦ 缺点:查询两顶点是否相邻效率低(O(deg(v)))

• 其他存储方式:

◦ 邻接多重表:解决无向图邻接表删除边需遍历两次的问题

◦ 十字链表:优化有向图的入度/出度查询效率

五、图的核心算法

(一)遍历算法

• 深度优先搜索(DFS):

◦ 思路:从起点出发,沿一条路径走到尽头,回溯后继续未遍历路径(类似树的先序遍历)

◦ 实现:递归(简洁)或栈(避免递归栈溢出)

◦ 应用:判断图连通性、查找路径、拓扑排序(DAG)、求强连通分量

• 广度优先搜索(BFS):

◦ 思路:从起点出发,按层级遍历所有邻接顶点(类似树的层序遍历)

◦ 实现:队列

◦ 应用:最短路径(无权图)、迷宫求解、拓扑排序

(二)最短路径算法

• 迪杰斯特拉(Dijkstra)算法:

◦ 适用:带权无负权边的图,求单源最短路径(从一个起点到所有其他顶点)

◦ 核心:贪心策略,每次选当前最短路径顶点,松弛邻接边权重

• 弗洛伊德(Floyd-Warshall)算法:

◦ 适用:任意带权图(可含负权边,不含负权回路),求所有顶点间最短路径

◦ 核心:动态规划,通过中间顶点逐步更新两顶点间最短路径

• 贝尔曼-福特(Bellman-Ford)算法:

◦ 适用:带权图(可含负权边),检测负权回路,求单源最短路径

(三)其他关键算法

• 拓扑排序(Topological Sort):

◦ 适用:有向无环图(DAG),输出顶点序列满足所有边的起点在终点前

◦ 实现:Kahn算法(基于入度)、DFS逆序

◦ 应用:任务调度、课程安排

• 最小生成树(MST):

◦ 适用:连通带权无向图,生成包含所有顶点且边权重和最小的生成子图

◦ 算法:Prim算法(适合稠密图,贪心选邻接最小边)、Kruskal算法(适合稀疏图,按权重选边避环)

◦ 应用:通信网络搭建、道路规划

六、应用场景

• 路径规划:地图导航(最短路径、最小成本)

• 网络相关:社交网络好友推荐(邻接顶点)、网络拓扑分析

• 任务调度:项目管理中任务依赖排序(拓扑排序)

• 其他:电路设计、物流配送优化、舆情传播分析

相关推荐
蒸蒸yyyyzwd4 小时前
cpp对象模型学习笔记1.1-2.8
java·笔记·学习
dalong105 小时前
A14:自定义动画演示
笔记·aardio
程序员徐师兄5 小时前
Windows JDK11 下载安装教程,适合新手
java·windows·jdk11 下载安装·jdk11 下载教程
RANCE_atttackkk5 小时前
[Java]实现使用邮箱找回密码的功能
java·开发语言·前端·spring boot·intellij-idea·idea
今儿敲了吗6 小时前
鸿蒙开发第一章学习笔记
笔记·学习·鸿蒙
闪闪发亮的小星星6 小时前
刚体运动学复习笔记
笔记
五岳6 小时前
DTS按业务场景批量迁移阿里云MySQL表实战(下):迁移管理平台设计与实现
java·应用·dts
zhougl9966 小时前
Java 所有关键字及规范分类
java·开发语言
Python 老手6 小时前
Python while 循环 极简核心讲解
java·python·算法
java1234_小锋7 小时前
Java高频面试题:MyISAM索引与InnoDB索引的区别?
java·开发语言