图的介绍
图也是一种非线性结构,图中任意两个节点间都可能有直接关系。相关定义如下:
-
无向图:图的结点之间连接线是没有箭头的,不分方向。
-
有向图:图的结点之间连接线是箭头,区分A到B,和B到A是两条线。
-
完全图:无向完全图中,节点两两之间都有连线,n个结点的连线数为(n-1)+(n-2)+…+1=n*(n-1)/2;有向完全图中,节点两两之间都有互通的两个箭头,n个节点的连线数为n*(n-1)。
-
度、出度和入度:顶点的度是关联与该顶点的边的数目。在有向图中,顶点的度为出度和入度之和。出度是以该顶点为起点的有向边的数目。入度是以该顶点为终点的有向边的数目。
-
路径:存在一条通路,可以从一个顶点到达另一个顶点,有向图的路径也是有方向的。
-
连通图和连通分量:针对无向图。若从顶点v到顶点u之间是有路径的,则说明v和u之间是连通的,若无向图中任意两个顶点之间都是连通的,则称为连通图。
-
强连通图的强连通分量:针对有向图。若有向图任意两个顶点间都相互存在路径,则称为强连通图。有向图中的极大联通子图称为其强联通分量。
-
网:边带权值的图称为网。
连通图和连通分量、强连通图的强连通分量和网了解即可
图的存储
邻接矩阵
使用二维数组来表示图中节点之间的连接关系。
- 第行和第列的元素表示节点和节点之间是否有连接。
- 空间复杂度较高,但查找连接关系效率高。
- 当图较密集时,邻接矩阵更好
邻接链表
用到了两个数据结构,先用一个一维数组将图中所有顶点存储起来,而后,对此一维数组的每个顶点元素,使用链表挂上和其有连线关系的结点的编号和权值,示例如下图所示:
空间复杂度较低,增加节点效率高,但查找连接关系效率低,当图较稀疏时,邻接链表更好
练习题
【2013年】从存储空间的利用率角度来看,以下关于数据结构中图的存储的叙述中,正确的是()
A.有向图适合采用邻接矩阵存储,无向图适合采用邻接表存储
B.无向图适合采用邻接矩阵存储,有向图适合采用邻接表存储
C.完全图适合采用邻接矩阵存储
D.完全图适合采用邻接表存储
答案:C
图的遍历
图的遍历是指从图的任意节点出发,沿着某条搜索路径对图中所有节点进行访问且只访问一次,分为以下两种方式:
- 深度优先遍历:从任一顶点出发,遍历到底,直至返回,再选取任一其他节点出发,重复这个过程直至遍历完整个图;
从上到下线遍历 - 广度优先遍历:先访问完一个顶点的所有邻接顶点,而后再依次访问其邻接顶点的所有邻接顶点,类似于层次遍历。
从左到右遍历
最小生成树
很容易出现题目
假设有n个节点,那么这个图的最小生成树有-1条边(不会形成环路,是树非图)
,这n-1条边会将所有顶点都连接成一个树,并且这些边的权值之和最小,因此称为最小生成树。
- 普里姆算法(Prim):从任意顶点出发,找出与其邻接的边权值最小的,此时此边的另外一个顶点自动加入树集合中,而后再从这这个树集合的所有顶点中找出与其邻接的边权值最小的,同样此边的另外一个顶点加入树集合中,依次递归,直至图中所有顶点都加入树集合中,此时此树就是该图的最小生成树。
- 克鲁斯卡尔算法(Kruscal,推荐):这个算法是从边出发的,因为本质是选取权值最小的-1条边,因此,就将边按权值大小排序,依次选取权值最小的边,直至囊括所有节点,要注意,每次选边后要检查不能形成环路。
上图使用克鲁斯卡尔算法
1、先画节点A B C D E F
2、计算边:6-1=5
3、依次取最小权值
4、如果最后两个权值一样,例如图中B和F,以及C和D权值都是300,但是B和F相连会导致环路,所以选择C和D
这两种算法都是局部最优原则,所以都是贪心法算法,并且没有谁的效率高
谁的效率差,因为克鲁斯卡尔算法是数边的,所以边越多,它算起来越麻烦
练习题
【2014年】Prim算法和Kruscal算法都是无向连通网的最小生成树的算法,Prim算法从一个顶点开始每次从剩余的顶点中加入一个顶点,该顶点与当前的生成树中的顶点的连边权重最小,直到得到一颗最小生成树;Kruscal算法从权重最小的边开始,每次从不在当前的生成树顶点中选择权重最小的边加入,直到得到一颗最小生成树,这两个算法都采用了
A.分治
B贪心
C动态规划
D.回溯
A.若网较稠密,则Prim算法更好
B.两个算法得到的最小生成树是一样的
C.Prim算法比Kruscal算法效率更高
D.Kruscal算法比Prim算法效率更高
答案:B A
图的拓扑序列
AOV网(以顶点表示活动的网):在有向图中,以顶点表示活动,用有向边表示活动之间的优先关系。
AOV如下图a:每个节点代表一个活动,如1,2,3,4,5,6节点都代表一个活动,1->2的边是有向边,说明1活动要执行完才能执行2。
AOV网用来表示大的工程项目执行计划,因此不能出现有向环,若存在,则意味着某项活动必须以自身任务的完成为先决条件,因此,若要检测一个工程是否可行,首先应检查对应的AOV网是否存在回路。检测的方法是对有向图构造其顶点的拓扑有序序列。
构造方法:将有向图的有向边作为活动开始的顺序,若图中一个节点入度为0,则应该最先执行此活动,而后删除掉此节点和其关联的有向边,再去找图中其他没有入度的结点,执行活动,依次进行,示例如下:
练习题
【2014年】拓扑排序是将有向图中所有顶点排成一个线性序列的过程,并且该序列满足:若在AOV网中从J顶点V到V有一条路径,则顶点V必然在顶点V之前。对于下面所示的有向图,是其拓扑序列
A.1234576
B.1235467
C.2135476
D.2134567
答案:C