当前位置:文档之家› 数据结构课程设计报告(完整版)[1]

数据结构课程设计报告(完整版)[1]

第二题:电梯模拟1、需求分析:模拟某校九层教学楼的电梯系统。

该楼有一个自动电梯,能在每层停留。

九个楼层由下至上依次称为地下层、第一层、第二层、……第八层,其中第一层是大楼的进出层,即是电梯的“本垒层”,电梯“空闲”时,将来到该层候命。

乘客可随机地进出于任何层。

对每个人来说,他有一个能容忍的最长等待时间,一旦等候电梯时间过长,他将放弃。

模拟时钟从0开始,时间单位为0.1秒。

人和电梯的各种动作均要消耗一定的时间单位(简记为t),比如:有人进出时,电梯每隔40t测试一次,若无人进出,则关门;关门和开门各需要20t;每个人进出电梯均需要25t;如果电梯在某层静止时间超过300t,则驶回1层侯命。

而题目的最终要求输出时:按时序显示系统状态的变化过程,即发生的全部人和电梯的动作序列。

2、设计2.1设计思想:(1)数据结构设计本题中的电梯的变化,是一个动态变化的过程,要在动态过程中实现正常跳转,首先要确定各种跳转的状态,因而这里我使用枚举类型来表示电梯的各种状态的:enum {up,down,stop,home}State(home);同时初始化最初状态为电梯在本垒层。

