树本身就是一个特殊的图。
6.1图的基本概念
定义
逻辑结构的应用
几个概念
图的类型
顶点相关
(强)连通图
子图
(强)连通分量
生成树和生成森林
连通图的生成树是包含图中全部顶点的一个极小连通子图。若图中顶点数为n,则它的生成树含有 n-1 条边。对生成树而言,若砍去它的一条边,则会变成非连通,若加上一条边则会形成一个回路。
在非连通图中,连通分量的生成树构成了非连通图的生成森林。
边的权、带权图/网
几种特殊形态的图
总结
6.2图的存储和基本操作
6.2.1邻接矩阵法
带权图(网)的存储
性能分析:适合用于存储稠密图
性质
设图G的邻接矩阵为A(矩阵元素为0/1),则An
的元素Ani等于由顶点i到顶点j的长度为n的路径的数目
总结
6.2.2邻接表法(顺序+链式存储)
总结
6.2.3十字链表、邻接多重表
十字链表(只能)存储有向图
邻接多重表(只能)存储无向图
总结
6.2.4图的基本操作
判断图G是否存在边
列出图G中与结点x邻接的边
在图G中插入顶点x
从图G中删除顶点x
若无向边(x, y)或有向边<x, y>不存在,则向图G中添加该边
若无向边(x, y)或有向边<x, y>存在,则从图G中删除该边
求图G中顶点x的第一个邻接点,若有则返回顶点号。若x没有邻接点或图中不存在x,则返回-1
假设图G中顶点y是顶点x的一个邻接点,返回除y之外顶点x的下一个邻接点的顶点号,若y是x的最后一个邻接点,则返回-1
获取/设置图G中边(x, y)或<x, y>对应的权值
总结
6.3图的遍历
6.3.1图的广度优先遍历(BFS)
代码实现
如果是⾮连通图,则⽆法遍历完所有结点
BFS算法(Final版)
对于无向图,调⽤BFS函数的次数=连通分量数
复杂度分析
广度优先生成树
广度优先生成森林
对⾮连通图的⼴度优先遍历,可得到⼴度优先⽣成森林
练习
总结
6.3.2图的深度优先遍历DFS
复杂度分析
深度优先遍历序列
深度优先生成树(森林)
同⼀个图的邻接矩阵表示⽅式唯⼀,因此深度优先遍历序列唯⼀,深度优先⽣成树也唯⼀;
同⼀个图邻接表表示⽅式不唯⼀,因此深度优先遍历序列不唯⼀,深度优先⽣成树也不唯⼀。
图的遍历与图的连通性
总结
6.4
6.4.1最小生成树
定义
Prim 算法(普里姆)
Prim 算法(普⾥姆):从某⼀个顶点开始构建⽣成树;每次将代价最⼩的新顶点纳⼊⽣成树,直到所有顶点都纳⼊为⽌。
Kruskal 算法(克鲁斯卡尔)
Kruskal 算法(克鲁斯卡尔):每次选择⼀条权值最⼩的边,使这条边的两头连通(原本已经连通的就不选)直到所有结点都连通。
对比
Prim 算法的实现思想
Kruskal 算法的实现思想
总结
6.4.2最短路径问题--BFS算法
总结
6.4.3最短路径问题--Dijkstra算法
具体实现
Dijkstra算法的时间复杂度
对⽐:Prim 算法的实现思想
Dijkstra 算法不适⽤于有负权值的带权图
6.4.4最短路径问题--Floyd算法
核心代码
升级版
不能解决的问题
Floyd算法可以⽤于负权值带权图;Floyd 算法不能解决带有“负权回路”的图(有负权值的边组成回路),这种图有可能没有最短路径
总结
6.4.5有向无环图描述表达式
有向⽆环图:若⼀个有向图中不存在环,则称为有向⽆环图,简称DAG图(Directed Acyclic Graph)
栗子
最终变成
解题方法(最好跟着视频走一遍)
6.4.6拓扑排序
AOV网
拓扑排序
拓扑排序:找到做事的先后顺序
实现方法:
① 从AOV⽹中选择⼀个没有前驱(⼊度为0)的顶点并输出。
② 从⽹中删除该顶点和所有以它为起点的有向边。
③ 重复①和②直到当前的AOV⽹为空或当前⽹中不存在⽆前驱的顶点为⽌。(说明有回路)
代码实现??
逆拓扑排序
对⼀个AOV⽹,如果采⽤下列步骤进⾏排序,则称之为逆拓扑排序:
① 从AOV⽹中选择⼀个没有后继(出度为0)的顶点并输出。
② 从⽹中删除该顶点和所有以它为终点的有向边。
③ 重复①和②直到当前的AOV⽹为空。
nice
学会了学会了