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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

数据结构课程设计.docx

1、数据结构课程设计算法与数据结构课程设计班 级:计科10801姓 名:指导老师2010年6月14-2010年6月25日 课程设计题目:图的基本操作及应用一引言数据结构是一门理论性强、思维抽象、难度较大的课程,是基础课和专业课之间的桥梁。该课程的先行课程是计算机基础、程序设计语言、离散数学等,后续课程有操作系统、编译原理、数据库原理、软件工程等。通过本门课程的学习,我们应该能透彻地理解各种数据对象的特点,学会数据的组织方法和实现方法,并进一步培养良好的程序设计能力和解决实际问题的能力,而且该课程的研究方法对我们学生在校和离校后的学习和工作,也有着重要的意义。数据结构是计算机科学与技术专业的一门核心

2、专业基础课程,在该专业的课程体系中起着承上启下的作用,学好数据结构对于提高理论认知水平和实践能力有着极为重要的作用。学习数据结构的最终目的是为了获得求解问题的能力。对于现实世界中的问题,应该能从中抽象出一个适当的数学模型,该数学模型在计算机内部用相应的数据结构来表示,然后设计一个解此数学模型的算法,再进行编程调试,最后获得问题的解答。二设计目的1能根据实际问题的具体情况,结合数据结构课程中的基本理论和基本算法,分析并正确确定数据的逻辑结构,合理地选择相应的存储结构,并能设计出解决问题的有效算法。2提高程序设计和调试能力。学生通过上机实习,验证自己设计的算法的正确性。学会有效利用基本调试方法,迅

3、速找出程序代码中的错误并且修改。3初步掌握软件开发过程中问题分析、系统设计、程序编码、测试等基本方法和技能。4训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风。5培养根据选题需要选择学习书籍,查阅文献资料的自学能力。三设计方案 本次课设是为了实现图的基本操作及运用,由于设计操作比较多,我们可以用代码的模块化来实现,这样看起来比较直观,也比较有条理,根据图的类别可以分为四大块:无向图,无向网,有向图以及有向网。然后在加上一个总体的菜单模块,分三级菜单实现。其实现的内容如下:1 无向图的基本操作及应用1 创建无向图的邻接矩阵2 创建无向图的邻接表3 无向

4、图的深度优先遍历4 无向图的广度优先遍历2 无向网的基本操作及应用1 创建无向网的邻接矩阵2 创建无向网的邻接表3 求最小生成树3 有向图的基本操作及应用1 创建有向图的邻接矩阵2 创建有向图的邻接表3 拓扑排序4 有向网的基本操作及应用1 创建有向网的邻接矩阵2 创建有向网的邻接表3 关键路径4 单源最短路径5 每对顶点之间的最短路径菜单流程图如下图: 四实现过程1.图的存储结构本次课设中主要采用邻接表和邻接矩阵的存储方式。邻接表:邻接表是图的一种链式存储结构。在邻接表中,对图中每个顶点建立一个单链表,第i个单链表中的结点表示依附于顶点Vi的边(对有向图是以顶点Vi为尾的弧)。每个结点由3个

5、域组成,其中邻接点域(adjvex)指示与顶点Vi邻接的点在图中的位置,链域(nextarc)指示下一条边或弧的结点;数据域(info)存储和边或弧相关的信息,如权值等。每个链表上依附一个表头结点。在表头结点中,除了设有链域(firstarc)指向链表中第一个结点之外,还设有存储顶点Vi的名或其他有关信息的数据域(data)。邻接矩阵:设G=(V,E)是具有n个顶点的图,则G的邻接矩阵是具有如下性质的n阶方阵:从图的邻接矩阵表示法中可以得到如下结论: (1)对于n个顶点的无向图,有A(i,i)=0,1in。(2)无向图的邻接矩阵是对称的,即A(i,j)=A(j,i),1in,1jn。(3)有向