而在电梯的运行过程中对于乘客来说,显然有一个进入电梯与出电梯的队列,因而在这里我是用的链表来实现这个过程的,同时用结构体来保存该乘客的信息:typedef struct passage{int now;//乘客当前所在的位置int dis;//乘客的目地地int wait;//最长的等待的时间int waitnow;//已经等待的时间struct passage *next;}Passage;虽然电梯中的状态是由枚举类型来实现的,但是在整个程序的运行过程中,我还是为电梯设置了一个结构体类型,以便保存更多的信息:typedef struct lift{int count_C;//计数电梯已到达的层数int count_A;//系统的总时间计数器记得必须初始化为0int flag_in[High];//九个楼层有无请求的标志哪个楼层如果有请求该标志置1int num;//等待队列中的人数记得要进行初始化为0int people;//电梯中人数int flag_out[High];}Lift;(2)算法设计顾名思义本程序在运行的过程中用到的算法便是—“电梯算法”,电梯算法借鉴了磁盘寻道C-LOOK算法,即电梯向一个方向运行,直到这个方向上没有服务为止。

2.2设计表示(1)、函数调用关系图及其说明如下:(2)函数接口说明:函数中的参数均是使用的全局变量的传递,因而在函数间进行传递的过程中比较简单,下面就将主要函数及他们之间的参数的关系列出如下:int OutOrIn(Lift &L,Passage *Queue,Passage *LiftQ);//进和出电梯的总函数int Update(Lift &L,Passage *Queue,Passage *LiftQ);//刷新的函数int Run(Lift &L,Passage *Queue,Passage *LiftQ);//整个电梯各种状态转换的函数int OpenTheDoor(Lift &L);//开门主要是用于解决其中的时间问题int CloseTheDoor(Lift &L);//关门int In(Lift &L);//进入主要是解决每个人进入电梯的时间问题int Out(Lift &L);//出去int Test(Lift &L,Passage *Queue,Passage *LiftQ);//电梯测试关门还是开门的函数int Request(Lift &L,Passage *Queue);2.3详细设计3、调试分析该程序的调试过程较为轻松,基本在算法实现的基础上没有出现什么错误,因而在调试的过程中并无什么深刻印象。

4、用户手册点击运行程序,在弹出的窗口中,会提示要输入的信息:1、提示信息为:“请输入图中的顶点数和弧数以及图的标志和弧的标志:”按要求输入即可,本题即输入9 11 v a2、提示信息为“请完成该邻接表的输入”:由于邻接表的输入信息一般较多,而且均是采用的链表来存储,因而该部分的输入要特别的小心3、在完成上面两步的输入后按enter键便能得到程序的运行结果,即输出完成整项工程至少需要多少时间和影响工程进度的关键活动5 测试数据及测试结果测试数据如下:9 11 v a131 6 12 4 23 5 3214 1 4314 1 5415 2 6526 9 77 7 8617 4 9718 2 10818 4 119程序运行结果如下:6、原程序清单如下:/*关键路径问题2010年07月31日晚上08:36开始动工*/#include<iostream>using namespace std;const int MAX_V_NUM=20;//最大存储顶点的数目const int STACK_INIT_SIZE=20;//栈的存储空间分配量////数据存储部分/*一下是图的邻接表的存储表示,由于第一次用用的比较的生疏……*/typedef struct ArcNode{i nt adjvex; //该弧所指向的顶点的位置s truct ArcNode *nextarc;//指下一条弧的指针i nt info;//该弧相关信息即权值i nt name;//弧的名字}ArcNode;typedef struct VNode{i nt data;//顶点的信息A rcNode *firstarc;//指向第一条依附该顶点的弧的指针}AdjList[MAX_V_NUM];typedef struct{A djList vertices;i nt vnum,arcnum;//图中当前顶点数和弧数c har kind,kind1;//图中的各类标志顶点和弧}ALGraph;typedef struct{i nt *base;i nt *top;i nt stacksize;}Stack;int ve[MAX_V_NUM];Stack T;//函数体描述部分int InitStack(Stack &S);int Push(Stack &S,int &e);int Pop(Stack &S,int &e);int CriticalPath(ALGraph &G);int ToPoOrder(ALGraph &G,Stack &T);int FindInDegree(ALGraph &G,int (&indegree)[MAX_V_NUM]);/*下面是函数的具体实现部分*///构造一个空栈int InitStack(Stack &S){S.base=(int*)malloc(STACK_INIT_SIZE*sizeof(int));i f(!S.base)return 0;S.top=S.base;S.stacksize=STACK_INIT_SIZE;//可以用于当栈的存储空间不够的情况下进行扩充r eturn 1;};//元素进栈int Push (Stack &S, int &e){*S.top++=e;r eturn 1;};//元素出栈int Pop(Stack &S, int &e){i f(S.top==S.base)return 0;e=*--S.top;r eturn 1;};//判断栈是否为空int StackEmpty(Stack &S){i f(S.top==S.base)return 1;e lsereturn 0;};//找出每个顶点的入度int FindInDegree(ALGraph &G,int (&indegree)[MAX_V_NUM]) {A rcNode *p;i nt i;f or(i=0;i<MAX_V_NUM;i++)indegree[i]=0;f or(i=0;i<G.vnum;i++){for(p=G.vertices[i].firstarc;p;p=p->nextarc)indegree[p->adjvex]++;}r eturn 0;}//拓扑排序同时求出各活动的最早发生时间int ToPoOrder(ALGraph &G,Stack &T){i nt count=0;i nt i,j,k;S tack S1;A rcNode *p;i nt indegree[MAX_V_NUM];I nitStack(T);I nitStack(S1);F indInDegree(G,indegree);f or(i=0;i<G.vnum;i++)if(indegree[i]==0)Push(S1,i);//建立0入度顶点栈Sf or(i=0;i<G.vnum;i++)ve[i]=0;w hile(!StackEmpty(S1)){Pop(S1,j);Push(T,j);count++;for(p=G.vertices[j].firstarc;p;p=p->nextarc){k=p->adjvex;if(--indegree[k]==0)Push(S1,k);if(ve[j]+(p->info)>ve[k])ve[k]=ve[j]+(p->info);}}// for(i=0;i<G.vnum;i++)// cout<<ve[i]<<endl;i f(count<G.vnum)return 0;e lsereturn 1;}//计算各顶点的最迟发生时间及进行输出int CriticalPath(ALGraph &G){i nt vl[MAX_V_NUM];i nt dut;A rcNode *p;// char tag;i f(!ToPoOrder(G,T))return 0;c out<<"完成整项工程至少需要的时间是:"<<ve[G.vnum-1]<<endl;f or(i=0;i<G.vnum;i++)vl[i]=ve[G.vnum-1];w hile(!StackEmpty(T)){for(Pop(T,j),p=G.vertices[j].firstarc;p;p=p->nextarc){k=p->adjvex;dut=(p->info);if(vl[k]-dut<vl[j])vl[j]=vl[k]-dut;}}// for(i=0;i<G.vnum;i++)// cout<<vl[i]<<endl;c out<<"影响工程进度的关键活动是:"<<endl;f or(j=0;j<G.vnum;j++)for(p=G.vertices[j].firstarc;p;p=p->nextarc){k=p->adjvex;dut=(p->info);ee=ve[j];el=vl[k]-dut;//cout<<"j="<<j<<"K="<<k<<"dut="<<dut<<"ee="<<ee<<"el="<<el<< endl;if(ee==el)//tag=(ee=el)?'*':'';cout<<G.kind1<<p->name<<endl;}return 1;}int main(){A LGraph G;i nt i,j,Hnum;// int indegree[MAX_V_NUM];//ALGraph G;c out<<"请输入图中的顶点数和弧数以及图的标志和弧的标志:"<<endl;c in>>G.vnum;c in>>G.arcnum;c in>>G.kind;c in>>G.kind1;c out<<"请完成该邻接表的输入:"<<endl;f or(i=0;i<G.vnum;i++){cout<<"请输入该顶点的信息"<<endl;cin>>G.vertices[i].data;cout<<"请输入与"<<G.kind<<G.vertices[i].data<<"号顶点相邻的弧的数目:"<<endl;cin>>Hnum;if(Hnum==0){G.vertices[i].firstarc=0;}else{cout<<"请依次次输入弧的信息(包括顶点的位置及权值和该边的名称)"<<endl;p=(ArcNode *)malloc(sizeof(ArcNode));G.vertices[i].firstarc=p;p->nextarc=0;cin>>p->adjvex;cin>>p->info;cin>>p->name;for(j=0;j<Hnum-1;j++){cout<<"请依次次输入弧的信息(包括顶点的位置及权值和该边的名称)"<<endl;q=(ArcNode *)malloc(sizeof(ArcNode));cin>>q->adjvex;cin>>q->info;cin>>q->name;q->nextarc=p->nextarc;p->nextarc=q;}}}//ToPoOrder(G,T);//CriticalPath(G);////////test///////////* for(i=0;i<G.vnum;i++){cout<<"该顶点是"<<G.kind<<G.vertices[i].data<<endl;cout<<"与该顶点相邻的顶点依次是:"<<endl;for(p=G.vertices[i].firstarc;p;p=p->nextarc){cout<<G.kind<<G.vertices[p->adjvex].data<<endl;}}*/// FindInDegree(G,indegree);//for(i=0;i<G.vnum;i++)// cout<<"indegree["<<i<<"]="<<indegree[i]<<endl;C riticalPath(G);////////////test end///////////r eturn 0;}/*第五题:关键路径问题1、需求分析:当一项工程被划分为若干个子任务或活动后,人们不仅需要确定这些活动的先后次序,而且需要进一步计算完成整个工程的时间,确定哪些活动是影响工程进度的关键活动,以便合理组织人力、物力、财力,加快这些活动的进度,为按时或提前完成整个工程提供保证。

相关主题