ImageVerifierCode 换一换
格式:DOCX , 页数:14 ,大小:60.30KB ,
资源ID:10669988      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/10669988.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(福建农林大学计算机与信息学院.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

福建农林大学计算机与信息学院.docx

1、福建农林大学计算机与信息学院福建农林大学计算机与信息学院福建农林大学计算机与信息学院计算机类课程设计报告课程名称:数据结构课程设计题目:图的算法实现(1)将图的信息建立文件;2)从文件读入图的信息,建立邻接矩阵和邻接表;(3)实现Prim、Kruskal、Dijkstra和拓扑排序算法。姓 名:易向阳系:计算机专 业:计算机科学与技术(专升本)年 级:07级学 号:071806019指导教师:黄思先职 称:副教授2008年 06月 28日1课程设计的目的42课程设计要求43算法思想描述43.1、存储结构的建立43.2、Prim算法43.3、Kruskal算法53.4、Dijkstra算法53.

2、5、拓扑排序算法54程序结构55测试结果66总结7参考文献8附录:91.课程设计的目的此次课程设计的目的是以C语言为基础,通过完成一些具有一定难度的课程设计题目的编写、调试、运行工作,进一步了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;巩固所学理论知识,使理论与实际相结合。从而提高自我分析问题、解决问题的能力。用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风,同时培养学生调查研究、查阅技术文献、资料、手册以及编写技术文献的能力。2.课程设计要求图的算法实现(1)

3、将图的信息建立文件; (2)从文件读入图的信息,建立邻接矩阵和邻接表; (3)实现Prim、Kruskal、Dijkstra和拓扑排序算法。3.算法思想描述 本程序涉及到图的存储结构的建立、Prim、Kruskal、Dijkstra和拓扑排序算法。3.1、存储结构的建立: 实现从文件中读入图的信息,同时建立:有向邻接矩阵、无向邻接矩阵、有向邻接表、无向邻接表。首先进行有向邻接矩阵、邻接表和无向邻接矩阵、邻接表的初始化。初始化有向邻接矩阵和无向邻接矩阵时,因为不知道会读入几个顶点和几条边,所以取无向邻接矩阵,把它存顶点的字符数组各字符初始化为“*”,以方便判断顶点名称记录到哪了。各边的度都初始化

4、为9999,表示不连通.顶点数和边数都初始为0, GraphKind分别初始为YOUXIANG,WUXIANG。初始化有向邻接表和无向邻接表时,顶点数、边数、GraphKind初始方法同上. 所有firstarc指向NULL表示还没有边。接着,向四个图中记录读入边的信息。用一个函数判断新读入的边的顶点是否在以前读入的信息中出现过,若没出现过则去记录顶点名称,出现过则不用了。无向图把信息当作无向的,一次添加两条边,有向图把信息当作有向的,一次只添加一条边,邻接矩阵添加边时,在二维数组对应位置填入边的权,邻接表添加边时,动态申请一个AreNode,加入边的信息后,用头插法插入相应位置。3.2、Pr

5、im算法:设图中顶点的全集为V, U中存放已选中过的点,用数据结构closedge存放选择需要的数据,先把下标0对应点放入U中, closedgei.uxiabiao=0,(因为U中只有下标0这一个点), closedgei.lowcost中存放其他点到下标为0的点的权,closedge0.lowcost=0;表示下标为0的点已在U中了。在closedge按顺序找到最先不在U中,且与U中点直接相连的点,把此边的权赋给min,用擂台式比较法选出closedgej.lowcost中最小的,此时min中存放的是最小值所在下标,也就是下一个要放入U中的点的下标。输出选中的这条边,它是最小生成树中的一条

6、边。因为U中又加入了一个点,所以要修改closedgei.lowcost的值,比较新选中点与V-U中点的权和原来的closedgei.lowcost,取小的那个存入。然后继续如上的选择,循环vexnum-1次,就选出了最小生成树中的vexnum-1条边。3.3、Kruskal算法:把有向图g的所有边的信息按权的大小,从小到大存入数据结构Kruskal中。这个排序过程由比较排序实现。创建无向图g,用来存放Kruskal算法生成的最小生成树。从权最小的边开始,看它是否能加入存放最小生成树的g中, selected20记录选中过的边中包含的顶点,若该边最多一个顶点出现过,则可以加入,若两个顶点都出现