6、图的邻接矩阵不一定对称的。因此用邻接矩阵来表示一个具有n个顶点的有向图时需要n2个单位来存储邻接矩阵;对有n个顶点的无向图则需存入上(下)三角形,故只需n(n+1)/2个单位。(4)无向图的邻接矩阵的第i行(或第i列)非零元素的个数正好是第i个顶点的度TD(vi)。(5)有向图的邻接矩阵的第i行(或第i列)非零元素的个数正好是第i个顶点的出度OD(vi)或入度ID(vi)。2.图的遍历 图的遍历是有关于图的算法中最常见、最典型的算法。与树的遍历相类似,图的遍历是从图中任意一个顶点出发,访问遍图中所有的顶点,且使每个顶点仅被访问一次。图的遍历算法是求解图的连通性、拓扑排序、和求关键路径等算法的基

7、础。由于图本身结构的复杂性,因而使得图的遍历要比树的遍历复杂得多。首先,图中所有顶点没有主次之分,因此也就没有一个“自然”的起始点;其次,图中任意顶点均有可能与其它顶点相邻,在沿着某一路径依次搜索访问顶点时完全有可能又回到该顶点上;此外,图中某一顶点可能与多个顶点相邻,当访问过该结点后,如何选择下一个要访问的顶点,就成为一个决策问题。鉴于图的遍历的复杂性,遍历算法的设计就必须考虑图的结构特征。图的遍历算法通常有两条遍历路径:深度优先遍历和广度优先遍历。这两种遍历既适用于无向图,也适用于有向图。 深度优先遍历方法的思想是:假设初始状态时图中所有顶点均未被访问过,从图中任意指定的顶点 V 出发 ,

8、先访问此顶点,然后基于邻接表结构访问依附于该顶点的第一个未被访问过的邻接顶点,接着仍基于邻接表结构从这个新被访问过的顶点出发,访问依附于该顶点的第一个未被访问过的邻接顶点如此访问下去直至到达一个所有邻接顶点都被访问过的顶点为止;然后倒过来依次回退到还有未被访问过的顶点,重复上述过程,直到图中所有与V有路径相通的顶点都被访问过。如果此时图中尚有没有被访问过的顶点,则再从其中一个未被访问过的顶点出发重复上述过程,直至图中所有顶点均被访问过为止。广度优先遍历的思想是:假设初始状态图中各顶点均未被访问过,从图中任意顶点 V 出发,在访问该顶点后,基于邻接表结构依次访问该顶点的所有未被访问过的邻接顶点,

9、然后分别从这些顶点出发,再依次访问它们的未被访问过的邻接顶点,并使得先被访问的顶点的邻接顶点先于后被访问的顶点的邻接顶点被访问;即从 V 开始访问,若它的邻接顶点依次是 W , X , Y,则依次访问W , X , Y,然后再访问W顶点的邻接顶点,再访问X顶点的邻接顶点,再访问Y顶点的邻接顶点,如此下去直至图中所有被访问过的顶点的邻接顶点均被访问过为止。若此时尚有未被访问过的顶点,则再从此顶点出发,重复上述过程,直到全部顶点都被访问一遍后结束。 结论:广度优先遍历相当于对广度优先生成树进行层序遍历。特别提示:对图这样的逻辑结构进行遍历,其算法通常是基于邻接表结构展开的。但无论采用深度优先遍历还

10、是广度优先遍历方法,初始选定的顶点不同,其遍历序列也不会相同,因此,遍历结果取决于三个要素:邻接表的形态(即图的存储结构);算法策略;选定的起始顶点。当三者其一发生改变,则遍历结果将随之发生变化。3最小生成树Prim算法是首先从v中任取一个顶点u0,将生成树T置为仅有一个结点u0的树,即置Uu0;然后只要U是V的真子集,就在所有那些其一个端点u己在T(即uU)、另一个端点v还未在T(即vVU)的边中,找一条最短(即权最小)的边(u,v),并把该条边(u,v)和其不在T中的顶点v,分别并入T的边集TE和顶点集U。如此进行下去,每次往生成树里并入一个顶点和一条边,直到把所有顶点都包括进生成树T为止

