news 2026/4/23 18:54:20

考研复习 Day 18 | 数据结构与算法--图(上)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
考研复习 Day 18 | 数据结构与算法--图(上)

一、图的基本概念

1.1 图的定义

图G由顶点集V和边集E组成,记为G=(V,E)

要素说明
V(G)顶点的有限非空集
E(G)顶点之间关系的集合

重要:线性表可以是空表,树可以是空树,但图不可以是空图。顶点集V必须非空,但边集E可以为空。


1.2 基本术语

1. 有向图 vs 无向图

类型边的形式说明
有向图<v, w>v称为弧尾,w称为弧头,表示v→w
无向图(v, w)(w, v)v和w互为邻接点

2. 简单图 vs 多重图

类型条件
简单图① 不存在重复边;② 不存在顶点到自身的边
多重图两顶点之间边数可超过1条,允许顶点通过边与自身关联

这里仅讨论简单图

3. 顶点的度、入度、出度

图类型定义重要结论
无向图度TD(v) = 依附于v的边数所有顶点的度之和 = 2|E|
有向图入度ID(v) = 以v为终点的边数;出度OD(v) = 以v为起点的边数

所有顶点的入度之和 = 出度之和 =|E|

注:符号含义对照表

符号含义类型举例
E边集(Edge Set)集合E = {(A,B), (B,C)}
|E|边的条数数字|E| = 2

很多人会偷懒直接用E表示边数,但它本质上是|E|

顶点v的度:TD(v) = ID(v) + OD(v)

4. 路径与回路

术语定义
路径顶点序列v₀, v₁, …, vₙ
路径长度路径上边的数量
回路(环)第一个顶点和最后一个顶点相同的路径
简单路径路径中顶点不重复出现
简单回路除首尾外,其余顶点不重复的回路
距离从u到v的最短路径的长度(不存在则为∞)

若一个图有n个顶点,且有大于n-1条边,则此图一定有环

5. 子图

V' ⊆ VE' ⊆ E,则称G'是G的子图。

