[数据结构与算法] 学习记录合辑 (07) 图

  • 该合辑为笔者自b站自学的“C++数据结构与算法”课程学习记录,旨在将重要的学习要点、思考内容与部分代码进行记录,以便后续自行翻看,亦可给其他读者带来一些参考
  • 内容基于笔者自身的理解或感悟,可能存在不妥当或是错误之处
  • 系统环境:Win10,Visual Studio 2019
  • 文中图片参考东北大学“数据结构与算法设计” (2020) 线上课程讲义

目录

1. 图相关术语

2. 图的表示

3. 图的遍历 

4. 最小生成树

5. 最短路径算法

6. 网络活动问题


图相关术语

名词解释

 一个图的数据结构可以抽象的表示为 G = (V,E),其中G代表Graph(图),V代表Verfices(顶点或元素),E代表Edge(边或关系)

图分为 无向图(undirected) 有向图(directed),无向图的两元素间关系不分方向,例如互为同学关系,而有向图强调方向,例如若干地点间的航班航向(可以是单向也可以是双向),其中元素间的无向边也可以用两条有向边来表示

完全图(complete graph)即为任两元素之间均有关系的图,也分为有向完全图和无向完全图,其中无向完全图的关系数量为 n(n-1) / 2,有向完全图的关系数量为 n(n-1)

weight / cost (权)元素间的关系可以拥有权重来抽象的表示一些信息,例如一种有向图 元素A指向元素B,该关系用权重10来表示A距离B点有10公里的路程,或用权重500来表示从A地到B地要花费500元路费等

带有 权重 的图可以被称作 网络(network)

degree(度)用来表示与某一顶点相关联的边的个数,还分为 入度(in - degree) 出度(out - degree),分别表示从该点出发和进入的边的个数(仅有向图)

path(路径)从一点到另一点所经过的顶点序列

length of path 路径长度(可带权)相加

loop(回路)首尾相连的路径

simple path(简单路径)顶点不重复的路径

acyclic graph(无环图)图中没有回路

acyclic directed graph(无环有向图)图中没有回路的有向图

connected graph(连通图)任意两顶点间都有路径的无向图

strongly connected graph(连通图)任意两顶点间都有路径的有向图

connecter component(连通分量)最大连通的子图

spanning tree(生成树)对连通图进行遍历,过程中所经过的边和顶点的组合可看做是一棵普通树,通常称为生成树。连通图中的生成树必须满足以下 2 个条件:

  1. 包含连通图中所有的顶点;
  2. 任意两顶点之间有且仅有一条通路;

spanning forest(生成森林)非连通图的各连通分量的生成树的总和


图的表示

在内存中存储图

 常见的有两种方法:Adjacency Matrix(邻接矩阵) Adjacency List(邻接表)

Adjacency Matrix(邻接矩阵)

若有n个节点,则用边长为n的矩阵来表示节点之间的关系,共花费n^2个存储空间,关系矩阵中,主对角线元素恒为零,因为节点与自身无需用关系来表示,另,无向图的邻接矩阵沿主对角线对称

若用邻接矩阵来表示Network(有向,有权),则用 “0” 表示无关,用常量 “C” 来表示权值(例如0.5、1、5、24 等),用无穷符号 “∞” 来表示无关

因矩阵的特性,使其在表示元素间关系时的空间复杂度达到了 O(n^2),其在对于稠密矩阵表达时还较为理想,当面对稀疏矩阵时,则浪费了许多空间

Adjacency List(邻接表)

 接上述所言,面对稀疏情况时,我们希望减少对内存空间的浪费,因此可以选择邻接表的方式对图进行表示,其空间复杂度可以优化到 O(n)

一般情况下,为了更为方便的找到某节点的出、入节点,用两个邻接表来表示一个图,分别为 出边表 入边表 ,此种方式牺牲内存空间取得了更高的查找效率

矩阵方式与表方式的相关操作复杂度等级如下图所示:


图的遍历 

遍历图中的各个元素

 一般有两种方式: depth first(深度优先) breadth first(广度优先)遍历,两种方法在所有元素已经在内存中有固定的位置关系时,遍历结果均唯一确定

前者利用递归与回退方法对元素进行遍历,优先对深度进行遍历:

深度优先遍历的时间复杂度:

O(n+e)        (list)

O(n^2)        (martrix)

后者优先对广度进行遍历:

广度优先遍历的时间复杂度:

O(e)            (list)

O(n^2)        (martrix)


最小生成树

生成树中权值和最小的那颗

前面有介绍生成树,而最小生成树就是生成树中所有路线的权值和加起来最少的那一颗,另强调一下,如果有n个顶点,则最小生成树应有n-1个边,且无环

Kruskal's Algorithm

算是一种贪心算法,先将所有边依据权值由小到大排列,再依次添加,如某次添加使得该树成环,则放弃此次添加,转而尝试下一条边,以此类推,直至达到n-1个边

利用小根堆和并查集实现相关算法设计,如有e个边,时间复杂度达到 O(e*loge) 

Prim's Algorithm

  1. 选取权值最小边的其中一个顶点作为起始点
  2. 找到离当前顶点权值最小的边,并记录该顶点为已选择
  3. 重复第二步,直到找到所有顶点,就找到了图的最小生成树

最短路径算法

两点之间有的时候没法儿走直线

求一个图中两顶点间的带权最短路径,放到生活中可能就是求地点之间的路径距离等等问题

Dijkstra's Algorithm

先确定一个点,再进行n-1步,每步都确定该点与其余n-1个顶点之间的最短距离,其缺点是只能体现图中某一个单一的点离其他顶点间的最短路径,时间复杂度为 O(n^2) 

Floyd's Algorithm

与上述方法不同的是,该方法可以记录任两个顶点间的最短距离


网络活动问题

有向无环图相关问题

在有向无环图中,用顶点代表活动,用边代表其先后顺序,解决相关问题(如大部分大学必修课程都要建立在一定前驱课程的学习基础上,因此要先学基础,再学专业课)

Topological Sort

顶点间不能确定明显的先后顺序关系时,由人为强行确定其顺序关系并最终表示输出序列(可能不唯一),其步骤如下:

  1. 挑选入度为0的节点
  2. 将该节点放入序列中
  3. 删除该节点与该节点所有的边,再进行第一步,直至所有点都被置入序列

该算法时间复杂度为 O(n+e) 

Activity On Edge Network (AOE网络)

用边来表示活动,顶点来表示事件,有两个特殊的名词:

关键路径:整个图中由起点至终点花费权重最大的一条路径

关键活动:关键路径上的所有活动边

关键活动的最迟发生时间和最早发生时间相同,不容片刻耽搁,工程中应用到的 关键路线法(CPM)就采用了该表示方法与计算思想 

该算法时间复杂度亦为 O(n+e) 


The End

猜你喜欢

转载自blog.csdn.net/Norths_/article/details/125724943
今日推荐