![数据结构教学计划编制问题实验5报告_第1页](http://file4.renrendoc.com/view/fa8f35d8236069782fa52ee25308b51c/fa8f35d8236069782fa52ee25308b51c1.gif)
![数据结构教学计划编制问题实验5报告_第2页](http://file4.renrendoc.com/view/fa8f35d8236069782fa52ee25308b51c/fa8f35d8236069782fa52ee25308b51c2.gif)
![数据结构教学计划编制问题实验5报告_第3页](http://file4.renrendoc.com/view/fa8f35d8236069782fa52ee25308b51c/fa8f35d8236069782fa52ee25308b51c3.gif)
![数据结构教学计划编制问题实验5报告_第4页](http://file4.renrendoc.com/view/fa8f35d8236069782fa52ee25308b51c/fa8f35d8236069782fa52ee25308b51c4.gif)
![数据结构教学计划编制问题实验5报告_第5页](http://file4.renrendoc.com/view/fa8f35d8236069782fa52ee25308b51c/fa8f35d8236069782fa52ee25308b51c5.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
HUNAN实验五最终报告题目:教学计划编制问题 学生姓名学生学号 专业班级 指导老师 2014年5月15日 需求分析输入形式:用户通过键盘输入课程总数、每门课的课程编号(固定占3位的字母数字串)和直接先修的课程号等的参数。不对非法输入做处理,假定输入的数据都合法。输出形式:如果拓扑排序成功,输出拓扑排序后的教学计划编制的顺序;如果拓扑排序不成功,输出排序错误信息,结束程序。程序功能:对于用户输入的一组课程编号,根据输入的先修顺序创建邻接矩阵进行存储,并输出拓扑排序后的课程编号的顺序。测试数据输入:输入课程总数:3输入每门课的课程编号:A01是否有直接先修的课程(T/F):F输入每门课的课程编号:A02是否有直接先修的课程(T/F):T先修课程编号:A01是否有直接先修的课程(T/F):F输入每门课的课程编号:A03是否有直接先修的课程(T/F):T先修课程编号:A02是否有直接先修的课程(T/F):F输出:教学计划编制完成,课程修读顺序为:A01,A02,A03(输入有误)课程输入错误!教学计划编制失败,请重新输入。二、概要设计 抽象数据类型题设要求使用一个有向图表示教学计划,顶点表示某门课程,有向边表示课程之间的先修关系,数据的对象是图中的每一个顶点和有向边。由此为本问题确定一个图的数据关系。 拓扑排序可以用顶点入度为0的方法实现,所以为实现拓扑排序的顶点顺序的存放,创建一个队列来存放。图的ADT数据对象:V,R(分别代表某门课程的顶点组成的一个顶点集
V
和代表课程先修关系的有向弧边组成的一个弧集
R。)数据关系:VR={<v,w>|v,w∈V且P(v,w)}<v,w>表示从v到w的一条弧,并称v为弧头,w为弧尾。基本操作: intn();//返回图中的顶点数 intfirst(int);//返回该点的第一条邻边 intnext(int); //返回该店的下一条邻边 voidsetEdge(int,int,int);//为有向边设置权值 intgetMark(int);//获得顶点的标志值 voidsetMark(int);//为顶点设置标志值队列ADT数据对象:int数据关系:R={<ai-1,ai>|ai-1,ai∈car,i=1,2,3….n}约定a1为队列头,an为队列尾。基本操作:queue();//队列结构初始化~queue();//结构销毁操作boolpush(constint&it);//数据入列boolpop(int&it);//数据出列intsize();//获取队列长度算法的基本思想通过用户输入的顶点的个数(课程数)初始化一个表示有向图的相邻矩阵,课程编号作为相邻矩阵的行列值以及有向边的关系(课程先修关系)完成一个有向图的构建。为了检验图中顶点是否都经过拓扑排序,为每个顶点初始化一个标志值0,当一个顶点经过拓扑排序后更改该顶点标志值0。对相邻矩阵棕的顶点进行入度为0的方法进行拓扑排序。排序结束后,遍历一次图中所有顶点的标志值,当有一个标志值为0时,输出错误信息,结束程序。否则,排序成功,输出排序后的顶点序列。程序的流程初始化模块:输入课程总数,再输入相应数量的课程编号及每个课程的先修课程,用这些信息初始化一个有向图。拓扑排序模块:对有向图进行拓扑排序。输出模块:根据有向图是否为空输出。为空时,输出拓扑排序结果;不为空时输出输入错误提示。各层次模块之间的调用关系初始化模块拓扑排序模块输出模块初始化模块拓扑排序模块输出模块三、详细设计物理数据类型由于用户输入的课程个数不定,所以存储拓扑排序后的顶点的个数不定,由此用链式队列来存储排序后的顶点。为了检查图中是否有回路,把每一个顶点的标志值初始化为0。有向图的基本操作初始化一个有向图 Graphm(intnumVert) { inti,j; numVertex=numVert;//顶点数 numEdge=0; mark=newint[numVert];//初始化标志数组 for(i=0;i<numVertex;i++) mark[i]=0;//每一个顶点的标志值初始化为0 matrix=(int**)newint*[numVertex]; for(i=0;i<numVertex;i++) matrix[i]=newint[numVertex];//构建一个相邻矩阵 for(i=0;i<numVertex;i++) for(j=0;j<numVertex;j++) matrix[i][j]=0; }有向图的销毁 ~Graphm() { delete[]mark; for(inti=0;i<numVertex;i++) delete[]matrix[i]; delete[]matrix;//销毁相邻矩阵 }获取第一个邻居intfirst(intv)//返回该点的第一条邻边 { inti; for(i=0;i<numVertex;i++) if(matrix[v][i]!=0)returni;//当顶点和顶点i有边时,返回顶点i的值 returni; } intnext(intv1,intv2)//获得v1的邻居v2 { inti; for(i=v2+1;i<numVertex;i++) if(matrix[v1][i]!=0)returni; returni; }其他基本操作 voidsetEdge(intv1,intv2)//设置有向图的边 { if(matrix[v1][v2]==0) numEdge++; matrix[v1][v2]=1; } intgetMark(intv)//获取顶点标记的值 {returnmark[v];} intsetMark(intv,intval)//设置访问的标记 {mark[v]=val;}拓扑排序找到第一个入度为0
的点存入队列中,从有向图中删去此顶点以及所有以它为尾的弧,再在这些点中找入度为0
的点。重复上述操作,直至图空,或者图不空但找不到无前驱的顶点为止,此时返回该队列。queue<int>topsort(GraphmG,queue<int>Q,queue<int>L,intn){ intcount[100]; intv,w,i; for(v=0;v<n;v++) {count[v]=0;} for(v=0;v<n;v++) for(w=G.first(v);w<n;w=G.next(v,w)) count[w]++; for(v=0;v<n;v++) if(count[v]==0)//找到度为0的点 { Q.push(v);G.setMark(v,1);}//顶点进队列,并更改顶点标志值为1 while(Q.size()!=0) { i=Q.front(); Q.pop(); L.push(i); for(w=G.first(i);w<n;w=G.next(i,w)) { count[w]--;//顶点度减一 if(count[w]==0)//找到度为0的点 {Q.push(w);G.setMark(w,1);}//顶点进队列,并更改顶点标志值为1 } } returnL;//返回存放排序后顶点的队列}队列基本操作//压入队列 boolpop(char*&it) { if(length()==0)returnfalse; it=front->elem; qnode*ltemp=front; front=front->next; deleteltemp; if(front==NULL)rear=NULL; size--; returntrue; } //出队列 boolpush(constchar*&it){ if(rear==NULL) front=rear=newqnode(it,NULL); else//append { rear->next=newqnode(it,NULL); rear=rear->next; } size++; returntrue; } //获取队列长度 intsize()const {returnsize;}最后,判断图中是否有回路。可以通过遍历图中的每一个顶点的标记值,如果有一个为0,那么说明图中存在回路。for(i=0;i<n;i++){ if(G.getMark(i)==0)//为0时表示该顶点未经过拓扑排序 {cout<<"课程输入错误!教学计划编制失败,请重新输入。"<<endl; exit(0);}}算法的具体步骤创建一个数组存储顶点信息,再构建一个邻接矩阵存储输入的课程编号(顶点),和课程先修关系(有向边)构成的有向图的信息,然后对邻接矩阵中的图的信息进行拓扑排序,把排序结果存放在一个队列中。如果一次排序结束后,遍历顶点标志值有为0,输出输入错误提示,结束程序;否则,输出队列中存储的课程编号序列。流程图如下:伪代码如下,charv[100][5]; charv1[4],v2[4]; GraphmT; queue<int>S; cin.get(n);//输入课程总数n T.CreatGraphm(n); cin.get(v);//输入每门课的编号,保存在*v[4]数组中 for(i=0;i<n;i++) { cout<<v[i]<<"---是否有直接先修的课程(T/F):"; cin>>ch; while(ch=='T') { GetNum(n2);//输入先修课程编号 T.setEdge(n2,i);//n2在前表示先修的顺序 cout<<"是否有直接先修的课程(T/F):"; cin>>ch; } } S=topsort(T,Q,L,n);//对图T进行拓扑排序,排序序列存储在队列中返回到S cout<<"教学计划编制完成,课程修读顺序为:"<<endl; printout(S);//输出排序后的顶点序列}算法的时空分析及改进设想因为图的邻接矩阵是一个|V|×|V|矩阵,所以邻接矩阵的空间代价为Θ(|V|^2),对于有n个顶点的和E条弧的有向图而言,对此图的拓扑排序算法时间复杂度为Θ(V+E)输入和输出的格式输入:输入课程数n----cin.get(n);cout<<"输入课程总数:"; cin<<n;输入每门课的课程编号----cin.get(v);for(i=0;i<n;i++){ cout<<"输入每门课的课程编号:"<<endl; cin.get(); cin.getline(v1,4); strcpy(v[i],v1);//要用字符串拷贝函数,用等号不能正确的赋值!! }获得先修的课程编号----GetNum(n2);cout<<"先修课程编号:";cin.get();in.getline(v2,4);n2=getNum(v,n,v2)
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年企业暂时性工作合同协议
- 2025年离婚协议财产保护策划与实施策略
- 2025年体育场馆管理服务合同
- 2025年猎头项目申请报告
- 2025年高精度二维伺服系统项目规划申请报告
- 2025年住宅租赁协议法律规范
- 2025年中国内地建筑工程合同管理全书
- 2025年企业团队建设培训费用预算协议样本
- 2025年公司租用办公地点合同样本
- 2025年典当行经营许可协议书
- 学校工作总结和存在的不足及整改措施
- Petrel中文操作手册(1-3)
- 《工业自动化技术》课件
- 代理分销销售协议书
- (绩效考核)钳工技能鉴定考核试题库
- 215kWh工商业液冷储能电池一体柜用户手册
- 装卸工安全培训课件
- 钳工实训安全
- 腿部经络课件教学课件
- 中小学校岗位安全工作指南
- 《钢铁是怎样炼成的》读书分享课件
评论
0/150
提交评论