《数据结构课程设计》报告题目:课程设计题目2教学计划编制班级:700学号:09070026姓名:尹煜完成日期:2011年11月7日一.需求分析本课设的任务是根据课程之间的先后的顺序,利用拓扑排序算法,设计出教学计划,在七个学期中合理安排所需修的所有课程。
(一)输入形式:文件文件中存储课程信息,包括课程名称、课程属性、课程学分以及课程之间先修关系。
格式:第一行给出课程数量。
大于等于0的整形,无上限。
之后每行按如下格式“高等数学公共基础必修6.0”将每门课程的具体信息存入文件。
课程基本信息存储完毕后,接着给出各门课程之间的关系,把每门课程看成顶点,则关系即为边。
先给出边的数量。
大于等于0的整形。
默认课程编号从0开始依次增加。
之后每行按如下格式“1 3”存储。
此例即为编号为1的课程与编号为3的课程之间有一条边,而1为3的前驱,即修完1课程才能修3课程。
例:(二)输出形式:1.以图形方式显示有向无环图2.以文本文件形式存储课程安排(三)课设的功能1.根据文本文件中存储的课程信息(课程名称、课程属性、课程学分、课程之间关系)以图形方式输出课程的有向无环图。
拓展:其显示的有向无环图可进行拖拽、拉伸、修改课程名称等操作。
2.对课程进行拓扑排序。
3.根据拓扑排序结果以及课程的学分安排七个学期的课程。
4.安排好的教学计划可以按图形方式显示也可存储在文本文件里供用户查看。
5.点击信息菜单项可显示本人的学好及姓名“09070026 尹煜”(四)测试数据(见六测设结果)二.概要设计数据类型的定义:1.Class Graph即图类采用邻接矩阵的存储结构。
类中定义两个二维数组int[][] matrix和Object[][] adjMat。
第一个用来标记两个顶点之间是否有边,为画图服务。
第二个是为了实现核心算法拓扑排序。
2.ArrayList<DrawInfo> list用来存储课程信息。
DrawInfo类是一个辅助画图的类,其中包括成员变量num、name、shuxing、xuefen分别代表课程的编号、名称、属性、学分。
ArrayList<DrawInfo>是一个DrawInfo类型的数组,主要用来在ReadFile、DrawG、DrawC、SaveFile、Window这些类之间辅助参数传递,传递课程信息。
3.Class DrawInfo, 包括int num;String name;String shuxing;float xuefen;四个成员变量。
4.Class Edge包括int from;int to;double weight;三个成员变量。
5.Class Vertex包括int value一个成员变量。
主要程序的流程图://ReadFile.java//SaveFile.java各个类之间的调用关系图:三.详细设计实现数据类型的定义1.2.3.4.四.调试分析在调试中首先遇到的最直观的问题就是画图时不知如何安排课程的坐标。
由于课程的个数不是固定的,需要根据用户的需求输入,需要把每门课程合理的安排在版面上,并且连线要尽量清楚。
后来想出了解决的办法,求出了适合的横纵坐标x=i*100%600; y=i*30%500;(i从0到N)在选择图的存储结构的时候,一开始我选择的是邻接表,但后来遇到了困难,无法把图的顶点信息和边信息传到画图的类中,所以我选择了邻接矩阵的存储结构。
采用邻接矩阵的存储结构可以很直观的看出顶点之间的关系也利于类之间参数的传递。
在画图的过程中,计算坐标是非常困难的。
由于Graphics类中提供的矩形以及文字的画法非常繁琐,需要大量精确地计算坐标值,才能将图画的尽人意。
通过多方查找参考资料,我在网上找到了jgraph开源包(第三方包)。
JGraph的基础知识简介,一个简单的开始JGraph是一个开源的,兼容Swing的基于MVC 体系结构图形组件,具有以下特点:1)基于Swing的扩展;(鉴于现在流行的SWT,这是一个缺点,不过SWT中加入Swing也是很方便的事)2)简单、高效的设计;3)时间效率高;4)100 %纯Java;JGraph不包含实际的数据,它提供了数据的视;JGraph对象画图的机制是:将图元定义为一个一个的cell,每个cell可以是一个顶点(vertex)、边(edge)或者节点(port)中的一种。
顶点可以有邻接的顶点,他们通过边相联系,边联接的两个端点称为目标和源,每个目标或者源是一个节点。
节点是顶点的孩子。
每个cell都可以有自己的孩子。
JGraph API见/view/7c33924ef7ec4afe04a1dfff.html拓扑排序算法的分析int[] topo() {int[] result = new int[length]; //准备结果数组int index;int pos = length;while (length>=1) {index = noNext(); //找到第一个没有后继的节点assert index != -1 : "图中存在环";result[--pos] = vertexs[index].value(); //放入结果中remove(index); //从图中把它删除}return result;}由于采用邻接矩阵存储图,所以该算法的时间复杂度是O(N^2)。
如果改进为邻接表存储图来进行拓扑排序算法的话那么时间复杂度会降低,即为O(n+e)节省了时间。
通过制作本次课程设计,我体会最深的就是数据结构这门课程综合了各方面的知识,考研了我们多方面的能力。
他包括面向对象程序设计、JAVA语言程序设计、以及集合与图论、数据结构算法等各方面知识。
在做课设之前,我查询了多方面的资料,阅读了许多书籍。
学习使用图形用户界面制作课设,学习使用了第三方开源包JGraph。
五.用户使用说明首先需要用户按规定格式将课程信息存储在“课程.txt”文本文件中。
然后运行程序,来到图形用户界面。
界面包含一个菜单,菜单中有两个菜单项,分别是打开以及个人信息。
点击个人信息菜单项即可显示本人的姓名学号点击打开菜单项,即可弹出根据“课程.txt”文件中存储的课程信息画出的有向无环图。
如:课程关系图界面包括两部分,一部分则是内容窗格里面画出的有向无环图,另一部分则是按钮“生成课表”。
在内容窗格里可以对课程进行拖拽、拉伸、修改名称等操作。
如图所示双击课程即可对课程名称进行修改。
鼠标左键点住课程拖拽即可把课程放在所需要的位置。
点击按钮“生成课表后”,即可看到安排好的教学计划。
点击“保存”按钮,提示保存课程计划成功即可将安排好的教学计划存储在“课程安排.txt”文本文件中可供用户查看。
如用户想退出课程定制系统,即可点击初始界面窗口上的关闭按钮结束程序。
六.测试结果1.正常数据输入数据输出结果2.边界情况(文件为空)输入数据输出情况3.错误情况(图中存在环)输入数据输出数据局限性:本系统无法针对用户存储文件格式的异常进行提示和处理。
若用户不按照所要求的格式存储文件,则系统无法画出课程的有向无环图,也无法对教学计划进行制定,系统将无法实现所有重要功能。
存储文件是本系统至关重要的一步,但由于存储文件的格式因人而异,因此无法抓住一场进行提示处理,所以要要求用户根据正确的格式存储课程信息以保证系统的正常运行。
健壮性:本系统可以对任意以正确格式存储课程信息的文件进行读取画图操作。
并对有环图和空文件进行错误提示。
重要的一点是,画出的图可以按用户的意愿拖动,方面用户读取图信息。
七.附录程序文件名清单核心算法(图的操作——拓扑算法)package com.yy;import java.awt.Color;import com.yy.*;class Graph { //用邻接矩阵法表示的图public Vertex[] vertexs;public Object[][] adjMat; //记载是否联通protected int[][] matrix;public int length = 0;public static Object CONN = new Object(); //标致是否联通Graph() {length = 0;}public void initGraph(int numVertex) {vertexs = new Vertex[numVertex];adjMat = new Object[numVertex][numVertex];matrix = new int[numVertex][numVertex];}void add(int value) {assert length <= vertexs.length;vertexs[length++] = new Vertex(value);}void connect(int from, int to) {assert from < length;assert to < length;adjMat[from][to] = CONN; //标志联通matrix[from][to] = 1;}void remove(int index) { //移除指定的顶点remove(vertexs, index); //在顶点数组中删除指定位置的下标for (Object[] bs : adjMat) {remove(bs, index); //邻接矩阵中删除指定的列}remove(adjMat, index); //在邻接矩阵中删除指定的行length--;}private void remove(Object[] a, int index) { //在数组中移除指定的元素,后面的元素补上空位for (int i = index; i < length - 1; i++) {a[i] = a[i + 1];}}int noNext() { //寻找没有后继的节点int result = -1;OUT:for (int i = 0; i < length; i++) {for (int j = 0; j < length; j++) {if (adjMat[i][j] == CONN) {continue OUT; //如果有后继则从外循环继续寻找}}return i; //如果没有与任何节点相连,则返回该节点下标}return -1; //否则返回-1}int[] topo() {int[] result = new int[length]; //准备结果数组int index;int pos = length;while (length >= 1) {index = noNext(); //找到第一个没有后继的节点assert index != -1 : "图中存在环";result[--pos] = vertexs[index].value(); //放入结果中remove(index); //从图中把它删除}return result;}public int[][] getMatrix() {return matrix;}}八.参考资料第三方开源包JGraph。