数据结构课程设计-关键路径Word版_第1页
数据结构课程设计-关键路径Word版_第2页
数据结构课程设计-关键路径Word版_第3页
数据结构课程设计-关键路径Word版_第4页
数据结构课程设计-关键路径Word版_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

整理为word格式整理为word格式整理为word格式《数据结构》课程设计报告课程题目:关键路径学院:班级:学号:姓名:指导教师:完成日期:目录TOC\o"1-1"\h\z\u一、需求分析 3整理为word格式整理为word格式整理为word格式二、概要设计 4三、详细设计 5四、 调试分析 11五、 用户使用说明 12六、 测试结果 12七、 附录 13一、需求分析1、问题描述整理为word格式整理为word格式整理为word格式AOE网(即边表示活动的网络),在某些工程估算方面非常有用。它可以使人们了解:(1)研究某个工程至少需要多少时间?(2)哪些活动是影响工程进度的关键?在AOE网络中,从源点到汇点的有向路径可能不止一条,但只有各条路径上所有活动都完成了,这个工程才算完成。因此,完成整个工程所需的时间取决于从源点到汇点的最长路径长度,即在这条路径上所有活动的持续时间之和,这条路径就叫做关键路径(criticalpath)。2、设计步骤(1)、以某一工程为蓝本,采用图的结构表示实际的工程计划时间。(2)、调查并分析和预测这个工程计划每个阶段的时间。(3)、用调查的结果建立AOE网,并用图的形式表示。(4)、用CreateGraphic()函数建立图的邻接表存储结构,能够输入图的顶点和边的信息,并存储到相应存储结构中。(5)、用SearchMaxPath()函数求出最大路径,并打印出关键路径。(6)、编写代码并调试、测试通过。3、测试数据eq\o\ac(○,v2)eq\o\ac(○,v5)eq\o\ac(○,v1)eq\o\ac(○,v4)eq\o\ac(○,v6)eq\o\ac(○,v3)6v1v2v3v4v5v68v1v2a13v1v3a22v2v4a32v2v5a43v3v4a54v3v6a63v4v6a72v5v6a81整理为word格式整理为word格式整理为word格式二、 概要设计为了实现上述函数功能: 1、抽象数据类型图的定义如下:ADTGraph{数据对象V:V是具有相同特性的数据元素的集合,称为顶点集。数据关系R:R={VR};VR={<v,w>|v,w∈V,且P(v,w),<v,w>表示从v到w的弧,谓词P(v,w)定义了弧<v,w>的意义和信息}基本操作:InitGraph(G);初始条件:图G存在。操作结果:构造一个图的顶点数为MAX,弧的个数也为MAX,其他信息都相应初始化了的图。CreatGraph(&G);初始条件:已经初始化了的图G。操作结果:通过输入函数输入图的顶点个数,各顶点信息,弧的条数,以及弧的其他信息,构造图G。}2、抽象数据类型栈的定义如下:ADTStack{数据对象:D={ai|ai∈ElemSet,i=1,2,…,n,n≥0}数据关系:Rl={<ai-1,ai>|ai-1,ai∈D,i=2,…,n}约定an端为栈顶,ai端为栈底。基本操作:InitStack(&S)操作结果:构造一个空栈S。StackEmpty(S)初始条件:栈S已经存在。操作结果:若栈S为空栈,则返回TRUE,否则FALSE。整理为word格式整理为word格式整理为word格式Push(&S,e)初始条件:栈S已经存在。操作结果:插入元素e为新的栈顶元素。Pop(&S,&e)初始条件:栈S已存在且不为空。操作结果:删除S的栈顶元素,并用e返回其值。}三、详细设计1、图的邻接表存储结构如下:#defineMAX20typedefstructArcNode//表节点{ intadjvex;//该弧所指向的顶点的位置 structArcNode*next;//指向下一条弧的指针 char*info1;//表示活动,如a1、a2、a3等等 intinfo2;//表示权值}ArcNode;typedefstructVNode//头结点{ Vertextypedata[3];//顶点信息,如v1、v2、v3等等。 ArcNode*first;//指向第一条依附该顶点的弧的指针。}VNode,AdjList[MAX];typedefstruct{ AdjListvertices; intvexnum;//图的顶点数 intarcnum;//图的弧数}ALGraph;整理为word格式整理为word格式整理为word格式2、栈的顺序存储结构如下:#defineSIZEMAX20#defineADD10typedefintElemtype;typedefstruct{ Elemtype*base; Elemtype*top; intmaxsize;}Stack;3、图的构建函数设计如下:intID[MAX]={0};//存放每个顶点的入度的数组IDintve[MAX]={0};//用来存放每个顶点的最早发生时间的数组vecharstr3[MAX][10];//存放活动的字符串数组voidInitGraph(ALGraph&G)//初始化图时将图的顶点数、弧数都赋为MAX{ G.vexnum=MAX; G.arcnum=MAX; for(inti=0;i<G.vexnum;i++)//每一个头结点的first指针都指向空 G.vertices[i].first=NULL;}voidCreateGraphic(ALGraph&G){ inti,j,s,n;ArcNode*p,*pp;//定义两个指向ArcNode表结点的指针p,pp charstr1[10],str2[10];//定义两个字符串str1,str2,最大长度为10 scanf("%d\n",&G.vexnum);//输入图的顶点数vexnum for(i=0;i<G.vexnum;i++) { scanf("%s",G.vertices[i].data);//输入各顶点的信息,顶点名称整理为word格式整理为word格式整理为word格式 G.vertices[i].first=NULL;//第i个头结点的first域指向空 } scanf("%d\n",&G.arcnum);//输入图的弧数arcnumfor(i=0;i<G.arcnum;i++) { scanf("%s%s%s%d",str1,str2,str3[i],&n);//输入每条弧的其它相关信息,str1是弧的弧尾,str2是弧的弧头,str3指的是活动,n指的是权值 for(j=0;j<G.vexnum;j++)//根据str1,找对应的弧尾,若找到, if(strcmp(str1,G.vertices[j].data)==0)则停止查找,并保存弧尾 break;所示的顶点在头结点中的序号j for(s=0;s<G.arcnum;s++)//根据str1,找对应的弧头,若找到 if(strcmp(str2,G.vertices[s].data)==0)则停止查找,并保存弧头 break;所示的顶点在头结点中的序号s pp=(ArcNode*)malloc(sizeof(ArcNode));//给pp申请一个内存空间 pp->adjvex=s;//将弧头所指向的顶点的位置下标存放在pp的adjvex域中 pp->info1=str3[i];//将该弧的活动信息存放在pp的info1域中 pp->info2=n;//将该弧的权值大小存放在pp的info2域中 pp->next=NULL;//pp的next指向空 ID[s]++;//s的入度加1 if(G.vertices[j].first!=NULL)//如果序号为j的头结点的first所指向的不为 {空,则表示该顶点已经连好了一条弧,需要找下一个可存放的位置整理为word格式整理为word格式整理为word格式 p=G.vertices[j].first;//用一个临时指针保存该头结点的first指针 if(p->next!=NULL)//如果first所指向的表结点的next指向不为空, {//则需要找下一个可存放位置 while(p->next->next!=NULL)//如果p所指向的表结点的next {所指向另一表结点的next不为空,就把p指针往后移一位 p=p->next; } p=p->next; } p->next=pp;//直到p的next指向为空,再把p的next指向pp } elseG.vertices[j].first=pp;//如果序号为j的头结点的first所指向的为空,直接把它的first指向pp }}4、堆栈的功能函数设计如下:StatusInitStack(Stack&S)//栈的初始化操作{ S.base=(Elemtype*)malloc(SIZEMAX*sizeof(Elemtype));//给栈分配内存空间 if(!S.base)exit(OVERFLOW);//若分配不成功,则返回OVERFLOW; S.top=S.base;//让栈的栈顶指针和栈底指针相等 S.maxsize=SIZEMAX;//栈的当前容量为SIZEMAX returnOK;}StatusPop(Stack&S,int&e){整理为word格式整理为word格式整理为word格式 if(S.top==S.base)//如果栈的栈顶指针等于栈底指针,则表示当前栈为空 returnERROR;//栈顶元素不存在,所以返回ERROR e=*(--S.top);//如果栈不为空,就取出S的栈顶指针所指向的数据, returnOK;//并把top指针往下移一个位置}StatusPush(Stack&S,inte){ if(S.top-S.base>=S.maxsize)//如果当前栈内存的元素超过了它的最大存放量 {//则必须追加空间 S.base=(Elemtype*)realloc(S.base,(S.maxsize+ADD)*sizeof(Elemtype)); if(!S.base) exit(OVERFLOW); S.top=S.base+S.maxsize; S.maxsize=S.maxsize+ADD; } *(S.top++)=e;//top指针往上移一位后,让top指针指向元素e returnOK;}StatusEmpty(StackS){ if(S.top==S.base)returnOK; //如果栈的栈顶指针等于栈底指针,则表示当前栈为空,返回OKelsereturnERROR;//否则返回ERROR}5、求关键路径的函数设计如下:StatusTopo(ALGraphG,Stack&T)//拓扑排序函数{inti,j,k; ArcNode*p;//定义一个指向ArcNode表结点的指针p整理为word格式整理为word格式整理为word格式 StackS;//定义一个存放入度为0的顶点所在的下标值的栈InitStack(S);//初始化栈S for(j=0;j<G.vexnum;j++)//查看各个顶点的入度是否为0, if(ID[j]==0)//若为0,就让该顶点所在位置的下标值入栈 Push(S,j); intcount=0;//记录进入拓扑排序栈T的元素个数 while(!Empty(S)) { Pop(S,j);//从零入度顶点栈S中取出栈顶元素,存放在j中 Push(T,j);//元素j入栈T,表示序号为j的顶点入栈 count++; for(p=G.vertices[j].first;p;p=p->next) {//找以第j个顶点为弧尾的弧的弧头 k=p->adjvex;//保存弧头所示的顶点的位置下标 ID[k]--;//删除该弧后,弧头所示的顶点入度减1 if(ID[k]==0)Push(S,k);//如果该顶点入度为0,就入栈S if((ve[j]+(p->info2))>ve[k])ve[k]=ve[j]+(p->info2);//如果j号顶点的最早发生时间与该弧的权值之和大于k号定点的 }//最早发生时间,就改变k号顶点的最早发生时间 } if(count<G.vexnum)returnERROR;//如果拓扑序列栈中的顶点数小于图的顶点数,则表示图中有环,没有关键路径 elsereturnOK;}StatusCritial(ALGraphG)//求关键路径函数{ inti,j,k,ee,el; intvl[MAX];//存放各顶点最迟发生时间的数组vlStackT;//定义一个存放拓扑序列元素的栈T整理为word格式整理为word格式整理为word格式InitStack(T);//初始化该栈ArcNode*p; if(!Topo(G,T))returnERROR;//如果拓扑排序不成功,也无法找到关键路径,就返回ERROR for(i=0;i<G.vexnum;i++)//顶点最迟发时间始化,都等于最后一个顶点的ve vl[i]=ve[G.vexnum-1]; while(!Empty(T))//在入度顶点栈不为空的条件下循环 { for(Pop(T,j),p=G.vertices[j].first;p;p=p->next) {//取出栈顶元素,并查找以j号顶点为弧尾的弧的弧头 k=p->adjvex;//把弧头所示的顶点位置下标值存放在k中 if(vl[k]-(p->info2)<vl[j])vl[j]=vl[k]-(p->info2);//如果k号顶点的最迟发生时间与该弧的权值之差小于j号定点的最迟发生时间,就改变vl[j] } } printf("关键顶点为a:"); for(j=0;j<G.vexnum;j++) {if(ve[j]==vl[j])//如果定点的最早发生时间与最迟发生时间相等,则表示该 printf("%s",G.vertices[j].data);//顶点是关键顶点,就输出该关键顶点的名称 } printf("\n"); printf("关键路径为:"); for(j=0;j<G.vexnum;j++) { for(p=G.vertices[j].first;p;p=p->next)整理为word格式整理为word格式整理为word格式 {k=p->adjvex; ee=ve[j]; el=vl[k]-(p->info2); if(el==ee)printf("%s",p->info1); } } printf("\n"); returnOK;}四、 调试分析1、本次课程设计题目思路特别清晰,算法特别简单,但是在编程过程中遇到了一系列的问题都值得思考与分析。2、首先是在图的创建过程中,用邻接表创建图的时候,指针使用没有正确到位而引发了一系列问题,后来通过与老师同学一起分析才找到了问题的症结所在。之前用临时指针p保存头结点的first指针,然后让p指向已经存好信息的表结点pp,这样操作并没有真正把它连起来,下次循环时,又覆盖了原来的信息。3、在成功创建了图后,把主函数中生成的图作为参数传给Critial()时,又发现原来图中的活动这一信息又改变了,全变成乱码了,原来是由于存放活动的字符串str3,由于不断的输入,导致最后字符串什么也没有了,而图中每个弧的活动指针都指向它,所以就全乱了,后来就把它改为字符串数组,并且把它设为全局变量。4、在调试Critial()这一函数中,也遇到了一些问题,在观察零入度栈S的栈顶元素和拓扑序列栈T的时候,在watch窗口中输入*(S.top--),发现一直乱变,根本不知道它的栈内元素,甚至怀疑栈的初始化函数有没有写对,后来通过查找以前堆栈类型问题以及与同学题目作对比才发现就是由于窗口输入内容写错了,应该改为*(S.top-1)。整理为word格式整理为word格式整理为word格式五、 用户使用说明第一行输入顶点个数vexnum。第二行输入各个顶点的名称。第三行输入弧的边数arcnum。接下来的arcnum行输入每一条弧的弧尾顶点、弧头顶点、活动以及权值大小。六、 测试结果

