408复习笔记 |
您所在的位置:网站首页 › 408数据结构题目汇总 › 408复习笔记 |
408笔记系列(六)(PS:本人使用的是王道四本书和王道视频) 数据结构:(六)图 前言一、简介二、主要内容1.图的概念2. 图的存储及基本操作2.1 邻接矩阵2.2 邻接表法2.3 十字链表法和邻接多重表 3. 图的遍历3.1 广度优先遍历(BFS)3.2 深度优先遍历 4. 图的应用4.1 最小生成树4.2 最短路径4.3 拓扑排序4.4 关键路径 三、常见题型及易错题总结 前言随着树学习的结束,我们又将认识到一种新的数据结构,这种结构在我们的日常生活中可以说是随处可见!没错,他就是图,可以这么说,图其实是包含了树的,在之后的学习中我们会发现在途中是有这个图的生成树的;那么我们图结构他到底长什么样子呢?(这一章因为考试并未重点考察过这里的代码,所以就不放代码了) 一、简介
所以从这里大家可以看出图结构是一种非常实用但是难度也很大的数据结构,需要我们非常认真的学习!!! 二、主要内容 1.图的概念图因为他的实用性,所以存在着非常多的概念,但主要针对考试的我们并不需要全部知道,等以后真正用到的时候再学也是可以的;王道书上关于图的概念介绍的就有点冗余,让人一时间有点摸不着北;那这里呢,为了更好的解决应对考试,将就几个考点说一下几个比较重要的概念; 首先肯定就是关于图的定义,那么图是什么?图G是由顶点集V和边集E组成的,顶点集是一个有限非空集合;边集就是顶点之间关系的集合;说的很官方,简单理解就是图是由点和边构成的;大家通过下图应该不难理解; 1. 无向图中度的总数等于边数的2倍 2. 有向图中边数等于入度数量加出度数量 这时大家可能会想到既然有度,那书里面不是还有树的高嘛?在图中并没有图高度这一说法,但是有图的路径这一说法,并且有三种不同的路径: 回路:第一个顶点到最后一个顶点相同的路径简单路径:序列中顶点不重复出现的路径;简单回路(环):除了第一个和最后一个顶点外,其余顶点不重复出现的回路;简单路径绝对不是回路!!! 介绍这些有关图本身的概念后,还有一些图之间的概念,就如同树里面有二叉树,一个图里面也有自己有特点的图; 连通图指的是在无向图中,任意两个顶点都有到对方的路径,那么称该图为连通图; 连通分量指的是无向图中极大连通子图;下图中的三个圈住的部分便是图的连通分量;(称为极大是因为如果此时加入任何一个不在图的点集中的点都会导致它不再连通) 这里有着非常经常考察的点: 1. 对于n个顶点的连通图,最少有n-1条边, 2. 对于n个顶点的非连通图,最多有[(n-1)*(n-2)]/2条边
这里考点如下: 对于有n个顶点的有向图最少有n条边 既然上面说到极大连通子图,那么一个图的极小连通子图我们称之为生成树,(之所以称为极小是因为此时如果删除一条边,就无法构成生成树,也就是说给极小连通子图的每个边都是不可少的)如图所示: 至此图的基本概念和考点都已经介绍结束,接下来就是我们数据结构的三步走啦!让我们看看图这个数据结构的逻辑结构、存储结构和运算吧! 2. 图的存储及基本操作上面我们介绍了图是什么,以及不同的定义和图的不同元素;接下来我们将开始正式了解图作为数据结构的一面,也就是图的三要素,首先图是一种非线性的逻辑结构,他的存储结构我们可以与树的存储结构对比着来看,我们知道树有三种存储方式——双亲表示法、孩子表示法和孩子兄弟表示法;那么结合树的三种存储方式呢,图的存储方式主要分为以下四种——邻接矩阵法、邻接表法、十字链表法和邻接多重表;图的运算也就是图的基本操作,对于不同的图,图的基本操作实现是不一样的,主要的几种操作也是创销增删该查等,包括如何查找顶点的第一个邻接点和找到顶点所有邻接点; 在图数据结构的三要素中,最重要的也是考试经常考察的便是图的存储结构啦! 2.1 邻接矩阵邻接矩阵其实相对应便是树中双亲表示法,通过顺序存储的方式存储图中的结点,如下图所示,顶点之间有邻接的呢,就标记为1,没有就标记为0; 邻接表其实跟树中的孩子表示法比较类似,他们采用的都是顺序加链表的方式进行表示,我们通过邻接表的图片来认识他,如果去掉1和2之间的边,是不是就和树的孩子表示法一样啦!我们知道孩子表示法在寻找双亲的过程中需要遍历所有结点,而我们的邻接表在解决有向图问题时求其顶点的入度需要遍历全部的邻接表; 十字链表法如图所示,同树的孩子兄弟表示法一样,十字链表法的每个弧结点都有两个指针域,分别指向弧头相同的下一条弧和弧尾相同的下一条弧;大家可能在这里会比较困惑,怎么变成弧了?其实我们的十字链表法是分为两个部分的,分别是顶点表和边表,顶点表里存放的是顶点结点,而边表中存放的是弧结点;他与邻接表不同的便是他每个顶点后存的不再是顶点而是边!边里面便有了两个顶点,根据这两个顶点我们变方便去找有向图的出度和入度啦! 是不是觉得非常的明智?但是呢?十字链表这个解决方案主要针对的是有向图使用的,如果是无向图,那这么做便变得毫无意义啦!这也是考试最容易考到的;
所以我们的邻接多重表便应运而生,如下图所示,两个指针分别指向下一条依附于前面顶点的边;因此我们有多少条边才会有多少个边结点,空间复杂度也变成了O(|V|+|E|); 在学习图的时候,我们非常需要结合树来学习,因为树作为一种特殊的图结构,在很多方面都是具有参考价值的;和树的遍历一样,图也有着的图的遍历算法,分为广度优先遍历和深度优先遍历; 3.1 广度优先遍历(BFS)广度优先遍历类似于树的层次遍历,访问一个顶点,并访问该顶点的所有邻接顶点,过程如图所示: 当考虑到广度优先遍历的时间时,因为图的存储结构是有四种的,而我们普遍使用的是邻接矩阵和邻接表,所以针对时间复杂度,我们需要对时间复杂度根据存储结构分别考虑: 当采用邻接矩阵存储时,我们访问每个结点的邻接点的时间复杂度都是O(|V|),因此当遍历所有的结点后,广度优先遍历的时间复杂度为O(|V|^2)(|V|为图的顶点数)当采用邻接表存储时,我们访问每个结点的邻接点其实就是访问图中所有的边,而对于无向图,邻接表中存储边的数量是图中边数量的2倍为2|E|,有向图为|E|;基于此,我们知道广度优先遍历的时间复杂度为O(|V| + |E|);此外,以上解决的都是连通图的问题,当图片是非连通图时,我们又该怎么办呢?如下图所示: 最后广度优先遍历后根据遍历的边可以得到一颗广度优先生成树,我们知道生成树是极小连通图,因此可能会是不唯一的,而广度优先生成树唯一不唯一便是根据图的存储结构决定的;当存储结构为邻接矩阵时,我们发现结点的邻接点顺序是不变的,因此得到的广度优先生成树是唯一的;而当存储结构为邻接表时,我们发现结点的邻接点顺序可能是不一样的,因此得到的广度优先生成树也是不唯一的; 3.2 深度优先遍历深度优先遍历从树的角度看,其实类似与树的前序遍历,访问图中一个起始点,从该点出发,访问与该点邻接但未被访问的点,之后在访问与访问点连接但未被访问的点,但不能继续访问下去,再一次退出被访问点;过程如图所示: 深度优先遍历的时间复杂度同广度优先遍历的时间复杂度一样也是与图的存储结构有着直接联系, 当采用邻接矩阵存储时,我们访问每个结点的邻接点的时间复杂度都是O(|V|),因此当遍历所有的结点后,广度优先遍历的时间复杂度为O(|V|^2)(|V|为图的顶点数)当采用邻接表存储时,我们访问每个结点的邻接点其实就是访问图中所有的边,而对于无向图,邻接表中存储边的数量是图中边数量的2倍为2|E|,有向图为|E|;基于此,我们知道广度优先遍历的时间复杂度为O(|V| + |E|);没错,深度优先遍历和广度优先遍历无论是邻接矩阵还是邻接表的存储结构,他们的时间复杂度都是相同的;在遇到非连通图的情况下解决方案同广度优先遍历也是一样的; 和广度优先生成树相对应的便是深度优先生成树,深度优先生成树在图结构为邻接矩阵存储时是唯一的,而在邻接表存储时是不唯一的;是的,和广度优先生成树也是一样的;但是有一点不同的是,因为深度优先搜索会一直向下寻找,所以一般深度优先生成树的树高是比广度优先生成树的树高大或者相等;上图的深度优先生成树长这样,大家可以感受一下: 这两种遍历手法其实对应的也是两种思想,用一张找迷宫出口的动图来看,两种方法都可以找到出口,但我们发现广度优先遍历如他的名字般搜索得更加广,而深度优先遍历搜索的深度更深;(蓝色是广度优先遍历,绿色是深度优先遍历) 图的应用可以说是非常之广泛的了,这里主要介绍以下几个部分:最小生成树算法、最短路径算法、拓扑排序和关键路径;这些也是在数据结构考试中频繁考察的知识点,又是是可以和计算机网络的大题结合着考察的,因此我们非常有必要对这一部分高度重视;主要还是各大算法的思想以及自己的理解; 4.1 最小生成树生成树我们知道,就是极小连通图;我们刚刚还学习了广度优先生成树和深度优先生成树,并且知道他们在不同的存储结构下生成的树还是不一样的;那最小生成树就跟他的名字一样,当然是最小的生成树啦!那什么最小呢?带权路径长度和最小,就是这棵生成树经过的路径代价最小,所以我们又称之为最小代价生成树;那还有一个问题?最小生成树唯一吗?我们通过下面的两个最小生成树算法来看一下吧! Prim算法 我们先看一下Prim算法的一个过程: Kruskal算法 首先看一下kruskal算法的一个过程吧,可以对比着上面的Prim算法看一下: 通过上面两个最小生成树的算法,我们不难看出我们最小生成树和我们边的权值是有很大关系的,因此我们可以得到一个结论:只有当边的权值全都不相同时,我们得到的最小生成树是不一样的; 4.2 最短路径最短路径指的是单源最短路径问题和各顶点之间最短路径算法,即从图的某一点到图中一点的最小代价路径,这在我们的生活中是非常常见的,比如地图上某点到某点的最短距离和最短路径问题以及地图每个点之间的最短距离分别是多少?,都可以通过图的算法进行解决;我们一般会有两种最短路径的算法,分别是Dijkstra算法和Floyd算法;Dijkstra算法解决的是单源最短路径问题,而Floyd算法解决的则是图中个顶点之间的最短路径;两位大佬都是图灵奖的得主,非常厉害;那我们看一下大佬的算法都是怎样的呢? Dijkstra算法 我们先来看一下Dijkstra算法的过程是怎么样的?![]() 拓扑排序也叫AOV网,这是考试中考察非常频繁的一个考点,个人认为在考察上甚至要高于上面提到的几个算法,上面的算法记住思想,其实是可以在考场上手推的;拓扑排序的流程是这样的:从AOV网中选择一个没有前驱的顶点并输出,从网中删除该顶点和所有以他为起点的有向边,重复上述操作直至AOV网为空或者当前王忠不存在无前驱的顶点为止,后一种情况说明有向图中必有环;就在这里往往会考察一个知识点:若有向图的顶点不能排成一个拓扑序列,则判定该有向图是个强连通图; 接下来我们看一下拓扑排序的过程:
关键路径又称为AOE网,用边来表示活动;开始点称之为源点,结束点称之为汇点;我们将路径也就是边称之为活动; 那么我们需要怎样才能找到关键路径呢?针对一个图,我们首先需要找到图中每个点,也就是图中每个事件的最早发生时间和最迟发生时间;最早发生时间取所有发生该事件需要带权路径长度最大值、最迟发生事件取所有发生该事件需要带全路径长度最小值; 之后依据事件最早发生时间和最迟发生时间,我们再找出所有活动的最早发生时间和最迟发生时间,活动最早发生时间为弧尾结点的最早发生时间;活动最迟发生时间为弧头指向结点的最迟发生时间 - 活动所需要的时间;将活动最迟发生时间减去活动最早发生时间称之为时间余量,时间余量为0的活动称之为关键活动,关键活动从源点到汇点称之为关键路径; 图到此便完结了主要内容,写得有些浮躁,没有代码加成,感觉效果会不太理想,之后二遍的时候会将代码完善完善,但应该只要也是伪代码了!之后就是查找和排序啦!数据结构基本已经学习完毕啦! 三、常见题型及易错题总结树和二叉树答案:A、C、C、B、A、C、C、C、D、C、C、D、D、C、D 答案见下一章! |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |