图的遍历算法

上传人:工**** 文档编号:511537567 上传时间:2023-07-23 格式:DOC 页数:13 大小:62KB
返回 下载 相关 举报
图的遍历算法_第1页
第1页 / 共13页
图的遍历算法_第2页
第2页 / 共13页
图的遍历算法_第3页
第3页 / 共13页
图的遍历算法_第4页
第4页 / 共13页
图的遍历算法_第5页
第5页 / 共13页
点击查看更多>>
资源描述

《图的遍历算法》由会员分享,可在线阅读,更多相关《图的遍历算法(13页珍藏版)》请在金锄头文库上搜索。

1、. .1 图的遍历问题在实践中常常遇到这样的问题:给定n个点,从任一点出发对所有的点访问一次并且只访问一次。如果用图中的顶点表示这些点,图中的边表示可能的连接,那么这个问题就可以表示成图的遍历问题,即从某个顶点出发,沿着某条搜索路径对图中每个顶点各做一次且仅做一次访问。图的遍历操作和树的遍历操作功能相似,是图的一种根本操作,图的许多其它操作都是建立在遍历操作的根底上。由于图构造本身的复杂性,所以图的遍历操作也比较复杂,主要表现在以下几个方面:(1) 在图构造中,没有一个确定的首结点,图中任意一个顶点都可以作为第一个被访问的结点。(2) 在非连通图中,从一个顶点出发,只能够访问它所在的连通分量上

2、的所有顶点,因此,还需要考虑如何选取下一个出发点以访问图中其余的连通分量。(3) 在图构造中,如果有回路存在,那么一个顶点被访问后,有可能沿回路又回到该顶点。(4) 在图构造中,一个顶点可以和其它多个顶点相连,当这样的顶点访问过后,存在如何选取下一个要访问的顶点的问题。 基于以上分析,图的遍历方法目前有深度优先搜索(DFS)和广度优先搜索(BFS)两种算法。下面将介绍两种算法的实现思路,分析算法效率并编程实现。1.1 深度优先搜索算法深度优先搜索算法是树的先根遍历的推广,它的实现思想是:从图G的某个顶点V0出发,访问V0,然后选择一个与V0相邻且没被访问过的顶点Vi访问,再从Vi出发选择一个与