7、过,则需判断加入该边是否会构成环,从该边一个顶点出发,深度优先搜索到另一顶点,则会构成环。若判断不会构成环,则加入该边。然后继续查看下一条边,直到选完vexnum-1条边。此时g中就存放了最小生成树,把它按打印图的方式打印就可以了。3.4、Dijkstra算法:该算法用queue path记录定点到其他各点的路径,用数组shuju记录算法需要的过程中供选择的数据。先把定点到各点的权存入shuju中,再在pathi中压入定点v和各点i。然后进入for循环vexnum-2次,确定定点到其他vexnum-2个点的路径,确定过程在函数Path()中进行。 数组visit记录顶点到某点路径是否确定过了,

8、在shuju中选择一个没选择过的且权最小的点,把该点在visit中对应的标记改为1,表示该点选过了,打印出该点对应的queue中的路径,并把该路径存入数组que_min_sub20中,方便以后改变其他路径。然后修改shuju中的未选过的点的数据,例如对于i点,若刚才选中的点到i点的权+定点到刚才选中的点的权shujui时修改。然后再循环,在shuju中选择点。3.5、拓扑排序算法:该算法首先用数组indegree存放每个顶点的入度,count记录输出过的顶点总数,先将入度为0的点放入队列q中,然后进入循环,队列不空时,弹出一个点,count加一,并把与从该点出发直接相连的点的入度减一,如果减的

9、结果是0则压入队列,然后循环,继续从队列中弹出下一个点。若循环结束时,count比顶点总数小,则说明该图中存在环。 首先对有向图,我们采取邻接表作为数据结构。且将表头指针改为头结点,其数据域存放该结点的入度,入度设为零的结点即没有前趋,至于删除结点及其为尾的弧运算,则可由将这些头顶点的入度减一来实现。在建立邻接表输入之前,表头向量的每个结点的初始状态为数据域VEX(入度)为零,指针域NXET为空,每输入一条弧 建立链表的一个结点,同时令k 的入度加1,因此在输入结束时,表头的两个域分别表示顶点的入度和指向链表的第一个结点指针。在拓扑排序的过程之中,输入入度为零(即没有前趋)的顶点,同时将该顶点

