C语言教学计划编排系统:邻接表拓扑排序实现,支持2种策略与4种排序结果

📅 2026/7/11 8:25:00
C语言教学计划编排系统:邻接表拓扑排序实现,支持2种策略与4种排序结果
C语言教学计划编排系统邻接表拓扑排序实现与策略优化引言在大学教学管理中课程安排是一项复杂而关键的任务。每个专业都需要制定合理的教学计划确保课程之间的先修关系得到满足同时还要考虑学期学分上限等约束条件。本文将介绍如何使用C语言实现一个基于邻接表和拓扑排序的教学计划编排系统支持两种不同的课程安排策略并生成四种不同的排序结果。这个系统不仅适用于计算机专业的数据结构课程设计也可以作为其他专业教学计划编制的参考工具。我们将从问题建模开始逐步讲解有向图的邻接表存储结构、拓扑排序算法的实现以及如何根据不同的策略优化课程安排顺序。1. 系统设计与数据结构1.1 问题建模与AOV网教学计划编制问题可以抽象为一个AOVActivity On Vertex网其中顶点表示课程有向边表示课程之间的先修关系例如如果课程B的先修课程是课程A则图中存在一条从A指向B的边。这样的有向图必须是无环的DAG否则会出现循环依赖无法制定合理的教学计划。1.2 邻接表存储结构我们使用邻接表来存储图结构相比邻接矩阵邻接表更适合存储稀疏图能有效节省内存空间。系统定义的核心数据结构如下#define MaxClass 99 // 最大课程数 #define MaxTerm 12 // 最大学期数 #define MaxCredit 30 // 每学期最大学分 typedef struct AdjVexNode { int AdjVex; // 邻接点的位序 struct AdjVexNode* Next; // 指向下一个邻接点的指针 } AdjVexNode; typedef struct { char data[4]; // 课程号如C01 int credit; // 课程学分 AdjVexNode* FirstArc; // 指向第一个邻接点的指针 int In_degree; // 课程入度用于拓扑排序 } VexNode; typedef struct { int term_num; // 学期总数 int max_credit; // 每学期学分上限 } Message; typedef struct { VexNode* Vex; // 顶点数组 int VexNum; // 顶点数课程数 Message* mes; // 学期信息可修改 } ClassGraph;1.3 系统功能模块系统主要功能模块包括用户菜单界面课程信息读取与存储拓扑排序实现课程安排策略选择结果输出与文件保存2. 拓扑排序算法实现2.1 基本拓扑排序原理拓扑排序是对有向无环图DAG的一种线性排序满足对于图中的每一条有向边(u,v)u在排序中总是位于v的前面。常见的拓扑排序算法有两种Kahn算法基于入度的贪心算法不断选择入度为0的顶点DFS算法基于深度优先搜索的后序遍历逆序在本系统中我们主要实现了Kahn算法的变体并进行了多种优化。2.2 四种拓扑排序变体系统实现了四种不同的拓扑排序策略通过改变节点选择顺序来产生不同的排序结果void Top_Sort(VexNode* result, int choice) { // choice1: 从后往前选择入度为0的节点层次遍历 // choice2: 从前往后选择入度为0的节点层次遍历 // choice3: 从后往前选择入度为0的节点每次选一个 // choice4: 从前往后选择入度为0的节点每次选一个 // ... 具体实现代码 }这四种策略会产生不同的课程排序序列为用户提供更多选择。2.3 环路检测在执行拓扑排序前系统会检测图中是否存在环这是通过检查最终输出的顶点数是否等于图中顶点总数来实现的if(S.size() G.VexNum) { printf(拓扑排序失败课程先修关系可能存在环路\n); return; }3. 课程安排策略系统支持两种主要的课程安排策略用户可以根据实际需求选择3.1 均匀安排策略目标尽量将课程均匀分配到各个学期避免某些学期课程过多而其他学期过少。实现方法计算每学期大致应安排的课程数在满足先修关系和学分限制的前提下尽量均匀分配if(G.VexNum % G.mes-term_num G.mes-term_num/2) per_max_num G.VexNum/G.mes-term_num; else per_max_num (G.VexNum/G.mes-term_num1);3.2 尽快安排策略目标尽可能将课程安排在前几个学期让学生尽早完成更多课程。实现方法不限制每学期课程数只考虑学分上限尽可能在每个学期安排更多课程per_max_num G.VexNum; // 不限制每学期课程数4. 系统实现与优化4.1 文件读写设计系统使用文本文件存储课程信息和先修关系格式如下学期总数 每学期学分上限 课程总数 课程号1 学分 先修课程1 先修课程2 ... 课程号2 学分 先修课程1 ... ...这种设计使得修改测试数据无需重新编译程序提高了灵活性。4.2 用户交互界面系统提供简洁的文本菜单界面支持以下功能void mainmenu() { printf(\n欢迎使用课程编排系统\n); printf(1. 查看课程信息\n); printf(2. 修改课程信息\n); printf(3. 均匀安排课程\n); printf(4. 尽快安排课程\n); printf(5. 关闭程序\n); // ... 处理用户输入 }4.3 时间复杂度分析系统主要时间消耗在拓扑排序和课程安排两个部分拓扑排序O(VE)其中V是顶点数E是边数课程安排最坏情况下O(V^2)取决于每学期能安排的课程数对于课程数不超过100的典型场景系统能够快速响应。5. 测试与结果分析5.1 测试数据设计使用教科书中的经典测试案例学期总数6每学期学分上限10课程12门C01-C12学分2,3,4,3,2,3,4,4,7,5,2,3先修关系参考教科书图7.265.2 结果对比系统会生成四种不同的拓扑排序结果并允许用户选择其中一种进行课程安排。下表展示了两种策略下的典型安排结果学期均匀安排策略课程尽快安排策略课程1C1, C9C1, C9, C102C2, C4C2, C4, C113C3, C10C3, C6, C124C5, C11C5, C85C6, C12C76C7, C8-5.3 异常处理系统能够检测并处理以下异常情况先修课程不存在学期数或学分超过上限先修关系存在环路无解情况无法在给定学期内安排所有课程6. 扩展与改进虽然当前系统已经实现了基本功能但还可以进一步扩展图形化界面使用GTK或Qt开发更友好的用户界面多策略组合允许混合使用均匀和尽快安排策略冲突检测检测课程时间冲突支持更复杂的排课约束教师分配在排课基础上增加教师资源分配功能实际使用中发现对于大型课程体系超过50门课程系统可能需要优化数据结构以提高性能。可以考虑使用更高效的图算法或并行计算技术来加速拓扑排序过程。