1、数据结构课程设计报告设计题目:教务课程计划的辅助制定班 级 学 号 姓 名 成 绩 2013-2014 年 第 1 学期一实习目的为用户编排课程,根据用户输入的信息来编排出每学期要学的课程.二问题描述(具体任务)问题描述扩展拓扑排序算法,进行课程学习计划的辅助制定。设计要求一个学生在一个学期可以同时学习多门课程,同一学期的各门课程之间不存在次序关系,制定课程计划使学生可以在最短时间内学完所有课程。三需求分析 1.程序的功能。大学的每个专业都要制订教学计划。假设任何专业都有固定的学习年限,每学年含两学期,每学期的时间长度和学分上限均相等。每个专业开设的课程都是确定的,而且课程在开设时间的安排必须
2、满足先修关系。每门课程有哪些先修课程是确定的,可以有任意多门,也可以没有。每门课恰好占一个学期。试在这样的前提下设计一个教学计划编制程序。本程序针对本科的学期内容,通过输入实际的课程及先后关系。结合每学期的学分及课程数,制定好学习计划。在输入相关数据后,程序会安排好每学期的课程。2.输入输出的要求。基本要求:a.输入参数包括:学期总数,一学期的学分上限,每门课的课程号(固定占 3 位的字母数字串) 、学分和直接先修课的课程号。b.允许用户指定下列两种编排策略之一:一是使学生在各学期中的学习负担尽量均匀;二是使课程尽可能地集中在前几个学期中。c.若根据给定的条件问题无解,则报告适当的信息;否则,
3、将教学计划输出到用户指定的文件中。计划的表格格式自行设计。四算法设计思想及流程图1.LocateVex():图的邻接表存储的基本操作。由初始条件: 图 G 存在,u 和 G 中顶点有相同特征转而进行判断,若 G 中存在顶点 u,则返回该顶点在图中位置;否则返回-1。图 GreateGreaph() 图 Display()2.CreateGraph():构造生成图。采用邻接表存储结构,构造没有相关信息的图 G(用一个函数构造种图)。3.Display():输出图的邻接矩阵。采用循环设置输出图的邻接矩阵。4.FindInDegree():求顶点的入度。图 LocateVex()图 FindInDe
4、gree() 图 InitStack()5.InitStack():构造一个空栈。6.ClearStack():清空栈。7.StackEmpty():判断栈是否为空。若栈 S 为空栈,则返回 TRUE,否则返回 FALSE。8.Pop():出栈。若栈不空,则删除 S 的栈顶元素,用 e 返回其值,并返回 OK;否则返回 ERROR。9.Push():入栈。插入元素 e 为新的栈顶元素。10.TopologicalSort():输出 G 顶点的拓扑排序结果。有向图 G 采用邻接表存储结构。若G 无回路,则输出 G 的顶点的一个拓扑序列并返回 OK, 否则返回 ERROR。五C 语言源代码#inc
5、lude#include#include / malloc()等#include / INT_MAX 等#include / EOF(=Z 或 F6),NULL#include / atoi()52#include / eof()#include / floor(),ceil(),abs()#include / exit()/ 函数结果状态代码#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1typedef int Status; / Status 是函数的类型,其值是函数结果状态代码,如
6、OK 等typedef int Boolean; / Boolean 是布尔类型,其值是 TRUE 或 FALSE#define MAX_NAME 20/* 顶点字符串的最大长度*/#define MAXCLASS 100int Z=0;int X=0;int xqzs,q=1,xfsx;typedef int InfoType;typedef char VertexTypeMAX_NAME; /* 字符串类型*/* 图的邻接表存储表示*/#define MAX_VERTEX_NUM 100typedef enumDGGraphKind; /* 有向图,有向网,无向图,无向网 */typede
7、f struct ArcNodeint adjvex; /* 该弧所指向的顶点的位置*/struct ArcNode *nextarc; /* 指向下一条弧的指针*/InfoType *info; /* 网的权值指针)*/ArcNode; /* 表结点*/typedef structVertexType data; /* 顶点信息 */ArcNode *firstarc; /* 第一个表结点的地址,指向第一条依附该顶点的弧的指针*/VNode,AdjListMAX_VERTEX_NUM; /* 头结点*/typedef structAdjList vertices,verticestwo;in
8、t vexnum,arcnum; /* 图的当前顶点数和弧数 */int kind; /* 图的种类标志 */ALGraph;/* 图的邻接表存储的基本操作 */int LocateVex(ALGraph G,VertexType u) /* 初始条件: 图 G 存在,u 和 G 中顶点有相同特征*/* 操作结果: 若 G 中存在顶点 u,则返回该顶点在图中位置; 否则返回-1 */int i;for(i=0;iadjvex=j;p-info=NULL; /* 图*/p-nextarc=(*G).verticesi.firstarc; /* 插在表头*/(*G).verticesi.first
9、arc=p;return OK;void Display(ALGraph G) /* 输出图的邻接表 G */int i;ArcNode *p;switch(G.kind)case DG: printf(“有向图n“);printf(“%d 个顶点: n“,G.vexnum);for(i=0;iadjvex.data);p=p-nextarc;printf(“n“);void FindInDegree(ALGraph G,int indegree) /* 求顶点的入度,算法调用*/int i;ArcNode *p;for(i=0;iadjvex+;p=p-nextarc;typedef int
10、 SElemType; /* 栈类型*/*栈的顺序存储表示*/#define STACK_INIT_SIZE 10 /* 存储空间初始分配量*/#define STACKINCREMENT 2 /* 存储空间分配增量*/typedef struct SqStackSElemType *base; /* 在栈构造之前和销毁之后,base 的值为 NULL */SElemType *top; /* 栈顶指针*/int stacksize; /* 当前已分配的存储空间,以元素为单位 */SqStack; /* 顺序栈*/* 顺序栈的基本操作*/Status InitStack(SqStack *S)
11、 /* 构造一个空栈 S */(*S).base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType);if(!(*S).base)exit(OVERFLOW); /* 存储分配失败 */(*S).top=(*S).base;(*S).stacksize=STACK_INIT_SIZE;return OK;void ClearStack(SqStack *S) /清空栈的操作S-top=S-base;Status StackEmpty(SqStack S) /* 若栈 S 为空栈,则返回 TRUE,否则返回 FALSE */if(S.top
12、=S.base)return TRUE;elsereturn FALSE;Status Pop(SqStack *S,SElemType *e) /* 若栈不空,则删除 S 的栈顶元素,用 e 返回其值,并返回 OK;否则返回 ERROR */if(*S).top=(*S).base)return ERROR;*e=*-(*S).top;return OK;Status Push(SqStack *S,SElemType e) /* 插入元素 e 为新的栈顶元素*/if(*S).top-(*S).base=(*S).stacksize) /* 栈满,追加存储空间*/(*S).base=(SEl
13、emType *)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;return OK;typedef int pathoneMAXCLASS;typedef int pathtwoMAXCLASS;Status TopologicalSort(ALGraph G) /* 有向
14、图 G 采用邻接表存储结构。若 G 无回路,则输出 G 的顶点的一个拓扑序列并返回OK, */* 否则返回 ERROR。*/int i,k,j=0,count,indegreeMAX_VERTEX_NUM;bool has=false;SqStack S;pathone a;pathtwo b;ArcNode *p;FindInDegree(G,indegree); /* 对各顶点求入度 indegree0vernum-1 */InitStack( /* 初始化栈*/for(i=0;inextarc) /* 对 i 号顶点的每个邻接点的入度减*/k=p-adjvex;if(!(-indegre
15、ek) /* 若入度减为,则入栈*/Push(/coutxfsx)break;indegreei-;for(p=G.verticesi.firstarc;p;p=p-nextarc) /* 对 i 号顶点的每个邻接点的入度减*/k=p-adjvex;indegreek-;/* if(!(-indegreek) 若入度减为,则入栈Push(*/resultrtop=i;rtop+;printf(“第%d 个学期的课程为:n“,qq);for(nn=0;nnrtop;nn+)printf(“课程%sn“,G.verticesresultnn.data);qq+;return OK;void mai
16、n() ALGraph f;printf(“教学计划编制问题的数据模型为拓扑排序 AOV-网结构。n“);printf(“以下为教学计划编制问题的求解过程:n“);printf(“请输入学期总数:“);scanf(“%d“,printf(“请输入学期的学分上限:“);scanf(“%d“,CreateGraph(Display(f);TopologicalSort(f);六测试分析(运行结果)输入学期总数,学分上限,课程数,先修关系边数,课程代表值,输入课程学分值输入每条弧的弧尾和弧头得出课程计划:七总结(收获及体会)在这次课程设计中,我们选择的题目是教学计划课程编制问题,我们在多方查找资料并
17、参考类似程序后,我们大体将程序的构架描绘好了。一边对照着网上的资料,一边对程序进行修改补充,然后根据拟好的大纲进行编制。这次实习,我认识到了以下几个方面。第一就是要合作。不懂的问题一定要向同学,老师请教。也能够让自己节省时间,有效率的完成工作。齐心协力完成这个程序,互相帮助,这是我们同做课题的同学的共同体会。第二就是要细心。程序的编制难免会出现错误,不能一次成功,出现错误后,一定要认真细心耐心的排查,程序才能完成。第三就是要学习。学习网上已经有的类似程序,学习他们的方法与思想。八参考文献1.数据结构教程 李春葆等 编著 清华大学出版社2.数据结构教程上机实验指导 李春葆等 编著 清华大学出版社
18、附录:测试数据开设课程为计算机专业必修课,它们是计算机导论,线性代数、离散数学、汇编语言、数据结构、操作系统等。各门课之间的次序关系见 AOV 网的数据模型。学期总数:6;学分上限:10;该专业共开设 12 门课,课程号从 C01 到 C12,学分顺序为2,3,4,3,2,3,4,4,7,5,2,3。先修关系如下: 课程编号 课程名称 先决条件C1 程序设计基础 无C2 离散数学 C1C3 数据结构 C1,C2C4 汇编语言 C1C5 语言的设计和分析 C3,C4C6 计算机原理 C11C7 编译原理 C5,C3C8 操作系统 C3,C6C9 高等数学 无C10 线性代数 C9C11 普通物理 C9C12 数值分析 C9,C10,C1图为课程之间优先关系的有向图C10C12C8C1C6C11C9C2C7C5C4C3