类型定义
生成子图满足V(G') = V(G)的子图

并非V和E的任何子集都能构成子图——E'中的边关联的顶点必须在V'中。

6. 连通性(无向图)

术语定义
连通从v到w存在路径
连通图图中任意两个顶点都是连通的
连通分量无向图中的极大连通子图

若一个图有n个顶点,边数少于n-1,则此图必然是非连通的

7. 强连通性(有向图)

术语定义
强连通从v到w从w到v都有路径
强连通图图中任意一对顶点都是强连通的
强连通分量有向图中的极大强连通子图

有向图强连通的最少边数:n条(形成一个环)

8. 生成树与生成森林

术语定义
生成树连通图的极小连通子图,包含所有顶点和n-1条边
生成森林非连通图中,每个连通分量的生成树共同构成

区分:极大连通子图(连通分量)要求包含尽可能多的顶点和边;极小连通子图(生成树)要求保持连通且边数最少。

9. 其他术语

术语定义
完全图无向:|E| = n(n-1)/2;有向:|E| = n(n-1)
稀疏图/稠密图|E| < n log₂n视为稀疏图
边上带有权值的图
有向树一个顶点的入度为0,其余顶点的入度均为1的有向图

二、图的存储及基本操作

2.1 邻接矩阵法

#define MaxVertexNum 100 typedef struct { VertexType vex[MaxVertexNum]; // 顶点表 EdgeType edge[MaxVertexNum][MaxVertexNum]; // 邻接矩阵(边表) int vexnum, arcnum; // 当前顶点数和边数 } MGraph;

特点

图类型邻接矩阵特点
无向图一定是对称矩阵,第i行(列)非零元素个数 = 顶点i的度
有向图第i行非零元素个数 = 出度;第i列 = 入度

重要结论

  • 空间复杂度:O(n²)

  • 判断两点是否有边:O(1)

  • 确定图中边数:需遍历整个矩阵

  • 稠密图适合邻接矩阵

  • Aⁿ[i][j] = 从i到j长度为n的路径数量


2.2 邻接表法

#define MaxVertexNum 100 typedef struct ArcNode { // 边表结点 int adjvex; // 邻接点位置 struct ArcNode *nextarc; // 下一条边的指针 // InfoType info; // 网边权值 } ArcNode; typedef struct VNode { // 顶点表结点 VertexType data; // 顶点信息 ArcNode *firstarc; // 第一条边 } VNode, AdjList[MaxVertexNum]; typedef struct { AdjList vertices; // 邻接表 int vexnum, arcnum; // 顶点数和边数 } ALGraph;

特点

图类型空间复杂度特点
无向图O(n + 2|E|)每条边出现两次
有向图O(n + |E|)
  • 稀疏图适合邻接表

  • 找所有邻接点:邻接表高效;邻接矩阵需扫描整行

  • 判断两点是否有边:邻接表需遍历边表,效率较低

  • 有向图入度:需遍历所有顶点的边表

  • 邻接表的表示不唯一(取决于输入顺序)


2.3 十字链表(有向图)

每条弧用一个弧结点表示,每个顶点用一个顶点结点表示。

弧结点结构

顶点结点结构

优点:容易找到以v为尾的弧(出度)和以v为头的弧(入度)


2.4 邻接多重表(无向图)

每条边只用一个结点表示,解决了邻接表中一条边用两个结点表示的问题。

边结点结构

顶点结点结构

优点:判断边是否存在只需遍历一次


2.5 四种存储方式对比

存储方式空间复杂度找相邻边删除边/顶点适用场景表示唯一性
邻接矩阵O(n²)遍历行/列O(n)删边方便,删顶点需移动数据稠密图唯一
邻接表无向O(n+2|E|),有向O(n+|E|)方便不方便稀疏图不唯一
十字链表O(n+|E|)方便方便有向图不唯一
邻接多重表O(n+|E|)方便方便无向图不唯一

三、图的遍历

3.1 广度优先搜索(BFS)

类似于树的层序遍历,借助队列实现,按路径长度递增的顺序访问顶点。

bool visited[MAX_VERTEX_NUM]; void BFSTraverse(Graph G) { for (int i = 0; i < G.vexnum; i++) visited[i] = FALSE; InitQueue(Q); for (int i = 0; i < G.vexnum; i++) if (!visited[i]) BFS(G, i); } void BFS(ALGraph G, int i) { visit(i); visited[i] = TRUE; EnQueue(Q, i); while (!QueueEmpty(Q)) { DeQueue(Q, v); for (ArcNode *p = G.vertices[v].firstarc; p; p = p->nextarc) { w = p->adjvex; if (!visited[w]) { visit(w); visited[w] = TRUE; EnQueue(Q, w); } } } }

性能分析

  • 空间复杂度:O(n)(辅助队列)

  • 时间复杂度:

    • 邻接表:O(n + |E|)

    • 邻接矩阵:O(n²)

BFS求单源最短路径(非带权图):

void BFS_MIN_Distance(Graph G, int u) { for (int i = 0; i < G.vexnum; i++) d[i] = ∞; visited[u] = TRUE; d[u] = 0; EnQueue(Q, u); while (!QueueEmpty(Q)) { DeQueue(Q, u); for (w = FirstNeighbor(G, u); w >= 0; w = NextNeighbor(G, u, w)) if (!visited[w]) { visited[w] = TRUE; d[w] = d[u] + 1; EnQueue(Q, w); } } }

广度优先生成树

  • 邻接矩阵存储:生成树唯一

  • 邻接表存储:生成树可能不唯一


3.2 深度优先搜索(DFS)

类似于树的先序遍历,借助递归(栈)实现,遵循“尽可能深”地探索的策略。

bool visited[MAX_VERTEX_NUM]; void DFSTraverse(Graph G) { for (int i = 0; i < G.vexnum; i++) visited[i] = FALSE; for (int i = 0; i < G.vexnum; i++) if (!visited[i]) DFS(G, i); } void DFS(ALGraph G, int i) { visit(i); visited[i] = TRUE; for (ArcNode *p = G.vertices[i].firstarc; p; p = p->nextarc) { j = p->adjvex; if (!visited[j]) DFS(G, j); } }

性能分析

  • 空间复杂度:O(n)(递归工作栈)

  • 时间复杂度:

    • 邻接表:O(n + |E|)

    • 邻接矩阵:O(n²)

深度优先生成树/森林

  • 连通图:一棵生成树

  • 非连通图:生成森林


3.3 图的遍历与连通性

图类型遍历特点
无向图调用BFS/DFS的次数 =连通分量数
有向图一次遍历不一定能访问所有顶点,需外层循环确保全覆盖

四、思考

1. 邻接矩阵 ≈ 城市之间的直达航班表

行是出发城市,列是到达城市,单元格填1表示有直达航班。对角线是自己的城市(0),矩阵对称表示往返都有航班。

2. 邻接表 ≈ 微信好友列表

每个用户有一个好友列表(边表),只存储自己的好友,不存储非好友关系。空间利用率高。

3. BFS ≈ 六度分隔理论

你认识的朋友是第一层,朋友的朋友是第二层……BFS正是按这个层层递进的顺序探索“社交网络”中的人际关系。

4. DFS ≈ 走迷宫

沿着一条路一直走,走到死胡同就退回上一个岔路口,换一条路继续走,直到走遍所有路。

注:以上内容参考 2027年数据结构考研复习指导 王道论坛 组编,其中有一些个人想法,如有任何错误或不妥,欢迎各位大佬指出,如果各位有一些有意思的想法,也可以和我交流一下~感谢!


五、明日计划

图(下)— 最小生成树、最短路径、拓扑排序、关键路径

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 18:52:49

PowerDMIS相对测量2:.测量薄壁金属件

.测量薄壁金属件 薄壁金属件由于易变形&#xff0c;测量时容易撞针或杆测量&#xff1b;故可用相对测量例&#xff1a;薄壁件中测量一孔 例&#xff1a;薄壁件中测量一孔 ① 在薄壁件端面探测一单点② 在圆界面用公式打开Z值③在公式中输入&#xff1a;单点Z值-薄壁件壁厚/2FA(…

作者头像 李华
网站建设 2026/4/23 18:51:29

别只盯着漏洞利用:从Amaterasu靶场学到的3个高效信息收集思维

从Amaterasu靶场实战中提炼的3个高阶信息收集思维 当大多数安全从业者还在机械地扫描端口和枚举服务时&#xff0c;真正的高手已经在思考如何将信息收集转化为系统性的侦察艺术。Amaterasu靶场就像一面镜子&#xff0c;照出了我们工作流中的思维盲区——那些被Nmap默认脚本掩盖…

作者头像 李华
网站建设 2026/4/23 18:51:28

抖音下载器完整教程:三步实现批量下载视频音乐的高效方案

抖音下载器完整教程&#xff1a;三步实现批量下载视频音乐的高效方案 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback su…

作者头像 李华
网站建设 2026/4/23 18:49:36

Display Driver Uninstaller终极指南:3分钟彻底清理显卡驱动残留

Display Driver Uninstaller终极指南&#xff1a;3分钟彻底清理显卡驱动残留 【免费下载链接】display-drivers-uninstaller Display Driver Uninstaller (DDU) a driver removal utility / cleaner utility 项目地址: https://gitcode.com/gh_mirrors/di/display-drivers-un…

作者头像 李华
网站建设 2026/4/23 18:49:29

3分钟掌握抖音无水印下载:开源工具完整实战指南

3分钟掌握抖音无水印下载&#xff1a;开源工具完整实战指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support. 抖…

作者头像 李华