数据结构实验报告教学计划编制.doc
《数据结构实验报告教学计划编制.doc》由会员分享,可在线阅读,更多相关《数据结构实验报告教学计划编制.doc(17页珍藏版)》请在冰豆网上搜索。
数据结构与程序设计实验
实验报告
课程名称
数据结构与程序设计实验
课程编号
0906550
实验项目名称
教学计划编制
学号
年级
姓名
专业
计算机科学与技术
学生所在学院
计算机学院
指导教师
杨静
实验室名称地点
21B276
哈尔滨工程大学
实验报告五
实验课名称:
数据结构与程序设计实验
实验名称:
教学计划编制
班级:
学号:
姓名:
时间:
2016.05.03
一、问题描述
学历进修需要学生在一定的时间内完成一定的课程学习,每一门课有一定的
学分,修满学分,可获取相应的学历。
因为有些课程内容是另一些课程的学习基
础,所以课程学习之间存有一定的先后次序。
如:
某学历的计算机专业需要学习的课程及课程之间的关系如表1所示。
表1计算机专业进修课程
课程进修关系图
课程编号
课程名称
学分
C1
程序设计基础
2
C2
离散数学
3
C3
数据结构
4
C4
汇编语言
3
C5
程序设计与分析
2
C6
计算机原理
3
C7
编译原理
4
C8
操作系统
4
C9
高等数学
7
C10
线性代数
5
C11
普通物理
2
C12
数值分析
3
C13
软件工程
3
C14
数据库原理
3
本设计的主要任务是根据需要完成的课程的先修关系、每学期开设的课程总
数及总的学习时间,制定出教学计划。
需事先的基本功能如下。
a.课程进修目录的读入。
b.课程进修目录的编辑,如课程增加、删除、信息修改等。
c.满足一定条件的教学计划的输出。
二、数据结构设计
1.以邻接表存储课程名和学分
#defineMAX_VERTEX_NUM100
typedefstructArcNode{//弧结构
intadjvex;//该弧所指向的顶点的位置;
structArcNode*nextarc;//指向下一条弧的指针
InfoType*info;//弧的权值指针
}ArcNode;//表结点
typedefstruct{//头节点
VertexTypedata;//顶点信息
ArcNode*firstarc;//第一个表结点的地址,指向第一条依附该顶点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct{
AdjListvertices,vertices2;//分别存课程名和学分
intvexnum,arcnum;//图的当前顶点数和弧数
intkind;//图的种类标志
}ALGraph;//图
2.拓扑排序时为了避免重复检测入度为0的顶点,用栈暂存所有入度为0的顶点
typedefstructSqStack{
SElemType*base;
SElemType*top;
intstacksize;
}SqStack;
三、算法设计
1.利用邻接表作为存储结构,构造课程先后关系的AOV网
intLocateVex(ALGraphG,VertexTypeu){//返回顶点u在图G中的位置
inti;
for(i=0;iif(strcmp(u,G.vertices[i].data)==0)
returni;
return-1;
}
StatusCreateGraph(ALGraph&G){//构造图
inti,j,k;
VertexTypev1,v2;//顶点信息,字符串类型
ArcNode*p;//指向第一条依附某顶点的弧的指针
printf("请输入教学计划的课程数:
");//课程数即为顶点数
scanf("%d",&G.vexnum);
printf("请输入课程先修关系数(弧的数目):
");
scanf("%d",&G.arcnum);
printf("请输入%d个课程的名称(以字符代替):
\n",G.vexnum);
for(i=0;iscanf("%s",G.vertices[i].data);//存储课程名
G.vertices[i].firstarc=NULL;
}
printf("请输入%d个课程的学分值:
\n",(G).vexnum);
for(i=0;iscanf("%s",G.vertices2[i].data);//存储学分
}
printf("请顺序输入每条弧的弧尾和弧头(以空格作为间隔):
\n");
for(k=0;kscanf("%s%s",v1,v2);
i=LocateVex(G,v1);
j=LocateVex(G,v2);
p=(ArcNode*)malloc(sizeof(ArcNode));//新建一个弧节点
p->adjvex=j;//指向下一个顶点的位置
p->info=NULL;
p->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=p;
}
returnOK;
}
2.在拓扑排序时为了避免重复检测入度为0的顶点,需要用栈暂存所有入度为0的顶点,以下为栈的相关操作
StatusInitStack(SqStack*S){//构造一个空栈
(*S).base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!
(*S).base)
exit(OVERFLOW);
(*S).top=(*S).base;
(*S).stacksize=STACK_INIT_SIZE;
returnOK;
}
voidClearStack(SqStack*S){//清空栈
S->top=S->base;
}
StatusStackEmpty(SqStackS){//判断栈是否为空
if(S.top==S.base)
returnTRUE;
else
returnFALSE;
}
StatusPop(SqStack*S,SElemType*e){
if((*S).top==(*S).base)
returnERROR;
*e=*--(*S).top;
returnOK;
}
StatusPush(SqStack*S,SElemTypee){
if((*S).top-(*S).base>=(*S).stacksize){
(*S).base=(SElemType*)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!
(*S).base)
exit(OVERFLOW);
(*S).top=(*S).base+(*S).stacksize;
(*S).stacksize+=STACKINCREMENT;
}
*((*S).top)++=e;
returnOK;
}
3.拓扑排序并输出课程设计
a.在有向图中选一个没有前驱的顶点且输出之
b.从图中删除该顶点和所有以它为尾的弧
重复a,b直至全部顶点均已输出,或者不存在无前驱的顶点(图中存在环)
StatusTopologicalSort(ALGraphG){//输出G顶点的拓扑排序结果
inti,k,count;
intindegree[MAX_VERTEX_NUM];//indegree数组存放顶点入度
boolhas=false;
SqStackS;
pathonea;
pathtwob;
ArcNode*p;
FindInDegree(G,indegree);//对各顶点求入度indegree[0..vernum-1]
InitStack(&S);
for(i=0;iif(!
indegree[i])
Push(&S,i);//入度为0者入栈
}
count=0;//对输出顶点计数
while(!
StackEmpty(S)){
Pop(&S,&i);
a[i]=*G.vertices[i].data;//课程名;
b[i]=*G.vertices2[i].data;//学分;
printf("课程%s→学分%s",G.vertices[i].data,G.vertices2[i].data);
++count;
for(p=G.vertices[i].firstarc;p;p=p->nextarc){
k=p->adjvex;
if(!
(--indegree[k]))//对i号顶点的每个邻接点的入度-1
Push(&S,k);
}
}
if(countprintf("此有向图有回路\n");
returnERROR;
}else{
printf("为一个拓扑序列。
\n\n");
has=true;
}
printf("各学期中的学习负担尽量均匀(输入1)\n");
printf("用尽可能短的时间完成教学计划(输入2)?
\n");
intpattern;
printf("请选择(1or2):
");
scanf("%d",&pattern);
FindInDegree(G,indegree);//对各顶点求入度indegree[0..vernum-1]
ClearStack(&S);
printf("=====================================================\n");
printf("教学计划如下:
\n");