1、- 1 -算法与数据结构课程设计报告系( 院): 计算机科学学院 专业班级: 计科 11101 姓 名: 袁斌 学 号: 201103258 指导教师: 周云才 设计时间: 2013.6.17 - 2012.6. 29 设计地点: 12 教机房 - 2 -报告目录一、课程设计目的 03二、设计任务及要求 03三、需求分析 04四、总体设计 04五、详细设计与实现 含代码和实现界面 06六、课程设计小结 17七、部分重要代码 18- 3 -一、课程设计目的:1能根据实际问题的具体情况,结合数据结构课程中的基本理论和基本算法,分析并正确确定数据的逻辑结构,合理地选择相应的存储结构,并能设计出解决问
2、题的有效算法。2提高程序设计和调试能力。学生通过上机实习,验证自己设计的算法的正确性。学会有效利用基本调试方法,迅速找出程序代码中的错误并且修改。3初步掌握软件开发过程中问题分析、系统设计、程序编码、测试等基本方法和技能。4训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风。5培养根据选题需要选择学习书籍,查阅文献资料的自学能力二、设计任务及要求:设计一个基于 DOS 菜单的应用程序。要利用多级菜单实现各种功能。内容如下:1 无向图的基本操作及应用: 创建无向图的邻接矩阵(5.1.1); 创建无向图的邻接表(5.1.2);- 4 - 无向图的深度优先遍
3、历(5.1.3); 无向图的广度优先遍历(5.1.4)。2 无向网的基本操作及应用 创建无向网的邻接矩阵(5.2.1); 创建无向网的邻接表(5.2.2); Prim 求最小生成树(5.2.3); Kruskal 求最小生成树( 5.2.4)。3 有向图的基本操作及应用 创建有向图的邻接矩阵(5.3.1); 创建有向图的邻接表(5.3.2); 拓扑排序(5.3.3)。4 有向网的基本操作及应用 创建有向网的邻接矩阵(5.4.1); 创建有向网的邻接表(5.4.2); 关键路径(5.4.3); 单源最短路径(5.4.4); 每对顶点之间的最短路径(5.4.5)。三、需求分析:按照需求,需要设计四
4、种图、两种存储结构、创建四种图的个两种存储结构的操作(8 个)、其他基本操作、多级菜单显示,图的操作有用到了线性表、栈和队列的基本操作。在老师给出了多级菜单现实的代码后,我们需要做的只是将函数写入其中。- 5 -四、总体设计:我用的软件是 Visual C+6.0。将不同的操作分在了不同的包里面。如右图所示。Typedef.h 包里面是所有的相关结构定义;UDG_Operation.h 包里面是有关于无向图的有关操作;UDN_Operation.h 包里面是有关于无向网的有关操作;DG_Operation.h 包里面是有关于有向图的有关操作;DN_Operation.h 包里面是有关于有向网的
5、有关操作;Queue_Operation.h 包里面是有关队列的有关操作;Stack_Operation.h 包里面是顺序栈的有关操作。包的引用很有规范,如下:#include “stdafx.h“#include “iostream“#include#include “stdlib.h“#include#include#include “malloc.h“ using namespace std;int visited20;#include “Typedef.h“#include “Queue_Operation.h“#include “Stack_Operation.h“#include
6、“UDG_Operation.h“#include “UDN_Operation.h“#include “DG_Operation.h“#include “DN_Operation.h“菜单由于老师已经给出,主要就是将函数带上参数写入代码。在菜单选择后触发函数,得出结果。函数总结:创建无向图的邻接矩阵:CreatUDG_M(MG);- 6 -打印无向图的邻接矩阵:dispgraph_MG(MG);创建无向图的邻接表:CreatUDG_ALG(ALG);打印无向图的邻接表:dispgraph_G(ALG);无向图的深度优先遍历:DFSTraverse(ALG);无向图的广度优先遍历:BFSTra
7、verse(ALG);创建无向网的邻接矩阵:CreatUDN_M(MN);打印无向网的邻接矩阵:dispgraph_MN(MN);创建无向网的邻接表:CreatUDN_ALG(ALN);打印无向网图的邻接表:dispgraph_N(ALN);Prim 算法求最小生成树:MiniSpanTree(MN,1);kraskal 算法求最小生成树:kruskal();创建有向图的邻接矩阵: CreatDG_M(MG);打印有向图的邻接矩阵:dispgraph_MG(MG);创建有向图的邻接表:CreatDG_ALG(ALG);打印有向图的邻接表:dispgraph_DG_G(ALG);拓扑排序:Top
8、ologicalSort(ALG);创建有向网的邻接矩阵:CreatDN_M(MN);打印有向网的邻接矩阵:dispgraph_MN(MN);创建有向网的邻接表:CreatDN_ALG(ALN);打印有向网的邻接表:dispgraph_DN_G(ALN);求关键路径:CriticalPath(ALN);求单源顶点最短路径:ShorttestPath_DIJ(MN,1);求每对顶点间最短路径:ShorttestPath_FLOYD(MN);- 7 -大体设计就是这么一个流程。还有一些有关于循环队列和顺序栈的操作,这里就不一一列出了。五、详细设计与实现(含代码和实现界面):5.0储存所有定义和预处
9、理的包(typedef.h)5.0.1预处理:#define MAXVEX 30/最大结点的个数#define MAXCOST 1000/最大权值#define STACKINCREMENT 10/栈的增量typedef char VertexType;/结点信息类型5.0.2图的邻接矩阵存储结构:typedef structVertexType vexsMAXVEX;/顶点信息int arcsMAXVEXMAXVEX;int vexnum,arcnum;/顶点数、边数MGraph;5.0.3图的邻接表存储结构:typedef struct arcnodeint adjvex; /邻接点序号i
10、nt w; /边或狐上的权struct arcnode *next;/指向下一条弧的指针ArcNode;typedef struct vnode VertexType data; /顶点信息int indegree; /该点的度ArcNode *firstarc; /指向下一个边结点Vnode,AdjListMAXVEX;typedef structAdjList vertices;int vexnum,arcnum;/图的当前顶点数和弧数ALGraph;5.0.4循环队列和栈的顺序存储表示- 8 -a.在处理无向图的广度优先遍历用到了循环队列极其简单操作。/栈的顺序存储表示 typedef
11、structint *base;int *top;int Stacksize;SqStack; /队列定义 typedef struct SqQueueint *base; int front;int rear;SqQueue;5.0.5多级菜单展示主菜单:次级菜单展示:- 9 -5.1无向图的基本操作及应用(UDG_Operation.h)5.1.1创建无向图的邻接矩阵用一个二维数组实现的。测试用如右图的无向图。测试结果:- 10 -5.1.2创建无向图的邻接表主要运用指针,运用链式分配存取空间。测试结果:5.1.3无向图的深度遍历无向图的深度优先遍历我采取的是用邻接表的方式。从图中的某个顶
12、点出发,访问此顶点,然后依次从 v 的未被访问的邻接点出发深度优先遍历,直至途中所有和 v 有路径相同的顶点都被访问到,若此时还有顶点未被访问,则另选图中一个未曾被访问的顶点做起始点,重复上述过程,直到所有顶点被访问完。测试结果:- 11 -5.1.4 无向图的广度优先遍历广度优先遍历也是利用邻接表,从顶点 v 出发访问 v 后依次访问 v 的各个未曾访问的邻接点,直到所有的邻接点被访问。若此时图中尚有顶点未被访问,则选择途中另一个未曾被访问的结点作为起始点重复上述过程。测试结果:5.2无向网的基本操作及应用(UDN_Operation.h )5.2.1创建无向网的邻接矩阵和无向图的几乎差不多
13、,只是当两个顶点之间存在边时,存的是边的权值,不存在边时用-1 表示。测试结果:- 12 -5.2.2创建无向图的邻接表与无向图的几乎一样,只是把权值存入其中。测试结果:5.2.3prim 算法求最小生成树主要利用无向网邻接矩阵的存取方式操作的,还需要用到一个标志数组。- 13 -测试结果: 5.2.4kraskal 算法求最小生成树主要是如何判断两个顶点是否属于同一分支,这里用一个数组记录。测试结果:- 14 -5.3.1创建有向图的邻接矩阵有向图的邻接矩阵和无向图的邻接矩阵实现过程一样,只是存的弧是有顺序的。测试结果:5.3.2创建有向图的邻接表有向图的邻接表的实现过程和无向图的过程几乎一
14、样,只是存取弧是有顺序。测试结果:5.3.3拓扑排序有向图的拓扑排序主要用到栈,采用的是有向图的邻接表的存取方法。- 15 -测试结果:5.4.1创建有向网的邻接矩阵和无向网的邻接矩阵思想一样,其中两顶点有边时,存入他们的权值,弧也是有方向的。测试结果:5.4.2创建有向网的邻接表实现过程与无向网的邻接表的实现过程一样,只是这里两点的边有方向。- 16 -测试结果: 5.4.3求关键路径主要是求取每个活动的最早和最迟发生时间,这里用到拓扑排序的思想求最早发生时间和逆拓扑排序的思想求最迟发生时间。测试结果:5.4.4求单源顶点最短路径的问题运用了迪杰斯特拉算法,用了网的邻接矩阵存取方式。所求的无
15、向网如右图。- 17 -测试结果:5.4.5求每对顶点间最短路径的问题采用了弗洛依德算法,采用的也是有向网的邻接矩阵的存取方式。测试结果:- 18 -六、课程设计小结:1难点与收获:这次是我第一次用 Visual Studio 2008 编写小程序,以前只是用它来做过一些动态网页,所以一开始使用的不是很熟悉,比如:包的导入顺序这个问题也是让我找了半天 先用到的必需放在前面。后来的编写过程也不是很顺利。书上都是一些伪码,使我不得不再到网上多看一些代码来做参考,但是也还是会遇到十分不好解决的问题。有一些算法很是复杂,参考再多也不能看懂。一般都还是得再去请教他人。代码做出来后,有的问题不是什么简单的
16、语法问题,而是逻辑问题。这种是最难找的,不过我还是想起了以前老师教的一种方法:设置断点,新加入做参考的变量一步一步的调试。用这个方法着实解决了一些变量的问题,如未初始化、没有加int v1=ALG.verticesv.data;coutadjvex=0)DFS(ALG,p-adjvex);p=p-next;void DFSTraverse(ALGraph ALG)int v;for(v=1;vfront=Q-rear=0; coutadjvex=0)v=p-adjvex;coutnext;void BFSTraverse(ALGraph ALG)int v;for(v=1;v“;coutry)
17、ry=x;elsepx=y;if(rx=ry)ry+;void kruskal()coutnm;int i,j;for(i=1;iei.u ei.v ei.w ;Init();sort(e+1,e+m+1,cmp);int cnt=0;for(i=1;i“next)k=p-adjvex ;ALG.vertices k.indegree -;if(ALG.vertices k.indegree =0)Push(S,k);- 24 -if(countnext )k=p-adjvex ;ALN.vertices k.indegree -;if(ALN.vertices k.indegree =0)P
18、ush(S,k);if(vei+p-w vek)vek=vei+p-w ;if(countnext)k=p-adjvex ;dut=p-w;if(vlk-dutnext)k=p-adjvex ;dut=p-w;ee=vei;el=vlk-dut;if(ee=el)cout( “ 0)disti.pre =v0;elsedisti.pre =0;distv0.pre =0;finalv0=1;for(i=1;i0)min=distj.length ;k=j;finalk=1;for(j=1;j“MN.vexs i“:“disti.length“(“;s.top =-1;s.data +s.top
19、 =i;j=disti.pre ;while(j)s.data +s.top =j;j=distj.pre ;- 27 -while(s.top !=-1)coutMN.vexs s.data s.top- “ “;cout“)“endl;/每对顶点最短路径问题void find(int PMAXVEXMAXVEXMAXVEX,MGraph MN,int a,int b)int k;for(k = 1; k = MN.vexnum; k+)if(Pabk=1 printf(“%ct“,MN.vexs k);find(P,MN,k,b);void ShorttestPath_FLOYD(MGra
20、ph MN)int u,v,w;int DMAXVEXMAXVEX;int PMAXVEXMAXVEXMAXVEX;for(v=1;v=MN.vexnum ;+v)for(w=1;w=MN.vexnum ;w+)Dvw=MN.arcs vw;for(u=1;u=MN.vexnum ;u+)Pvwu=0;if(Dvw!=-1)/v到w有直接路径Pvwv=1;Pvww=1;for(u=1;u=MN.vexnum ;u+)for(v=1;v=MN.vexnum ;v+)for(w=1;w=MN.vexnum ;w+)if(Dvu+DuwDvwfor(int i=1;i=MN.vexnum ;i+)Pvwi=Pvui|Puwi;- 28 -if(Dvw=-1for(int i=1;i=MN.vexnum ;i+)Pvwi=Pvui|Puwi;for(u=1;u=MN.vexnum ;u+)for(v=1;v=MN.vexnum ;v+)if(Duv!=-1coutMN.vexs u“t “;find(P,MN,u,v);coutMN.vexs v“ “;cout“长度为“Duv;coutendl;指导老师意见:成绩: 教师签名: 年 月 日