11、。此时,必有UV,TE中有n-1条边。MST性质保证上述过程求得的T(U,TE)是G的一棵最小生成树。Kruskal算法是一开始,先将G图中的边都去掉,只留下孤立的顶点,这个图即为G图最初的生成子图G1。然后逐步地将当前最小边e1加上去,每次加的时候,要保持住“没有圈”这一性质,在加了Nl条边(N是顶点个数)后,G1便成为所要求的最小生成树了。4拓扑排序简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序,直观地看,偏序指集合中仅有部分成员之间可比较,而全序指集合中全体成员之间均可比较。实现拓扑排序的方法很简单:(1)在有向图中选一个没有前驱的顶点且输入之。(2)从图

12、中删除该顶点和所有以它为尾的弧。重复上述两步,直至全部顶点均已输出,或者当前图中不存在无前驱的顶点为止。5 关键路径 在一个带权的有向无环图中,顶点表示事件,弧表示活动,权表示活动持续的时间。路径长度是指路径上各活动持续时间之和,不是路径上弧的数目,路径长度最长的路径叫做关键路径。假设开始点是V1,从V1到Vi的最长路径长度叫做时间Vi的最早发生时间,这个时间决定了所有以Vi为尾的弧锁表示的活动的最早开始时间,用e(i)表示活动ai的最早开始时间,还可以定义一个活动的最迟开始时间l(i),两者之差l(i)- e(i)意味着完成活动ai的时间余量。辨别关键活动就是要找e(i)= l(i)的活动。

13、6 最短路径Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,算法的基本思想:假设每个点都有一对标号 (dj, pj),其中dj是从起源点s到点j的最短路径的长度 (从顶点到其本身的最短路径是零路(没有弧的路),其长度等于零);pj则是从s到j的最短路径中j点的前一点。Floyd(弗洛伊德)算法基本思想:从代表任意2个顶点Vi到Vj的距离的带权邻接矩阵开始,用cij表示从Vi到Vj的距离(费用、时间),每次插入一个顶点Vk,然后将vi到vj间的已知最短路径与插入顶点Vk作为中间顶点(一条路径中除始点和终点外的其他顶点)时可能产生的Vi到Vj路径距离比较,取较小值以得到新的距离矩阵。如

14、此循环迭代下去,依次构造出n个矩阵(或表格)L1,L2,.Ln,当所有的顶点均作为任意 2 个顶点Vi到Vj中间顶点时得到的最后的带权邻接矩阵Ln反映了所有顶点对之间的最短距离信息,成为图G的距离矩阵。最短路径求法:定义di为在已产生的最短路径中加入一条最短边的长度,从而使得扩充的路径到达顶点i。最初,仅有从k到k的一条长度为0的路径,这时对于每个顶点i,di等于aki(a是有向图的长度邻接矩阵)。为产生下一条路径,需要选择还未产生最短路径的下一个节点,在这些节点中d值最小的即为下一条路径的终点。当获得一条新的最短路径后,由于新的最短路径可能会产生更小的d值,因此有些顶点的d值可能会发生变化,

15、更新dj值为mindj,di+aij。所有顶点对之间的最短路径是指:对于给定的有向网G=(V,E),要对G中任意一对顶点有序对V、W(VW),找出V到W的最短距离和W到V的最短距离。解决此问题的一个有效方法是:轮流以每一个顶点为源点,重复执行迪杰斯特拉算法n次,即可求得每一对顶点之间的最短路径,总的时间复杂度为O(n3)。五测试结果1无向图邻接矩阵的创建:邻接表的创建:深度优先遍历:广度优先遍历:2无向网邻接矩阵的创建:邻接表的创建:Prim算法:Kruskal算法:3有向图邻接矩阵的创建:邻接表的创建:拓扑排序:4有向网邻接矩阵的创建:邻接表的创建:关键路径:单源顶点最短路径:每对顶点最短路

16、径:六使用说明本次课设的编译平台是VC6.0,下面我将以关键路径的求解来说明一下该如何使用本程序。本程序是以模式菜单的模式来提示读者输入相关信息,主菜单模式如下图:由于关键路径的求解是有向网中的一个具体操作,因此选择菜单4,即输入数字4,输入后将跳到如下图所示的界面: 按要求应该选择子菜单3,即输入数字3,将会出现提示文字,按提示文字输入相关信息,输入完成后按回车键即可打印出结果,其效果如下图: 其他的使用方法类比这一例子都可得出运行结果,在这里就不一一列举了。七可改进的地方 由于本次课设时间安排比较紧,所以在程序上有一些不足,比如说在与用户的交互上做得不是很好,提示语句较少,而且在输出格式上

