算法与数据结构——图
图
图的基本概念
图的定义
图G由顶点集V和边集E组成,记为G = (V, E),其中V(G)表示图G中顶点的有限非空集;E(G)表示图G中顶点之间的关系(边)集合。若V={v1, v2, v3, ..., vn},则用|V|表示图G中顶点的个数,E = {(u, v) | u∈V, v∈V},用|E|表示图G中的边数。
图不可以为空,V一定是一个非空集,而E可以是一个空集。
有向图
若E是有向边(也称弧)的有限集合时,则图G为有向图。弧是顶点的有序对,记为<v, w>,其中v、w是顶点,v成为弧尾,w称为弧头,<v, w>称为从顶点v到顶点w的弧,也称v邻接w,或w邻接自v。

如上图所示,对于<A, E> E为弧尾,A为弧头
无向图
若E是无向边(简称边)的优先级和时,则图G为无向图。边是顶点的无序对,记为(v, w) 或 (w, v),因为(v, w) = (w, v),其中v、w是顶点。可以说顶点w和顶点v互为临界点。边(v, w)依附于顶点v和w,或者说边(v, w)和顶点v、w相关联。

简单图、多重图
一个图G如果满足:
- 不存在重复边
- 不存在顶点到自身的边
那么,称图G为简单图。

若图G中某两个顶点之间的边数大于1条,有允许顶点通过一条边与自身相连,则称图G为多重图。

顶点的度、入度、出度
对于无向图:顶点的度是指依附于该顶点的边的条数,记为TD(V)
$$
\sum_{i=1}^{n}{TD(v_i)} = 2 |E|
$$
对于有向图:
入度是以顶点v为终点的有向边的数目,记为ID(V)
出度是以顶点v为起点的有向边的数目,记为OD(V)
顶点v的度等于其入度和出度之和,即TD(V) = ID(V) + OD(V)
在具有n个顶点、e条边的有向图中:
$$
\sum_{i=1}^{n}ID(v_i) = \sum_{i=1}^{n}OD(v_i) = e
$$
路径、路径长度和回环
顶点vp到顶点vq之间一条路径是指顶点序列。当然,关联的边也可以理解为路径的构成元素。
路径上边的数目称为路径长度。
第一个顶点和最后一个顶点相同的路径称为回路或环
图的存储及基本操作
邻接矩阵法

0表示无边
1表示有边
对于无向图来说,第i个结点的度就是第i行或第i列非零元素的个数。
对于有向图来说,第i个结点的出度是第i行非零元素的个数;第i个结点的入度是第i列所对应元素的个数。
#define MaxVertexNum 100
typedef struct {
// 顶点表
char Vex[MaxVertexNum];
// 邻接矩阵,边表
bool Edge[MaxVertexNum][MaxVertexNum];
// 图的当前顶点数和边数/ 弧数
int vexNum, arcNum;
}MGraph;
邻接矩阵法存储带权图

在对应位置写两个顶点之间对应的权值。如果两个顶点不存在边,则存放一个无穷大值。
#define MaxVertexNum 100
// 宏定义常量“无穷”
#define INFINITY 99999
// 顶点数据类型
typedef char VertextType;
// 带权图中边上权值的数据类型
typedef int EdgeType;
typedef struct {
VertexType Vex[MaxVertexNum];
EdgeType Edge[MaxVertexNum][MaxVertexNum];
int vexnum, arcnum;
}MGraph;
邻接矩阵法的性能分析
空间复杂度:
$$
O(|V|^2)
$$
只和定点数相关,和实际的边数无关。
适合用于稠密图。
无向图的邻接矩阵是对称矩阵,可以使用压缩存储(只存储上三角或下三角)的方法进行存储。
邻接矩阵法的性质
设图G的邻接矩阵为A,则An的元素An[i][j]等于由顶点i到顶点j的长度为n的路径的数目。
邻接表法
顺序 + 链式 存储方式


在无向图中,遍历某个顶点的边链表,边链表的个数就是其顶点的度。
而在有向图中:遍历某个顶点的边链表,边链表的个数就是其顶点的出度;如果需要求顶点的入度,需要遍历所有顶点,事件花费较高。
图的邻接表表示方式不唯一。
邻接表法性能分析
对于有向图,其空间复杂度为:
$$
O(|V|+|E|)
$$
对于无向图,其空间复杂度为:
$$
O(|V| + 2|E|)
$$
十字链表(理解)
存储有向图

邻接多重表(理解)
存储无向图

空间复杂度为 O(|V| + |E|)
图的基本操作
- Adjacent(G, x, y)——判断图G是否存在边<x, y>或(x, y)
- Neighbors(G, x)——列出图G中与结点x邻接的边
- InsertVertex(G, x)——在图G中插入顶点x
- DeleteVertex(G, x)——在图G中删除顶点x
- AddEdge(G, x, yS)——若无向边(x, y)或有向边<x, y>不存在,则向图G中添加该边
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)