1、数 据 结 构 课 程 设 计教学计划编制问题(图的应用)班级学号 21333 班 2133326学生姓名 孙丽提交日期 2015 年 7 月 23 日成 绩计算机与通信工程学院目 录一 需求分析11.设计任务12.功能模块图13.流程图24.目标测试2二 详细设计41.运行环境42.开发工具43.涉及知识点44.数据结构定义及基本操作45.函数调用关系图56.伪码流程6三 调试分析91.调试过程中遇到的问题与解决方法92算法的时空分析93.改进思想94.经验体会9四 用户手册9五 测试结果111.输入112.输出14六 附录16七 参考文献231一、需求分析1、设计任务教学计划编制问题(图的
2、应用)问题描述大学的每个专业都要制定教学计划。假设任何专业都有固定的学习年限,每学年含两学期,每学期的时间长度和学分上限值均相等。每个专业开设的课程都是确定的,而且课程在开设时间的安排必须满足先修关系。每门课程有哪些先修课程是确定的,可以有任意多门,也可以没有。每门课恰好占一个学期。试在这样的前提下设计一个教学计划编制程序。实现提示输入参数应包括:学期总数,一学期的学分上限,每门课的课程号(可以是固定占 3位的字母数字串) 、学分和直接先修课的课程号。应允许用户指定下列两种编排策略之一:一是使学生在各学期中的学习负担尽量均匀;二是使课程尽可能地集中在前几个学期中。若根据给定的条件问题无解,则报
3、告适当的信息;否则将教学计划输出到用户指定的文件中。计划的表格格式可以自己设计。可设学期总数不超过 12,课程总数不超过 100。如果输入的先修课程号不在该专业开设的课程序列中,则作为错误处理。2、功能模块图主程序模块栈的定义及操作 拓扑排序模块图的定义及操作1、栈的顺序存储表示2、构造空栈3、判断栈是否为空4、入栈 5、出栈1、图的邻接表存储表示2、构造图3、求图中各节点的入度1、在有向图中选个没有前驱顶点且输出。2、从图中删除该顶点和所有以它为尾的弧。CreateGraph():构造图 InitStack():构造一个空栈 StackEmpty():判断是否为空栈 Push():入栈Pop
4、():出栈 FindInDegree():求顶点的入度TopologicalSort():输出 G 顶点的拓扑排序结果23、流程图(具体流程图见详细设计伪码流程)主程序构造图 GreateGraph ( )拓扑排序 TopologicalSort开始结束4、目标测试正确测试:3错误测试:4二、详细设计1、运行环境:(1)WINDOWS 7 系统(2)C-Free 5.02、开发工具:C 语言3、涉及知识点:(1)栈。用到有关栈的操作有初始化栈、判断栈是否为空、入栈和出栈。其中栈主要用来存放入度为零的顶点,即当前无先修关系可以编排的课程。(2)图。用到有关图的操作有创建图、统计图中各顶点的入度。
5、利用邻接表作为有向图的存储结构,且在头结点中增加一个存放顶点入度的数组(indegree) 。入度为零的顶点即为没有前驱的顶点,删除顶点及以它为尾的弧的操作,则可换以弧头顶点入度减一来实现。(3)拓扑排序。(a)在有向图中选一个没有前驱的顶点且输出之。(b)从图中删除该顶点和所有以它为尾的弧。重复上述两步,直至全部顶点均已输出,或者当前图中不存在无前驱的顶点为止,后一种情况则说明有向图中存在环。4、数据结构定义及基本操作A.所用存储结构及宏定义:#define MAX_VERTEX_NUM 100 /最大课程总数#define STACK_INIT_SIZE 100 /存储空间的初始分配量#d
6、efine STACKINCREMENT 10 /存储空间的分配增量/图的邻接表存储表示typedef struct ArcNode int adjvex;/该弧所指向顶点的位置struct ArcNode *nextarc;/指向下一条弧的指针ArcNode;typedef struct VNodechar name24;/课程名int classid; /课程号int credit;/课程的学分int indegree;/该结点的入度int state;/该节点的状态,1代表已学,0代表未学ArcNode *firstarc; /指向第一条依附该顶点的弧的指针VNode,AdjListMA
7、X_VERTEX_NUM;typedef structAdjList vertices;/顶点向量int vexnum,arcnum;/图的当前顶点数和弧数ALGraph;typedef int ElemType;5/栈的顺序存储表示typedef struct /栈ElemType *base;ElemType *top;int stacksize;SqStack;B.程序中各函数的简要说明:(1)void CreatGraph(ALGraph /该弧所指向顶点的位置struct ArcNode *nextarc;/指向下一条弧的指针ArcNode;typedef struct VNodec
8、har name24;/课程名int classid; /课程号int credit;/课程的学分int indegree;/该结点的入度int state;/该节点的状态,1 代表已学,0 代表未学ArcNode *firstarc; /指向第一条依附该顶点的弧的指针VNode,AdjListMAX_VERTEX_NUM;typedef structAdjList vertices;int vexnum,arcnum;ALGraph;typedef int ElemType;typedef structElemType *base;ElemType *top;int stacksize;Sq
9、Stack;void CreateGraph(ALGraph ArcNode *p;printf(“请输入需要编排课程总数:“);scanf(“%d“,for( i=1;iG.vexnum|mG.vexnum)printf(“输入的顶点序号不正确请重新输入:“);scanf(“%d,%d“,p = (ArcNode*)malloc(sizeof(ArcNode);if (p = NULL)printf(“memory allocation failed,goodbey“);return;p-adjvex = m;p-nextarc=G.verticesn.firstarc;G.vertices
10、n.firstarc = p;printf(“n 建立的邻接表为:n“);/输出建立好的邻接表for(i=1;i“,G.verticesi.classid);for(p=G.verticesi.firstarc;p!=NULL;p=p-nextarc)18printf(“%d-“,p-adjvex);printf(“NULL“);printf(“n“);void InitStack(SqStack if (!S.base) printf(“ERROR“);return;S.top=S.base;S.stacksize=STACK_INIT_SIZE;int StackEmpty(SqStack
11、 elsereturn 0;void Push(SqStack if(!S.base) printf(“ERROR“);return;S.top=S.base+S.stacksize;S.stacksize+=10;*S.top+=e;int Pop(SqStack *e=*-S.top;return 0;19void FindInDegree(ALGraph G, int indegree)/求图中各节点的入度int i;for (i = 1; i adjvex+;G.verticesi.firstarc = G.verticesi.firstarc-nextarc;void Topolog
12、icalSort_1(ALGraph G,int numterm,int uplcredit)FILE *fp;fp=fopen(“bianpai1.txt“,“w“);struct ArcNode *p;SqStack S;int indegreeMAX_VERTEX_NUM;/存放各节点的入度 int i,j,k;int count; /课程编括排数目计数器int sumcredit;/每个学期的课程学分累加器FindInDegree(G,indegree);for (i = 1; i nextarc)/对 j 号顶点每个邻接点的入度减一G.verticesp-adjvex.indegre
13、e-;else Push(S,j);/将未输出的节点重新压入栈fprintf(fp,“n“);printf(“n“);if(countnextarc)/对 j 号顶点每个邻接点的入度减一G.verticesp-adjvex.indegree-;else Push(S,j);/将未输出的节点重新压入栈fprintf(fp,“n“);printf(“n“);if(countG.vexnum)printf(“n 课程编排出错n“);elseprintf(“n 课程编排成功n“);fclose(fp);int main()/主函数 printf(“ 教学计划编制问题n“);printf(“ (拓扑排序
14、 AOV-网)nn“);/AOV-网:顶点表示活动,弧表示活动间优先关系的有向图;int CONTINUE=1;/while(CONTINUE!=0)printf(“-n“);int numterm;/学期总数int uplcredit; /一个学期的学分上限int selectway;ALGraph G;printf(“请输入学期总数:“);scanf(“%d“,printf(“请输入一个学期的学分上限:“);scanf(“%d“,CreateGraph(G);while(CONTINUE != 0)printf(“请选择编排策略:1. 课程尽可能集中到前几个学期; 2.课程尽量均匀分布n“);scanf(“%d“,if(selectway=1)TopologicalSort_1(G,numterm,uplcredit);if(selectway=2)TopologicalSort_2(G,numterm,uplcredit);printf(“n 按 1 继续,按 0 结束:“);23scanf(“%d“, return 0;七、 参考文献1.谭浩强.C+程序设计(第 2 版).北京:清华大学出版社,20112.谭浩强.C 程序设计(第四版).北京:清华大学出版社,20103.严蔚敏,吴伟民.数据结构(C 语言版).北京:清华大学出版社,2007