10、的直接后继的入度减1。5.1查邻接表中入度为零的顶点,并进栈。5.2当栈为空时,进行拓扑排序。(1)、退栈,输出栈顶元素V。(2)、在邻接表中查找Vj的直接后继Vk,将Vk的入度减一,并令入度减至零的顶点进栈。5.3 若栈空时输出的顶点数不是N个则说明有向回路,否则拓扑排序结束。为建立存放入度为零的顶点的栈,不需要另分配存储单元,即可借入入度为零的数据域。一方面,入度为零的顶点序号即为表头结点的序号,另一方面,借用入度为零的数据域存放带链栈的指针域(下一个入度的顶点号。 4.程序结构本程序的结构如图1所示。其中xiabiao函数用于判断新读入的边的顶点是否在以前读入的信息中出现过,若没出现过则

11、去记录顶点名称,出现过则不用了。Quan_sort函数用于选择权最小的边。cha_ru函数用于将选出的边加入存放最小生成树的图中。y_n_huan函数用来判断加入新的边后,是否会构成环。Path函数用来选择一个点到其余各点中最短的路径,并修改选择后其余各点到U中点的最短路径长度。图1图15.测试结果本程序在VC+环境下加以实现,通过实验表明运行正确。下面介绍一个实验示例。 (1)程序的主菜单,如图2:图2(2)图3是用prim算法得到的最小生成树:图3(3)图4是用kruskal算法得到的最小生成树,显示的是它的邻接表:图4(4)图5是由其中一个点到其他点的最短路径:图5(5)图6是该图的拓扑

12、排序序列:图66.总结图是上学期学习的一个比较复杂的知识点,它包含了丰富的内容。通过课程设计加深了我对图知识的认识,巩固了关于图的一些算法:建立邻接矩阵和邻接表,Prim、Kruskal、Dijkstra和拓扑排序算法。通过课程设计,有如下几点收获和体会:1、在上学期的学习中,建立邻接矩阵和邻接表,Prim、Dijkstra和拓扑排序算法都有详细的讲解,Kruskal算法则只是讲解了大概思想,并没有涉及编程的内容,这就成了整个课程设计中最麻烦的一部分。在做这部分的时候,我并没有像书中介绍的方法,而是用了一个比较繁琐的方法,重新创建了一个图,用来存放生成的最小生成树。从权最小的边开始,看它是否能

13、加入存放最小生成树的图中, 用一个数组记录选中过的边中包含的顶点,若该边最多一个顶点在数组中出现过,则可以加入,若两个顶点都出现过,则需判断加入该边是否会构成环,方法是从该边一个顶点出发,深度优先搜索到另一顶点,则会构成环,否则不会构成环。这样使程序显得冗长,不过功能还是能完整的实现的。2、整个程序和以往所编的程序最大的区别就是要求从文件读入信息,文件是C语言中极其重要的部分,通过课程设计,加深了对文件知识的掌握。我的程序原先是只能从固定的一个文件读入图的信息,经过修改,它可以通过输入文件名来选择要读入的文件,使程序更加灵活,功能更加完善。3、通过课程设计还提高了一点改错能力,对于一些常见问题

14、加深了印象。每次课程设计都会有多多少少的收获,这些收获将成为以后学习中一笔不可或缺的财富。参考文献:1 谭浩强. C语言程序设计(第二版)M.北京:清华大学出版社,20032 严蔚敏. 吴伟民. 数据结构(C语言版)M.北京:清华大学出版社,20053 李云清. 杨庆红. 揭安全. 数据结构(C语言版)M.北京:人民邮电出版社,20064 陈慧南. 图书馆目录832676 北京:高等教育出版社 2005.130-140.5 宁正元,王秀丽. 北京:清华大学出版社 2006.53-91.附录:参考程序/*最小生成树*/#includestdio.h/*标准输入输出*/#includealloc.

15、h/*分配空间*/# define nax 20#define null 0/* define link struct type1 */typedef struct type1int vex;struct type1 *next; link;/* int vex;link naxt;*/#define len sizeof(link)#define NULL 0 link *alnax+1; int n,e; link *p; int storenax+1; void readlist() int i,j,k; link *q; printf(请输入结点数目N=n); scanf(n%d,&n

16、); printf(请输入有向图的关联对数E=?n); scanf(n%d,&e); for(i=1;ivex=0; ali-next=NULL; for(i=1;i=e;i+) printf(输入第%d对关联对n,i); scanf(n%d,%d,&j,&k); alk-vex=alk-vex+1; q=(link *)malloc(len); q-vex=k; q-next=alj-next; alj-next=q; void topo() int i,j,k,top; link *q; top=0; for(i=1;ivex=0) ali-vex=top; top=i; i=0; whi

17、le(top) j=top; top=altop-vex; i=i+1; storei=j; q=alj-next; while(q) k=q-vex; alk-vex=alk-vex-1; if(alk-vex=0) alk-vex=top; top=k; q=q-next; if(in) printf(有环,不能进行拓扑排序!n); else printf(拓扑序列为:); for(i=1;i=n;i+) printf(%5d,storei); /*dijkstra 算法*/void Dijkstra(int x) int markn0+1,distn0+1,pathn0+1; int i

18、,j,k; int min; for(i=1;i=n;i+) /为数组赋初值 marki=2; disti=mapmatrixxi; pathi=x; markx=1; /找到第二组中找到离原点最近的节点,把其下标给k for(i=2;i=n;i+) min=32767; for(j=1;j=n;j+) if(markj=2&distjmin) /若是第二组中的并且该值小于min保存该节点的小标 min=distj; / 把该值赋给min k=j; / 记录该值的小标 markk=1; for(j=1; j(double)distk+(double)mapmatrixkj) distj=dis

19、tk+mapmatrixkj; pathj=k; /将k保存在path中作为原点到该节点的路径的倒数第二个节点 for(i=1; i=n; i+) /按path中的记录输出最短路径 if(i!=x) printf(%d:%d,disti,i); / 输出该节点值与该节点的名 j=i; while(j!=x) / 当不为起点时做 j=pathj; /将j赋值为从原点到j的到数第个节点 printf(-%d,j); / 输出j printf(n); void main() readlist(); topo(); createmap(); /创建图的函数 printmapmatrix(); /使用邻接表输出 dfs(1); /深度优先遍历 printf(n); bfs(1); /广度优先遍历 printf(n); Dijkstra(1); /Dijkstra算法 getch();

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1