6.1 图的定义和基本术语
图是离散数学中的概念
边:没有方向。
弧:带有方向。
():无向偶对,没有先后关系。
<> :有序偶对,简称序偶,有先后关系。
以下括号表示有向图的相关内容
6.2 案例引入
六度空间理论
6.3 图的类型定义
6.4 图的存储结构
6.4.1 邻接矩阵(二维数组)
1)无向图的邻接矩阵
2)有向图的邻接矩阵
注意:如何区分二维数组的行和列?在二维数组中,如a[3][4], 表示3行4列。
3)有向网的邻接矩阵
4)邻接矩阵的存储表示
- 采用邻接矩阵创建无向网
- 采用邻接矩阵创建无向图、有向图、有向网
有方向和无方向的区别:二维数组是否对称、
图和网的区别:二维数组元素的值是0/1,还是权值/无穷大
5)邻居矩阵创建图/网的优缺点
6.4.2 邻接表(链式存储)
邻接表用一个一维的数组,存放一个结构体,也就是头结点,该结构体第一个元素存放顶点数据,第二个元素存放指向该顶点的邻接顶点的头指针。
如果是有权值的网,则表结点多一个info来存储权值:
1)无向图的邻接表
e条边,由于是无向图,每条边对应两个表结点,所以有2e个表结点。
无向图中顶点Vi的度位第i个单链表中的表结点数。
2)有向图的邻接表
3)邻接表的存储表示
总结:
邻接表的存储结构分为三部分:
- 顶点结点(包含顶点信息、指向邻接顶点的指针)构成的数组
- 每个顶点的邻接顶点构成的单链表
- 整个图
结合图和代码注释认真分析下面三个结构体的区别
注意:这里直接定义了AdjList表示表头结点构成的数组,即邻接表。
上面是邻接顶点的类型定义。
.
上面是整个图的定义。
.
难点:
以下是具体算法
4)邻接表创建图/网的优缺点
5)邻接表和邻接矩阵的对比
6.4.3 十字链表
十字链表和临接多重表先做了解
6.4.4 邻接多重表
6.5 图的遍历
6.5.1 图的基本概念
6.5.2 深度优先搜索遍历概念
6.5.3 深度优先遍历算法实现——邻接矩阵
6.5.4 DFS算法效率
- 时间复杂度
如果通过递归算法分析,不太好分析出时间复杂度。
但是从邻接矩阵二维数组的结构看,n个结点构成的n*n的矩阵被遍历了一次,虽然有些元素位置不满足要求,但还是进行了判断。因此时间复杂度为O(n2)。
6.5.5 非连通图的遍历
6.5.6 广度优先遍历概念
广度优先遍历和二叉树的层次遍历相似,而后者采用的是一个队列。
使用队列进行广度优先遍历的方法(非递归):
-
访问一个顶点,刷新visited[i]的值;
-
然后入队该顶点;
-
然后出队一个队首顶点;
-
出队之后将该顶点的所有邻接顶点依次入队,入队一个访问一个,刷新visited[i]的值;
-
反复进行 3、4。
不懂看就再看视频
问题:上述算法中倒数第6行的两个子函数不懂。
注意:以上算法是非递归的形式,看起来比较复杂。尽量用递归形式的。
6.5.7 BFS算法效率
6.5.8 DFS和BFS算法的对比
6.6 图的应用
6.6.1 最小生成树
2)算法的思想
上面回顾了生成树,下面是最小生成树:
构造最小生成树的算法都是利用到了MST的性质,MST也就是“最小生成树”。而MST就是一种贪心算法。
如果在原无向网中最底部权值为6的边改为权值为5,那么就可以得到两种不同的最小生成树,一种和先前的一样,一种如下图所示。因此,最小生成树可能不唯一。
2)算法的实现
待补充
以下代码看懂:最小生成树
上述代码中使用了大量c++的知识,vector(二维)、sort、find等,需要复习(学习上)c++之后才可以看懂。
因此,数据结构的这一遍学习主要是学习知识点、算法思想,至于具体实现要等学习c++之后。
但是c++内容很多,不可能完全掌握c++每个知识点之后再去学习算法的实现。
因此,安排如下:
数据结构第一遍学习 先不考虑较难算法的实现;
数据结构第二遍学习(包括知识点深入理解、刷题),根据具体算法涉及到的c++知识再去学习掌握。
6.6.2 最短路径
1)Dijistra算法
2)Floyd算法
以上两种方法的时间复杂度都是n的三方。
以上:“了解算法思想”。
6.6.3 有向无环图及其应用
1)拓扑排序
1)关键路径
求关键路径就是找最长路径,这和6.6.2最短路径的区别不仅在于一个求最长、一个求最短,还在于求关键路径针对的是有向无环图(带权值),而求最短路径针对的可以是带环的有向图(带权值)。
event:事件
earliest:最早
latest:最晚
**注:**前面不是很懂的话,从这页ppt开始能够比较清楚的理解:
求关键路径步骤
- 求每个事件的最早发生时间、最晚发生时间
- 求每个活动的最早开始时间、最晚开始时间
- 求每个活动的时间余量,也就是最晚开始时间-最早开始时间