数据结构学习笔记(三)——图

图相关概念

参考资料:【王道计算机考研 数据结构】

图的定义

图G由顶点集V和边集E组成,记为G=(V, E),其中VG)表示图G中顶点的有限非空集; E(G)表示图G中顶点之间的关系(边) 集合。若V={V1, V2,...,Vn),则用|V|表示图G中顶点的个数,也称图G的阶,E={(u, v)|u∈V, v∈V,用|E|表示图G中边的条数

注意:线性表可以是空表,树也可以为空,树可以是空树,但图不可以为空。即V一定为非空集

无向图与有向图

无向图

若E是无向边(简称边)的有限集合时,则图G为无向图。边
是顶点的无序对,记为(v, w)或(w, v),因为(v, w) = (w, v),其
中v、w是顶点。可以说顶点w和顶点v互为邻接点。边(v, w)
依附于顶点w和v,或者说边(v, w)和顶点v、w相关联。
G2 = (V2, E2)
V2 = {A, B, C, D, E}
E2 = {(A, B), (B, D), (B, E), (C, D), (C, E), (D, E)}

有向图

若E是有向边(也称弧)的有限集合时,则图G为有向图。
弧是顶点的有序对,记为<v, w>,其中v、w是顶点,v称为
弧尾,w称为弧头,<v, w>称为从顶点v到顶点w的弧,也称
v邻接到w,或w邻接自v。 <v, w> ≠ <w, v>
G1 = (V1, E1)
V1 = {A, B, C, D, E}
E1 = {<A, B>, <A, C>, <A, D>, <A, E>, <B, A>, <B, C>, <B, E>, <C, D>}

简单图和多重图

简单图
① 不存在重复边;
② 不存在顶点到自身的边
多重图
图G中某两个结点之间的边数多于一条,又允许顶点通过同一条边和自己关联,则G为多重图

顶点的度、入度、出度

度的定义:
对于无向图:顶点v的度是指依附于该顶点的边的条数,记为TD(v)。
在具有n个顶点、e条边的无向图中,无向图的全部顶点的度的和等于边数的2倍

对于有向图:
入度是以顶点v为终点的有向边的数目,记为ID(v);
出度是以顶点v为起点的有向边的数目,记为OD(v)。
顶点v的度等于其入度和出度之和,即TD(v) = ID(v) + OD(v)。

顶点-顶点的关系描述

• 路径——顶点vp到顶点vq之间的一条路径是指顶点序列 ,
• 回路——第一个顶点和最后一个顶点相同的路径称为回路或环
• 简单路径——在路径序列中,顶点不重复出现的路径称为简单路径。
• 简单回路——除第一个顶点和最后一个顶点外,其余顶点不重复出现的回路称为简单回路。
• 路径长度——路径上边的数目
• 点到点的距离——从顶点u出发到顶点v的最短路径若存在,则此路径的长度称为从u到v的距离。
若从u到v根本不存在路径,则记该距离为无穷(∞)。
• 无向图中,若从顶点v到顶点w有路径存在,则称v和w是连通的
• 有向图中,若从顶点v到顶点w和从顶点w到顶点v之间都有路径,则称这两个顶点是强连通的

连通图、强连通图

若图G中任意两个顶点都是连通的,则称图G为连通图,否则称为非连通图。
若图中任何一对顶点都是强连通的,则称此图为强连通图。

常见考点:
对于n个顶点的无向图G,
若G是连通图,则最少有 n-1 条边
若G是非连通图,则最多可能有\(C^2_{n-1}\)

常见考点:
对于n个顶点的有向图G,若G是强连通图,则最少有 n 条边(形成回路)

图的局部-子图

设有两个图G = (V, E)和G' = (V', E'),若V'是V的子集,且E'是
E的子集,则称G'是G的子图。
若有满足V(G') = V(G)的子图G',则称其为G的生成子图

连通分量

无向图中的极大连通子图称为连通分量。子图必须连通,且包含尽可能多的顶点和边

强连通分量
有向图中的极大强连通子图称为有向图的强连通分量
子图必须强连通,同时保留尽可能多的边

生成树

连通图的生成树是包含图中全部顶点的一个极小连通子图。若图中顶点数为n,则它的生成树含有 n-1 条边。对生成树而言,若砍去它的一条边,则会变成非连通图,若加上一条边则会形成一个回路。
边尽可能的少,但要保持连通

生成森林

在非连通图中,连通分量的生成树构成了非连通图的生成森林。

边的权、带权图/网

边的权——在一个图中,每条边都可以标上具有某种含义的数值,该数值称为该边的权值。
带权图/网——边上带有权值的图称为带权图,也称网。
带权路径长度——当图是带权图时,一条路径上所有边的权值之和,称为该路径的带权路径长度

几种特殊形态的图

无向完全图——无向图中任意两个顶点之间都存在边

有向完全图——有向图中任意两个顶点之间都存在方向相反的两条弧

边数很少的图称为稀疏图,反之称为稠密图

树——不存在回路,且连通的无向图
有向树——一个顶点的入度为0、其余顶点的入度均为1的有向图,称为有向树。
常见考点:n个顶点的图,若 |E|>n-1,则一定有回路

总结

图的存储

邻接矩阵法

  • 无向图:第i个结点的出度 = 第i行的非零元素个数
  • 有向图:
    第i个结点的入度 = 第i列的非零元素个数
    第i个结点的度 = 第i行、第i列的非零元素个数之和

    特点:
  • 空间复杂度:\(O(|V|^2)\)——只和顶点数相关,和实际的边数无关
  • 适合用于存储稠密图
  • 无向图的邻接矩阵是对称矩阵,可以压缩存储(只存储上三角区/下三角区)
    性质:
    设图G的邻接矩阵为A(矩阵元素为0/1),则An的元素An[i][j]等于由顶点i到顶点j的长度为n的路径的数目

邻接表法


十字链表


空间复杂度: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,y):若无向边(x, y)或有向边<x, y>不存在,则向图G中添加该边。

• RemoveEdge(G,x,y):若无向边(x, y)或有向边<x, y>存在,则从图G中删除该边。

• FirstNeighbor(G,x):求图G中顶点x的第一个邻接点,若有则返回顶点号。若x没有邻接点或图中不存在x,则返回-1。


• NextNeighbor(G,x,y):假设图G中顶点y是顶点x的一个邻接点,返回除y之外顶点x的下一个邻接点的顶点号,若y是x的最后一个邻接点,则返回-1。

• Get_edge_value(G,x,y):获取图G中边(x, y)或<x, y>对应的权值。
• Set_edge_value(G,x,y,v):设置图G中边(x, y)或<x, y>对应的权值为v。

回顾:

图的遍历

广度优先遍历

树的层序遍历
广度优先遍历(Breadth-First-Search, BFS)要点:

  1. 找到与⼀个顶点相邻的所有顶点
  2. 标记哪些顶点被访问过
  3. 需要一个辅助队列
    •FirstNeighbor(G,x):求图G中顶点x的第⼀个邻接点,若有则返回顶点号。
    若x没有邻接点或图中不存在x,则返回-1。
    •NextNeighbor(G,x,y):假设图G中顶点y是顶点x的⼀个邻接点,返回除y之外
    顶点x的下⼀个邻接点的顶点号,若y是x的最后⼀个邻接点,则返回-1。
    同一个图的邻接矩阵表示方式唯一,因此⼴度优先遍历序列唯一
    同一个图邻接表表示方式不唯一,因此⼴度优先遍历序列不唯一

    空间复杂度:最坏情况,辅助队列大小为 O(|V|)
    时间复杂度:
    邻接矩阵存储的图:
    访问 |V| 个顶点需要O(|V|)的时间查找每个顶点的邻接点都需要O(|V|)的时间,⽽总共有|V|个顶点时间复杂度= O(|V|2)
    邻接表存储的图:
    访问 |V| 个顶点需要O(|V|)的时间查找各个顶点的邻接点共需要O(|E|)的时间,时间复杂度= O(|V|+|E|)

广度优先生成树

只保留第一次入队的边

⼴度优先⽣成树由⼴度优先遍历过程确定。由于邻接表的表示⽅式不唯一,因此基于邻接表的⼴度优先⽣成树也不唯⼀。

广度优先生成森林

总结

深度优先遍历



空间复杂度:来自函数调用栈,最坏情况,递归深度为O|v|
时间复杂度=访问各结点所需时间+探索各条边所需时间
邻接矩阵存储的图:
访问 |V| 个顶点需要O(|V|)的时间
查找每个顶点的邻接点都需要O(|V|)的时间,⽽总共有|V|个顶点
时间复杂度= O(|V|2)
邻接表存储的图:
访问 |V| 个顶点需要O(|V|)的时间
查找各个顶点的邻接点共需要O(|E|)的时间,
时间复杂度= O(|V|+|E|)

深度优先生成树


对⽆向图进⾏BFS/DFS遍历
调⽤BFS/DFS函数的次数=连通分量数
对于连通图,只需调⽤1次 BFS/DFS

总结

最小生成树(最小代价树)

生成树:连通图的生成树是包含图中全部顶点的一个极小连通子图。
若图中顶点数为n,则它的生成树含有 n-1 条边。对生成树而言,若砍去它的一条边,则会变成非连通图,若加上一条边则会形成一个回路。

  • 如果⼀个连通图本身就是⼀棵树,则其最⼩⽣成树就是它本身
  • 只有连通图才有⽣成树,⾮连通图只有⽣成森林
  • 最⼩⽣成树可能有多个,但边的权值之和总是唯⼀且最⼩的
  • 最⼩⽣成树的边数 = 顶点数 - 1。砍掉⼀条则不连通,增加⼀条边则会出现回路
  • 如果⼀个连通图本身就是⼀棵树,则其最⼩⽣成树就是它本身
  • 只有连通图才有⽣成树,⾮连通图只有⽣成森林

求最小生成树

  • Prim算法
    Prim 算法(普⾥姆):
    从某⼀个顶点开始构建⽣成树;每次将代价最⼩的新顶点纳⼊⽣成树,直到所有顶点都纳⼊为⽌。

  • Kruskal 算法(克鲁斯卡尔)
    Kruskal 算法(克鲁斯卡尔):每次选择⼀条权值最⼩的边,使这条边的两头连通(原本已经连通的就不选)直到所有结点都连通

总结

最短路径

BFS算法

Dijkstra算法

Floyd算法



回顾

有向无环图

有向⽆环图:若⼀个有向图中不存在环,则称为有向⽆环图,简称DAG图(Directed Acyclic Graph)

DAG描述表达式




拓扑排序

AOV网

AOV⽹(Activity On Vertex NetWork,⽤顶点表示活动的⽹):
⽤DAG图(有向⽆环图)表示⼀个⼯程。顶点表示活动,有向边<Vi, Vj>表示活动Vi必须先于活动Vj进⾏

拓扑排序


拓扑排序的实现:
① 从AOV⽹中选择⼀个没有前驱(⼊度为0)的顶点并输出。
② 从⽹中删除该顶点和所有以它为起点的有向边。
③ 重复①和②直到当前的AOV⽹为空或当前⽹中不存在⽆前驱的顶点为⽌。
代码:

逆拓扑排序

对⼀个AOV⽹,如果采⽤下列步骤进⾏排序,则称之为逆拓扑排序:
① 从AOV⽹中选择⼀个没有后继(出度为0)的顶点并输出。
② 从⽹中删除该顶点和所有以它为终点的有向边。
③ 重复①和②直到当前的AOV⽹为空。
DFS算法实现

4,3,1,0,2

回顾

关键路径

AOE网


在AOE⽹中仅有⼀个⼊度为0的顶点,称为开始顶点(源点),它表示整个⼯程的开始;也仅有⼀个出度为0的顶点,称为结束顶点(汇点),它表示整个⼯程的结束。

从源点到汇点的有向路径可能有多条,所有路径中,具有最⼤路径⻓度的路径称为
关键路径,⽽把关键路径上的活动称为关键活动
完成整个⼯程的最短时间就是关键路径的⻓度,若关键活动不能按时完成,则整个
⼯程的完成时间就会延⻓
事件vk的最迟发⽣时间vl(k)——它是指在不推迟整个⼯程完成的前提下,该事件最迟必须发⽣的时间。
活动ai的最迟开始时间l(i)——它是指该活动弧的终点所表示事件的最迟发⽣时间与该活动所需时间之差







可能有多条关键路径,只提⾼⼀条关键路径上的关键活动速度并不能缩短整个⼯程的⼯期,只有加快那些包括在所有关键路径上的关键活动才能达到缩短⼯期的⽬的。

回顾

posted @ 2023-02-01 22:30  LV426  阅读(262)  评论(0)    收藏  举报