3、Vi相邻且未被访问的顶点Vj进展访问,依次继续。如果当前被访问过的顶点的所有邻接顶点都已被访问,那么退回已被访问的顶点序列中最后一个拥有未被访问的相邻顶点的顶点W,从W出发按同样的方法向前遍历,直到图中所有顶点都被访问。其递归算法如下:Boolean visitedMAX_VERTEX_NUM; /访问标志数组Status (*VisitFunc)(int v); /VisitFunc是访问函数,对图的每个顶点调用该函数void DFSTraverse (Graph G, Status(*Visit)(int v)VisitFunc = Visit;for(v=0; vG.vexnum; +v

4、)visitedv = FALSE; /访问标志数组初始化for(v=0; v=0; w=NextAdjVex(G,v,w)/FirstAdjVex返回v的第一个邻接顶点,假设顶点在G中没有邻接顶点,那么返回空0。/假设w是v的邻接顶点,NextAdjVex返回v的相对于w的下一个邻接顶点。/假设w是v的最后一个邻接点,那么返回空0。if(!visitedw)DFS(G, w); /对v的尚未访问的邻接顶点w调用DFS由以上表达可知,深度优先搜索算法的效率取决于图的数据构造的表示方法。当访问某顶点Vi时,DFS的时间主要消耗在从该顶点出发搜索它的所有邻接点上。用邻接矩阵表示图时,其搜索时间为O

5、(n);用邻接表表示图时,需搜索第i个边表上的所有结点。因此,对所有n个顶点访问,在邻接矩阵上共需检查n2个矩阵元素,而在邻接表上需将边表中所有e个结点检查一遍。故由理论分析可知,DFS的时间复杂度为O(n2)或O(n+e)。1.2 广度优先搜索算法广度优先搜索算法是树的按层次遍历的推广,它的根本思路是:首先访问初始点Vi,并将其标记为已访问点,然后访问Vi的所有未被访问过的邻接点Vi1,Vi2,Vit,并均标记为已访问,再按照Vi1,Vi2,Vit的顺序,依次访问每一个顶点的所有未被访问过的邻接点,并标记为已访问。依次类推,直到图中所有和初始点Vi有路径相通的顶点都被访问过为止。如果仍有未被

6、访问过的顶点,该算法必须从图的其它连通分量的任意顶点重新开场。其非递归算法如下:Boolean visitedMAX_VERTEX_NUM; /访问标志数组Status (*VisitFunc)(int v); /VisitFunc是访问函数,对图的每个顶点调用该函数void BFSTraverse (Graph G, Status(*Visit)(int v)VisitFunc = Visit;for(v=0; vG.vexnum, +v)visitedv = FALSE;initQueue(Q); /置空辅助队列Qfor(v=0; v=0; w=NextAdjVex(G,u,w)if(!V

7、isitedw) /w为u的尚未访问的邻接顶点Visitedw=TRUE; VisitFunc(w);EnQueue(Q, w);广度优先搜索算法的时间复杂度和深度优先搜索算法的时间复杂度一样。和深度优先搜索不同的是,广度优先搜索的队列是惟一的,对于具有n个顶点和e条边的无向图或有向图,每个顶点均入队一次,当图是连通图时,只需要调用一次邻接矩阵或邻接链表即可完成遍历操作。故邻接矩阵表示法的遍历时间效率为O(n2),邻接链表表示法的遍历时间效率为O(n+e)。1.3 运行结果及分析这里选择邻接矩阵作为图的存储构造编写程序,然后将图1的顶点和边输入程序作为测试。fhdgebac图1 测试图程序运行

8、结果如以下图2:图2运行结果图由结果知,对图1深度优先遍历的结果为:a b d h e c f g,广度优先遍历的结果为a b c d e f g h。又因为程序的时间效率为O(n2),当测试数值非常小时,程序运行的时间将十分小,忽略不计,故遍历时间为0。2.字符串匹配问题字符串匹配(String match)是在实际工作中经常碰到的问题,通常是输入主字符串(String)和字串(又称模式Pattern)组成,然后根据一定的算法来得出字串在主字符串中的位置。通常准确的字符串匹配算法包括暴力搜索(Brute force,又叫蛮力法),KMP(Knuth-Morris-Pratt),BM(Boye

9、r Moore)等等。假定原字符串长度为n,子字符串长度为m,下面将介绍以上这三种方法并给出其实现。2.1 蛮力法蛮力法是一种简单的匹配算法,它将字串和主字符串从左方对齐,然后从左到右将子串和主字符串中每一对相应的字符串进展匹配,如果一旦不匹配,那么把字串向右移动一格,再进展下一轮匹配。因为这种尝试的最大次数是n-m+1次,在最坏的情况下,每次尝试需要进展m次比较,所以在最坏的情况下,字符比较的次数为m*(n-m+1)。故蛮力法的时间效率为O(mn)。其设计思想为:在串S、T中比较的起始下标为i和j;循环直到S中剩下的字符个数小于T的长度或T的所有字符都比较完:如果Si=Tj,那么继续比较S和

10、T的下一个字符,否那么将i和j回溯,进展下一趟比较;如果T中的字符都比较完,那么匹配成功,返回匹配的起始下标,否那么匹配失败,返回0。2.2 KMP算法KMP算法使用了输入增强的思想,对模式进展预处理以得到一些信息,把这些信息存储在表中,然后在给定文本中实际查找模式时使用这些信息。KMP算法也是将子字符串从左到右和主串进展匹配,和蛮力法不同的是,KMP算法在匹配失败后,并不是简单的从目标串的下一个字符串开场新一轮的检测,而是依据在检测之前得到的有用信息,直接跳过不必要的检测,从主串中找一个和子串字符匹配成功的字符,以这个字符为起点将字串对齐,然后开场新的匹配。从而到达一个较高的匹配效率。KMP

11、算法的时间复杂度为O(n+m),当m远小于n的时候,算法的效率将取决于主字符串的长度,即时间复杂度为O(n)。其设计思想为:在串S、T中比较的起始下标为i和j;循环直到S中剩下的字符个数小于T的长度或T的所有字符都比较完:如果Si=Tj,那么继续比较S和T的下一个字符,否那么将i向右滑动到nextj的位置,即j=nexti;如果j=0,那么将i和j分别加1,准备进展下一趟比较。如果T中的字符都比较完,那么匹配成功,返回匹配的起 始下标,否那么匹配失败,返回0。2.3 BM算法BM算法是一种准确字符串匹配算法,采用输入增强思想,对模式进展预处理以得到一些有用信息。和KMP算法不同的是,BM算法采

12、用从右到左比较的方法,同时应用到了坏字符规那么和好后缀规那么,来决定向右跳跃的距离。所谓坏字符规那么就是在BM算法从右到左扫描过程中,假设发现某个字符x不匹配,那么按如下两种情况考虑:A. 如果字符x在模式p中没有出现,那么从字符x开场的m个文本显然不可能与p匹配成功,直接跳过该区域即可。B. 如果x在模式p中出现,那么以该字符为起点将子串对齐。好后缀规那么为:假设发现某个字符不匹配的同时,已有局部字符匹配成功,那么按如下情况考虑:A. 如果在模式p中位置t处已匹配局部p1在p中某位置t1也出现,且位置t1前一个字符与位置t的前一个字符不一样,那么将p右移使t1对于t方才所在的位置。B. 如果

13、在p中任何位置已匹配局部p1都没有再出现,那么找到与p1的后缀p2一样的p的最长前缀x,向右移动p,使得x对应方才p2后缀所在位置。BM算法的时间复杂度为O(n+m2),当子串长度m非常小时,算法效率取决与主字符串的长度n。故其时间复杂度为O(n)。2. 运行结果及分析根据上面的介绍,我们编写程序来实现三种字符串匹配算法。如图3所示图3匹配算法运行结果图 由图3我们可知当随机输入主字符串和子字符串时,BF算法运行时间为0.016秒,而另外两种算法的时间为0,可忽略不计。可知明显蛮力法所花费的时间比较多,这和前面的理论分析中的蛮力法的时间复杂度为O(m*n)相符合。而通过对结果分析知,KMP算法

14、和BM算法的匹配效率非常高,这和理论分析中二者时间复杂度为O(n)也相符合。事实上,当我们输入的字符串长度非常大时,这种时间上的优势将更加明显,这里就不再一一测试了。附录(程序代码)1. 图的遍历*include * include time.h*define INFINITY 32767*define MAX_VEX 20 /最大顶点个数*define QUEUE_SIZE (MAX_VEX+1) /队列长度using namespace std;bool *visited; /访问标志数组/图的邻接矩阵存储构造typedef struct char *vexs; /顶点向量 int arcsMAX_VEXMAX_VEX; /邻接矩阵 int vexnum,arcnum; /图的当前顶点数和弧数Graph;/队列类class Queue public: void InitQueue() base=(int *)malloc(

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 医学/心理学 > 基础医学

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号