有向图AOV网的拓扑序列生成课程设计报告-数据结构与算法课程设计报告(共12页).doc
《有向图AOV网的拓扑序列生成课程设计报告-数据结构与算法课程设计报告(共12页).doc》由会员分享,可在线阅读,更多相关《有向图AOV网的拓扑序列生成课程设计报告-数据结构与算法课程设计报告(共12页).doc(12页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、精选优质文档-倾情为你奉上题目:AOV网的拓扑序列生成一、问题分析和任务定义本次课程设计要求对于给定的AOV网求出它所有拓扑序列。AOV网(Activity on Vertex Network)是一个有向无环图(Directed Acycline Graph,DAG图)。AOV网中,如果顶点Vi表示的活动在和顶点Vj表示的活动之前进行,则称Vi是Vj的前驱顶点,Vj是Vi后继顶点。拓扑排序就是将有向无环图中的各个顶点排成一个序列,使得所有的前去后继关系都得到满足。对于相互之间没有次序关系的顶点,在拓扑排序的序列中可以处在任意的位置。因此,拓扑排序的结果往往是不唯一的。本次课程设计的主要任务就是
2、将给定的一个AOV网输出所有的该种序列。下面以图一为例:对于该图其所有的拓扑序列如下:(1)、V0 V1 V2 V3 V4(2)、V0 V1 V2 V4 V3(3)、V1 V0 V2 V3 V4(4)、V1 V0 V2 V4 V3二、数据结构的选择和概要设计对于给出的AOV网首先要确定它的存储方式,这里选择邻接表,它的具体数据结构如下图二所示:typedef struct node /邻接表中的结点类型int number; /结点编号struct node *next; /指向下一个结点int info; /与表头结点边的信息ListNode;typedef struct /定义表头结点数组
3、int number; /顶点信息ListNode *firstarc; /指向第一个邻接点AdjList; /表头结点类型typedef struct /邻接表类型AdjList headmax_vertex_num; /邻接表的组int vexnum ,edgnum; /顶点个数、边的个数ALGraph;一种拓扑序列的生成一般有一下步骤:(1)、从有向无环图中选择一个没有前驱结点的顶点并加入到结点的序列中;(2)、从有向无环图中删除该顶点以及该顶点为尾的所有的弧;(3)、重复(1)(2)的步骤。在整个拓扑排序的过程中需要频繁的检查顶点的前驱以及作删除顶点和弧的操作,在这里我们用两个全局变量
4、rudumax_vertex_num和visitedmax_vertex_num来分别实现这两个操作,如果rudui为零则表示无前驱结点,如果visitedi为零则表示没有被访问过。如果每删除一个结点就检查,那样的话时间复杂度将很大(等于遍历所有的顶点一遍),因此设计一个堆栈,把检测到的入度为零的结点入栈。每次删除顶点只要从栈中取出一个结点即可。这里堆栈也有一个数据结构,具体实现如图三所示:typedef struct int datamax_vertex_num;/堆栈数组int top;/栈顶标志Stack; /顺序表类型 但是如果需要实现一个AOV网所有拓扑序列的生成则不止如此。在每找到
5、一个符合要求的结点后入栈,从而实现一种拓扑排序。在一趟拓扑排序结束后,应该进行恢复删除的结点和删除的弧,并标记已经有过的序列,在恢复某几个个结点后进行下一次的拓扑排序。这里用到递归的思想。具体实现见下面的详细设计。三、详细设计和编码本次课程设计的重点在于输出AOV网的所有拓扑序列,因此图的创建即输出之类的问题不做为重点,在此设计过程略过。对于拓扑排序算法流程图如图四所示:实现该算法的具体编码如下:void topusort(Stack *L,ALGraph *G,int i)/拓扑排序 ListNode *P; int j,k;Soutput(L); Sinsert(L,i); /把顶点Vi加
6、入到栈中 P=G-headi.firstarc; visitedi=1; /把排序过的点标记 while(P) j=P-number; ruduj-; /把以Vi为头的终止结点入度减1 P=P-next;if(L-top+1=G-vexnum)/判断栈中一种拓扑排序完成Soutput(L);printf(n);flag+;for(k=0;kvexnum;k+)/调用部分 if(visitedk=0)&(ruduk=0)/ 如果Vk在此轮中未被访问过且入度为0topusort(L,G,k);visitedi=0; /使Vi恢复为未访问P=G-headi.firstarc; while(P) j=
7、P-number; ruduj+; /使Vj的入度恢复 ,加1 P=P-next; Sdelete(L);首先建立空栈,并从第一个顶点开始进行拓扑排序。将该结点初始化为被访问过,并将图类的结点指针指向该编号的结点的表头数组firstarc域,把该顶点入栈后,将所有的以它为起点的弧都删掉,即将弧的终点的入度都减一。接着判断栈里面的数据个数是否和图顶点的个数一样,如果一样,则说明已经有一次拓扑排序完成,若不一样,则往下进行递归,再将符合条件的顶点入栈,直到一次拓扑排序完成的条件成立。最后将顶点出栈,恢复所有结点的入度,并准备下一趟拓扑排序。注意,在这里,可能再某一次拓扑排序完成后,所有的结点还没有
8、来得及全部出栈,则发现了又可以入栈的情况如图一中的第二、四种排序就属于这种例子。四、上机调试这里我按照做课程设计的过程,将在其中遇到的问题和解决的办法都写在这里。1、课程设计开始,确定使用什么样的数据结构来存储图的时候,在邻接表和邻接矩阵之间进行徘徊。课本上使用的事邻接表,我当时想自己重新想,不按照课本上已设计好的来,但是在随后的操作中,发现在对于每个结点进行查找,删除等操作的时候才发现,用邻接矩阵很不方便,也正是在此才明白用邻接表的优越性。2、接下来就是创建图及输出图的一些函数的编写。这部分比较简单,除了一些语法错误外没有很严重的错误。这归功于以前在每次做实验的时候,这些基本的算法实现都有,
9、直接按照这里的数据结构复制过来就行了。3、下面是本次课程设计的核心部分。 (1)、在拓扑排序里面有必须设计一个数据结构来接受从图里面扫描出来没有入度且没有被访问过的结点。开始的时候对于该数据结构的选择很是犯难,这让开始一天,程序毫无进展,想过用队列用栈用顺序表,但是思想都很混乱,在将以前写过的这些基础函数都用到这里还是不能解决问题。结果我想,这个数据结构到底有什么样的特点,要什么样的功能。基于该数据结构必须实现要将开始所有的符合条件的顶点保存起来,在判断保存的数据个数是否等于图的顶点个数后,才将所有的数据的输出,作为一次拓扑排序结束。在此判断符合栈的先进先出的特点,最终确定使用栈的数据结构。其
10、实在这里对于栈到底是使用顺序栈还是链栈也是一个需要考虑的问题,一般链栈要比顺序栈要灵活,但是这里最终要用栈里面的元素个数判断是否一次拓扑排序结束,而顺序栈里面的栈顶元素正好有这个功能,所有这里选择用顺序栈。 (2)、接下来就是递归的具体实现了,开始的时候设计了一个计算入度的函数,但是后来发现这样做不好。第一、每次在删除顶点后都要计算入度,这样算法的性能里面时间和空间的复杂度都要大大的增加;第二,每次在计算入度的时候都要将图中所有的顶点都加进去,而在某些阶段,有许多的顶点已经相当于被删掉了,这样,失去了备份,连整个图都被破坏了程序会不稳定,健壮性得不到肯定。所以在这里使用了一个全局数组,用于存储
11、每个顶点的入度,而不作为图的一个部分。这样在每次删除恢复顶点的时候都很简单。 (3)、在这里遇到语法问题和很简单,大多使一些,参数没写,逗号没写等问题。仔细编译即便都得到解决了,但是下面的一些逻辑问题则用了我很多的时间去解决。 a、在删除以某个顶点为起点的弧时,没有用另外一个变量去代替形参i,导致出现混乱,有的顶点并没有作为第一个扫描对象而使许多排序情况没有。 b、在一次拓扑排序结束后,要恢复顶点的入度。在此开始没有想到要将该顶点的访问设为未访问,而至使只能输出一次拓扑排序。 c、在恢复某个单链表中所有的结点的入度的时候,要将该类型的指针先指向该表头数组的指针firstarc域.否则这部分的循
12、环根本就没有运行。因为在前面指针P在删除弧的时候已经指空了。 d、在一般的情况都实现了过后有一个很严重的问题,就是在输入的图不是网的时候,无法判断。在最后想到如果不是AOV网则不可能有拓扑排序在这里设一个全局变量count来接受拓扑排序的次数。若为0则提示改图非法。4、 主要算法的时间和空间性能的分析。分析上述拓扑排序算法,如果有向图包含n个顶点和e条弧,则第一个for循环的时间复杂度为O(n).在单链表中,查找邻接点的时间复杂度为O(e),e为图中边或弧的数目,加上访问顶点的时间,则每调用一次拓扑排序函数的时间复杂度为 O(n+e)。算法的总时间复杂度取决于调用拓扑排序函数的次数。从空间性能
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- AOV 拓扑 序列 生成 课程设计 报告 数据结构 算法 12
限制150内