17、也做得不够完善,排版有些杂乱,也存在一定的资源浪费。在遍历过程设计中,开始存在遍历的开始顶点不明,结果出现差异,经过添加与使用者的交互,以及对代码的改进,再经过多次调试,使得输出界面明朗化,给操作者的提示也有了增加。当然还有一些程序也存在类似的问题,这里由于自身的知识功底不足,暂时没有改进的能力。在代码的模块化上,虽然在总体上看起来还不错,不过在某些细节上还做得不够。在时间复杂度和空间复杂度上也有待改进,使程序的内存占用能有降低。八难点和收获 难点:本次课设主要是实现图的基本操作与应用,总体看来难度一般,主要是在细节的把握上,以及代码模块化上,要下一些功夫,还有就是有些语法比较难懂,需要仔细的

18、研读。图是数据结构中的一个重点,也是一个难点,其应用范围较广,所包含知识点多,因此在课设的时候参考了不少资料。遍历的过程是从图的某一顶点开始,存在随意性,其复杂度比树要复杂得多,在开始编写时,没有注意到这一点,以致在测试时对输出结果的把握上出现偏差。拓扑排序也是一个难点,它要考虑图中是否存在环路,只有不存在环的图中才能输出其拓扑序列。在图的应用中有几个关键算法,例如prim(普里姆)算法,kruskal(克鲁斯卡尔)算法求最小生成树,关键路径的求解,dijkstra(迪杰斯特拉)算法,floyd(弗洛伊德)算法求最短路径,都是本次课设的难点,这是图中很重要的应用。当然这些算法中各自也有相对的优

19、越性,prim算法适用于求边稠密的网的最小生成树,kruskal算法相对于prim算法而言,它更适合于求边稀疏的网的最小生成树;dijkstra算法适用于求单源顶点各顶点的最短路径,floyd算法则更适合于求每一对顶点的最短路径。因此在算法的选择上,合理性这是一个难点。代码的模块化,是在设计一个项目的重中之重,它不仅使我们所编写的代码在界面上看起来更美观,在使用上也更简单,更容易上手。对一个设计者而言,代码的模块化是我们必须重视的问题。收获:通过这一段时间的课设,我学到了数据结构课堂上学不到的知识,认识上也有了一定的提高,对数据结构这门课程有了进一步的了解。数据结构重在算法,他是数据的一种组织

20、形式。做了这次课程设计,我觉得课程设计这种形式真的是我们需要的,可以让我们学到很多,包括书上的、书外的。课设相当于一次对课堂上所学知识的一次综合大演练,对我们理解课本,理解程序有很大的帮助。不仅如此,在程序的编写过程中了学会了如何查找相关资料,在查找资料的同时也深感自己知识的局限性,以及基本功的不牢靠。基础的牢靠对我们来说相当重要,不论是在每学期的课设中,还是在我们以后的行业从事中也起着重要的作用。正比如在建筑物的建设中,如果你的地基打得不够牢靠,那么你建的再高,也是一座危房。每次课设都是一个考验人耐心的时候,只有真正的沉下心来,才能在完成任务的同时自己能收获课堂上学不到的知识,才能拓宽自己在专业方面的知识面,才能领悟编程的主要思想课设的目的不仅仅是让我们得出结果以及一大堆代码就完事了,而是让我们学习编程的思想,只有在编程的思想上有了提高,才能算上真正的提高。培养一种编程的思想,对我们每个计算机专业的学生来说,是最根本的,也是最重要的。还有一点,就是理论和实践两者永远是戚戚相关的。在实践的上机操作中,不仅是让我们了解数据结构的理论知识,更重要的是培养解决实际问题的能力,所以相信通过此次课设可以提高我们分析设计能力和编程能力,为后续课程的学习及实践打下良好的基础。

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

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