七、 附录

以下是该程序设计的完整代码:#include<stdio.h>#include<string.h>#include<stdlib.h>#defineTRUE1#defineFALSE0整理为word格式整理为word格式整理为word格式#defineOK1#defineERROR0#defineOVERFLOW-2#defineMAX20#defineSIZEMAX20#defineADD10typedefintStatus;typedefintInfotype;typedefcharVertextype;typedefintElemtype;intID[MAX]={0};intve[MAX]={0};charstr3[MAX][10];typedefstructArcNode{ intadjvex; structArcNode*next; char*info1; intinfo2;}ArcNode;typedefstructVNode{ Vertextypedata[3];ArcNode*first;}VNode,AdjList[MAX];typedefstruct{ AdjListvertices; intvexnum; intarcnum;}ALGraph;typedefstruct{ Elemtype*base; Elemtype*top; intmaxsize;}Stack;voidInit(ALGraph&G){ G.vexnum=MAX;G.arcnum=MAX; for(inti=0;i<G.vexnum;i++) G.vertices[i].first=NULL;}整理为word格式整理为word格式整理为word格式voidCreateGraphic(ALGraph&G){ inti,j,s,n;ArcNode*p,*pp; charstr1[10],str2[10]; scanf("%d\n",&G.vexnum); for(i=0;i<G.vexnum;i++) { scanf("%s",G.vertices[i].data); G.vertices[i].first=NULL; } scanf("%d\n",&G.arcnum); for(i=0;i<G.arcnum;i++) { scanf("%s%s%s%d",str1,str2,str3[i],&n); for(j=0;j<G.vexnum;j++) if(strcmp(str1,G.vertices[j].data)==0) break; for(s=0;s<G.arcnum;s++) if(strcmp(str2,G.vertices[s].data)==0) break; pp=(ArcNode*)malloc(sizeof(ArcNode)); pp->adjvex=s; pp->info1=str3[i]; pp->info2=n; pp->next=NULL; ID[s]++; if(G.vertices[j].first!=NULL) { p=G.vertices[j].first; if(p->next!=NULL) { while(p->next->next!=NULL) { p=p->next; } p=p->next; } p->next=pp; } else G.vertices[j].first=pp; }}整理为word格式整理为word格式整理为word格式StatusInitStack(Stack&S){ S.base=(Elemtype*)malloc(SIZEMAX*sizeof(Elemtype)); if(!S.base)exit(OVERFLOW); S.top=S.base; S.maxsize=SIZEMAX; returnOK;}StatusPop(Stack&S,int&e){ if(S.top==S.base)returnERROR; e=*(--S.top); returnOK;}StatusPush(Stack&S,inte){ if(S.top-S.base>=S.maxsize) { S.base=(Elemtype*)realloc(S.base,(S.maxsize+add)*sizeof(Elemtype)); if(!S.base)exit(OVERFLOW); S.top=S.base+S.maxsize; S.maxsize=S.maxsize+add; } *(S.top++)=e;//*(S.top)=e,S.top++; returnOK;}StatusEmpty(StackS){ if(S.top==S.base)returnOK; elsereturnERROR;}StatusTopo(ALGraphG,Stack&T){inti,j,k; ArcNode*p; StackS;InitStack(S); for(j=0;j<G.vexnum;j++) if(ID[j]==0) Push(S,j); intcount=0; while(!Empty(S))整理为word

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论