数据结构课程设计报告完整版本.docx
《数据结构课程设计报告完整版本.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计报告完整版本.docx(48页珍藏版)》请在冰豆网上搜索。
数据结构课程设计报告完整版本
第二题:
电梯模拟
1、需求分析:
模拟某校九层教学楼的电梯系统。
该楼有一个自动电梯,能在每层停留。
九个楼层由下至上依次称为地下层、第一层、第二层、……第八层,其中第一层是大楼的进出层,即是电梯的“本垒层”,电梯“空闲”时,将来到该层候命。
乘客可随机地进出于任何层。
对每个人来说,他有一个能容忍的最长等待时间,一旦等候电梯时间过长,他将放弃。
模拟时钟从0开始,时间单位为0.1秒。
人和电梯的各种动作均要消耗一定的时间单位(简记为t),比如:
有人进出时,电梯每隔40t测试一次,若无人进出,则关门;关门和开门各需要20t;每个人进出电梯均需要25t;如果电梯在某层静止时间超过300t,则驶回1层侯命。
而题目的最终要求输出时:
按时序显示系统状态的变化过程,即发生的全部人和电梯的动作序列。
2、设计
2.1设计思想:
(1)数据结构设计
本题中的电梯的变化,是一个动态变化的过程,要在动态过程中实现正常跳转,首先要确定各种跳转的状态,因而这里我使用枚举类型来表示电梯的各种状态的:
enum{up,down,stop,home}State(home);
同时初始化最初状态为电梯在本垒层。
而在电梯的运行过程中对于乘客来说,显然有一个进入电梯与出电梯的队列,因而在这里我是用的链表来实现这个过程的,同时用结构体来保存该乘客的信息:
typedefstructpassage
{
intnow;//乘客当前所在的位置
intdis;//乘客的目地地
intwait;//最长的等待的时间
intwaitnow;//已经等待的时间
structpassage*next;
}Passage;
虽然电梯中的状态是由枚举类型来实现的,但是在整个程序的运行过程中,我还是为电梯设置了一个结构体类型,以便保存更多的信息:
typedefstructlift
{
intcount_C;//计数电梯已到达的层数
intcount_A;//系统的总时间计数器记得必须初始化为0
intflag_in[High];//九个楼层有无请求的标志哪个楼层如果有请求该标志置1
intnum;//等待队列中的人数记得要进行初始化为0
intpeople;//电梯中人数
intflag_out[High];
}Lift;
(2)算法设计
顾名思义本程序在运行的过程中用到的算法便是—“电梯算法”,电梯算法借鉴了磁盘寻道C-LOOK算法,即电梯向一个方向运行,直到这个方向上没有服务为止。
2.2设计表示
(1)、函数调用关系图及其说明如下:
(2)函数接口说明:
函数中的参数均是使用的全局变量的传递,因而在函数间进行传递的过程中比较简单,下面就将主要函数及他们之间的参数的关系列出如下:
intOutOrIn(Lift&L,Passage*Queue,Passage*LiftQ);//进和出电梯的总函数
intUpdate(Lift&L,Passage*Queue,Passage*LiftQ);//刷新的函数
intRun(Lift&L,Passage*Queue,Passage*LiftQ);//整个电梯各种状态转换的函数
intOpenTheDoor(Lift&L);//开门主要是用于解决其中的时间问题
intCloseTheDoor(Lift&L);//关门
intIn(Lift&L);//进入主要是解决每个人进入电梯的时间问题
intOut(Lift&L);//出去
intTest(Lift&L,Passage*Queue,Passage*LiftQ);//电梯测试关门还是开门的函数
intRequest(Lift&L,Passage*Queue);
2.3详细设计
3、调试分析
该程序的调试过程较为轻松,基本在算法实现的基础上没有出现什么错误,因而在调试的过程中并无什么深刻印象。
4、用户手册
点击运行程序,在弹出的窗口中,会提示要输入的信息:
1、提示信息为:
“请输入图中的顶点数和弧数以及图的标志和弧的标志:
”按要求输入即可,本题即输入911va
2、提示信息为“请完成该邻接表的输入”:
由于邻接表的输入信息一般较多,而且均是采用的链表来存储,因而该部分的输入要特别的小心
3、在完成上面两步的输入后按enter键便能得到程序的运行结果,即输出完成整项工程至少需要多少时间和影响工程进度的关键活动
5测试数据及测试结果
测试数据如下:
911va
1
3
161
242
353
2
1
414
3
1
415
4
1
526
5
2
697
778
6
1
749
7
1
8210
8
1
8411
9
0
程序运行结果如下:
6、原程序清单如下:
/*
关键路径问题
2010年07月31日晚上08:
36开始动工
*/
#include
usingnamespacestd;
constintMAX_V_NUM=20;//最大存储顶点的数目
constintSTACK_INIT_SIZE=20;//栈的存储空间分配量
////数据存储部分
/*
一下是图的邻接表的存储表示,由于第一次用用的比较的生疏……
*/
typedefstructArcNode
{
intadjvex;//该弧所指向的顶点的位置
structArcNode*nextarc;//指下一条弧的指针
intinfo;//该弧相关信息即权值
intname;//弧的名字
}ArcNode;
typedefstructVNode
{
intdata;//顶点的信息
ArcNode*firstarc;//指向第一条依附该顶点的弧的指针
}AdjList[MAX_V_NUM];
typedefstruct
{
AdjListvertices;
intvnum,arcnum;//图中当前顶点数和弧数
charkind,kind1;//图中的各类标志顶点和弧
}ALGraph;
typedefstruct
{
int*base;
int*top;
intstacksize;
}Stack;
intve[MAX_V_NUM];
StackT;
//函数体描述部分
intInitStack(Stack&S);
intPush(Stack&S,int&e);
intPop(Stack&S,int&e);
intCriticalPath(ALGraph&G);
intToPoOrder(ALGraph&G,Stack&T);
intFindInDegree(ALGraph&G,int(&indegree)[MAX_V_NUM]);
/*下面是函数的具体实现部分*/
//构造一个空栈
intInitStack(Stack&S)
{
S.base=(int*)malloc(STACK_INIT_SIZE*sizeof(int));
if(!
S.base)
return0;
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;//可以用于当栈的存储空间不够的情况下进行扩充
return1;
};
//元素进栈
intPush(Stack&S,int&e)
{
*S.top++=e;
return1;
};
//元素出栈
intPop(Stack&S,int&e)
{
if(S.top==S.base)
return0;
e=*--S.top;
return1;
};
//判断栈是否为空
intStackEmpty(Stack&S)
{
if(S.top==S.base)
return1;
else
return0;
};
//找出每个顶点的入度
intFindInDegree(ALGraph&G,int(&indegree)[MAX_V_NUM])
{
ArcNode*p;
inti;
for(i=0;iindegree[i]=0;
for(i=0;i{
for(p=G.vertices[i].firstarc;p;p=p->nextarc)
indegree[p->adjvex]++;
}
return0;
}
//拓扑排序同时求出各活动的最早发生时间
intToPoOrder(ALGraph&G,Stack&T)
{
intcount=0;
inti,j,k;
StackS1;
ArcNode*p;
intindegree[MAX_V_NUM];
InitStack(T);
InitStack(S1);
FindInDegree(G,indegree);
for(i=0;iif(indegree[i]==0)
Push(S1,i);
//建立0入度顶点栈S
for(i=0;ive[i]=0;
while(!
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//cout<if(countreturn0;
else
return1;
}
//计算各顶点的最迟发生时间及进行输出
intCriticalPath(ALGraph&G)
{
intvl[MAX_V_NUM];
intdut;
inti,j,k,ee,el;
ArcNode*p;
//chartag;
if(!
ToPoOrder(G,T))
return0;
cout<<"完成整项工程至少需要的时间是:
"<for(i=0;ivl[i]=ve[G.vnum-1];
while(!
StackEmpty(T))
{
for(Pop(T,j),p=G.vertices[j].firstarc;p;p=p->nextarc)
{
k=p->adjvex;
dut=(p->info);
if(vl[k]-dutvl[j]=vl[k]-dut;
}
}
//for(i=0;i//cout<cout<<"影响工程进度的关键活动是:
"<for(j=0;jfor(p=G.vertices[j].firstarc;p;p=p->nextarc)
{
k=p->adjvex;
dut=(p->info);
ee=ve[j];
el=vl[k]-dut;
//cout<<"j="<if(ee==el)
//tag=(ee=el)?
'*':
'';
cout<name<}
return1;
}
intmain()
{
ALGraphG;
inti,j,Hnum;
ArcNode*p,*q;
//intindegree[MAX_V_NUM];
//ALGraphG;
cout<<"请输入图中的顶点数和弧数以及图的标志和弧的标志:
"<cin>>G.vnum;
cin>>G.arcnum;
cin>>G.kind;
cin>>G.kind1;
cout<<"请完成该邻接表的输入:
"<for(i=0;i{
cout<<"请输入该顶点的信息"<cin>>G.vertices[i].data;
cout<<"请输入与"<"<cin>>Hnum;
if(Hnum==0)
{
G.vertices[i].firstarc=0;
}
else
{
cout<<"请依次次输入弧的信息(包括顶点的位置及权值和该边的名称)"<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{
cout<<"请依次次输入弧的信息(包括顶点的位置及权值和该边的名称)"<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{
cout<<"该顶点是"<cout<<"与该顶点相邻的顶点依次是:
"<for(p=G.vertices[i].firstarc;p;p=p->nextarc)
{
cout<adjvex].data<}
}*/
//FindInDegree(G,indegree);
//for(i=0;i//cout<<"indegree["<
CriticalPath(G);
////////////testend///////////
return0;
system(“pause”);
}
第五题:
关键路径问题
1、需求分析:
当一项工程被划分为若干个子任务或活动后,人们不仅需要确定这些活动的先后次序,而且需要进一步计算完成整个工程的时间,确定哪些活动是影响工程进度的关键活动,以便合理组织人力、物力、财力,加快这些活动的进度,为按时或提前完成整个工程提供保证。
要求:
给定一个带权的有向图代表一个工程的AOE网络,研究如下问题:
(1)完成整项工程至少需要多少时间?
(2)哪些活动是影响工程进度的关键活动?
示例图:
2、设计
2.1设计思想:
(1)数据结构设计
本题中的数据结构主要影响在于整个程序设计过程中数据的存储和拓扑排序、关键路径算法的实现,而在算法的实现过程中又要依赖数据的存储结构,而在图的存储结构中,比较适合实现拓扑排序算法的显然是邻接表的存储结构,所以本程序设计过程中均采用的是邻接表的存储方法。
其主要数据的主要存储结构体声明如下:
typedefstructArcNode
{
intadjvex;//该弧所指向的顶点的位置
structArcNode*nextarc;//指下一条弧的指针
intinfo;//该弧相关信息即权值
intname;//弧的名字
}ArcNode;
typedefstructVNode
{
intdata;//顶点的信息
ArcNode*firstarc;//指向第一条依附该顶点的弧的指针
}AdjList[MAX_V_NUM];
typedefstruct
{
AdjListvertices;
intvnum,arcnum;//图中当前顶点数和弧数
charkind,kind1;//图中的各类标志顶点和弧
}ALGraph;
同时由于拓扑排序实现过程中要用到进栈和出栈的操作,因此还有栈的声明如下:
typedefstruct
{
int*base;
int*top;
intstacksize;
}Stack;
(2)算法设计
本程序的算法设计主要体现在拓扑排序和求事件的最早发生时间和最迟发生时间的的过程中,因此算法设计主要也是针对拓扑排序和求事件发生的最早发生和最迟发生时间的算法设计。
拓扑排序的思想是将入度为零的结点进行S1中的出栈操作,同时将其对T进行进栈,这主要是方便在进行完求最早发生时间后,通过出栈的操作直接求最迟发生时间。
2.2设计表示
(1)、函数调用关系图及其说明如下:
(2)函数接口说明:
函数中的参数均是使用的全局变量的传递,因而在函数间进行传递的过程中比较简单,下面就将主要函数及他们之间的参数的关系列出如下:
intInitStack(Stack&S);
intPush(Stack&S,int&e);
intPop(Stack&S,int&e);
intCriticalPath(ALGraph&G);
intToPoOrder(ALGraph&G,Stack&T);
intFindInDegree(ALGraph&G,int(&indegree)[MAX_V_NUM]);
2.3详细设计
该程序的算法主要在以下四个方面:
拓扑排序、求出事件的最早发生时间、求出事件的最迟发生时间、求出关键活动,其中关键活动的算法设计较为简单,即是在求出各活动的最早发生时间和最迟发生时间的前提下根据判断两时间是否相等,来判断是否是关键活动,因而主要的算法设计便在前三个方面。
拓扑排序与求事件的最早发生时间相结合,拓扑排序即将入度为零的栈S中的元素依次出栈,同时将该元素进栈到栈T中,在进栈的同时求出其最早发生时间算法如下:
从ve(0)=0开始向前递推
Ve(j)=
然后便是求事件的最迟发生时间,该过程就是对上面的过程中得到的栈T进行依次出栈,同时求其最迟发生时间,其算法简要描述如下:
从vl(n-1)=ve(n-1)起向后递推
Vl(i)=
具体实现见代码中intToPoOrder(ALGraph&G,Stack&T)和intCriticalPath(ALGraph&G)函数;
3、调试分析
该程序的调试过程较为轻松,基本在算法实现的基础上没有出现什么错误,因而在调试的过程中并无什么深刻印象。
4、用户手册
点击运行程序,在弹出的窗口中,会提示要输入的信息:
4、提示信息为:
“请输入图中的顶点数和弧数以及图的标志和弧的标志:
”按要求输入即可,本题即输入911va
5、提示信息为“请完成该邻接表的输入”:
由于邻接表的输入信息一般较多,而且均是采用的链表来存储,因而该部分的输入要特别的小心
6、在完成上面两步的输入后按enter键便能得到程序的运行结果,即输出完成整项工程至少需要多少时间和影响工程进度的关键活动
5测试数据及测试结果
测试数据如下:
911va
1
3
161
242
353
2
1
414
3
1
415
4
1
526
5
2
697
778
6
1
749
7
1
8210
8
1
8411
9
0
程序运行结果如下:
6、原程序清单如下:
/*
关键路径问题
2010年07月31日晚上08:
36开始动工
*/
#include
usingnamespacestd;
constintMAX_V_NUM=20;//最大存储顶点的数目
constintSTACK_INIT_SIZE=20;//栈的存储空间分配量
////数据存储部分
/*
一下是图的邻接表的存储表示,由于第一次用用的比较的生疏……
*/
typedefstructArcNode
{
intadjvex;//该弧所指向的顶点的位置
structArcNode*nextarc;//指下一条弧的指针
intinfo;//该弧相关信息即权值
intname;//弧的名字
}ArcNode;
typedefstructVNode
{
intdata;//顶点的信息
ArcNode*firstarc;//指向第一条依附该顶点的弧的指针
}AdjList[MAX_V_NUM];
typedefstruct
{
AdjListvertices;
intvnum,arcnum;//图中当前顶点数和弧数
charkind,kind1;//图中的各类标志顶点和弧
}ALGraph;
typedefstruct
{
int*base;
int*top;
intstacksize;
}Stack;
intve[MAX_V_NUM];
StackT;
//函数体描述部分
intInitStack(Stack&S);
intPush(Stack&S,int&e);
intPop(Stack&S,int&e);
intCriticalPath(ALGraph&G);
intToPoOrder(ALGraph&G,Stack&T);
intFindInDegree(ALGraph&G,int(&indegree)[MAX_V_NUM]);
/*下面是函数的具体实现部分*/
//构造一个空栈
intInitStack(Stack&S)
{
S.base=(int*)malloc(STA