拓扑排序(算法与数据结构课程设计)

合集下载

拓扑排序-数据结构

拓扑排序-数据结构

拓扑排序问题描述:若用有向网表示教学计划,其中顶点表示某门课程,有向边表示课程之间的先修关系(如果A课程是B课程的先修课程,那么A到B之间有一条有向边从A 指向B)。

试设计一个教学计划编制程序,获取一个不冲突的线性的课程教学流程。

(课程线性排列,每门课上课时其先修课程已经被安排)。

基本要求:(1)输入参数:课程总数,每门课的课程号(固定占3位的字母数字串)和直接先修课的课程号。

(2)若根据输入条件问题无解,则报告适当的信息;否则将教学计划输出到用户指定的文件中。

需求分析:(测试数据加强版)1、输入形式:第一行是是个整数t,表示有t组测试数据;每一组测试数据的第一行是一个整数n,表示结点数目接下来的n行是n个顶点的信息接下来的一行是一个整数m,表示有向边的数目接下来是m行数据每一行是一条有向边的起止结点信息2、输出形式:如果可以实现拓扑排序,输出其得到的合法线性序列否则,输出“Input Error!”;3、功能描述:帮助判断当前的课程是否可以安排得当;如果得当,输出一个合法的修读顺序;4、样例输入输出:输入:25MathEnglishPhysicsChineseMusic5Math EnglishMath PhysicsEnglish ChinesePhysic ChineseChinese Music5MathEnglishPhysicsChineseMusic4Math EnglishMath PhysicsEnglish ChinesePhysic Chinese输出:Input Error!Math English Physics Chinese Music抽象数据结构类型描述(ADT):采用邻接表的方式来存储数据:抽象数据类型描述:Typedef struct Arc * link;struct Arc{Int adjvex;//邻接点编号Char info[15];//存储结点信息Link nextarc;//指向下一个邻接点};Struct Vex{Char info; //顶点信息Int indgree;//顶点的入度Link firstarc; //指向下一个邻接点};概要设计:算法主题思想:<1>、在有向图中选择一个没有前驱的顶点,输出之;<2>、从有向图中删除该顶点和所有以该顶点为尾的边;<3>、重复上述步骤,直到全部顶点都已经输出了或者图中剩下的顶点都不满足上述的两个条件位置。

算法与数据结构课设(有向图,无向图,有向网,无向网)

算法与数据结构课设(有向图,无向图,有向网,无向网)

算法与数据结构课程设计报告系(院):计算机科学学院专业班级:教技1001姓名:李##学号: ******### 指导教师:***设计时间:2012.6.16 - 2012.6.24设计地点:4号楼2号机房目录一、设计方案 (1)二、实现过程以及代码 (2)三、测试 (20)四、结论和分析 (23)五、难点和收获 (23)一、 设计方案1.程序设计基本过程:拿到课程设计任务书,按照要求,需要设计有向图、有向网、无向图 、无向网四种图,以及邻接矩阵、邻接表两种数据存储结构,三层以上的显示菜单。

图的操作中又包含了有关线性表、栈和队列的基本操作。

由于显示菜单已给出,剩下的任务就是把函数写入其中。

2.程序流程图:预定义 定义结构体 定义变量 各种函数3.程序设计的原理:图的操作都是以两种存储结构为基础的:邻接矩阵存储结构和邻接表存储结构,如有向图,有向网,无向图,无向网的创建,其他的操作都是在四种图创建后才开始进行的。

所以,首先必须理解两种存储结构的定义。

图的邻接矩阵存储结构即图的数组表示法。

用两个数组分别存储数据元素(如顶点)的信息和数据元素之间的关系(如边或弧)的信息。

用邻接矩阵存储结构的图具有以下几点特征:(一):顶点数:vexnum ,边(弧)数:arcnum ,图的种类:kind ;(二):邻接矩阵:arcs(1顶点关系类型:adj 2相关信息:*info);(三):顶点向量(顶点名):vexs[];其优点是以二维数组表示有n 个顶点的图时,需存放n 个顶点的信息和n*n 条弧的信息存储量。

借助邻接矩阵容易判定任意两个顶点之间是否有边或弧相连,并容易求出各个顶点的度。

缺点是时间复杂度是O (n*n ),例如,构造一个具有n 个顶点和e 条边的无向网的时间复杂度为O (n*n+e*n )。

图的邻接表存储结构是图的一种链式存储结构。

对图中的每个顶点建立一个单链表,每个结点由三个域组成,邻接点域adjvex (弧尾在邻接表链表中的位序),链域nextarc (下一条弧),数据域info(权值)。

求拓扑序列排序课程设计

求拓扑序列排序课程设计

求拓扑序列排序课程设计一、教学目标本课程的教学目标是让学生掌握拓扑序列排序的基本概念、原理和应用,培养学生运用拓扑序列排序解决问题的能力。

具体包括以下三个方面的目标:1.知识目标:(1)理解拓扑序列排序的定义和性质;(2)掌握拓扑排序算法及其实现;(3)了解拓扑序列排序在实际应用中的重要性。

2.技能目标:(1)能够运用拓扑排序解决简单的问题;(2)能够运用图论知识分析和解决拓扑排序相关问题;(3)能够运用编程语言实现拓扑排序算法。

3.情感态度价值观目标:(1)培养学生对计算机科学的兴趣和热情;(2)培养学生团队合作、自主学习的能力;(3)培养学生运用所学知识解决实际问题的意识。

二、教学内容本课程的教学内容主要包括以下几个部分:1.拓扑序列排序的基本概念:图、顶点、边、度数、入度、出度等;2.拓扑排序的原理:拓扑排序的定义、拓扑排序的存在性、拓扑排序的算法;3.拓扑排序算法实现:深度优先搜索(DFS)算法、广度优先搜索(BFS)算法;4.拓扑排序的应用:任务调度、项目规划等实际问题。

三、教学方法为了达到本课程的教学目标,将采用以下几种教学方法:1.讲授法:通过讲解拓扑序列排序的基本概念、原理和应用,使学生掌握相关知识;2.讨论法:学生分组讨论拓扑排序算法实现和应用问题,培养学生的思考和表达能力;3.案例分析法:分析实际应用中的拓扑排序问题,让学生学会将理论知识应用于实际问题;4.实验法:安排拓扑排序算法的编程实验,培养学生的动手能力和实际问题解决能力。

四、教学资源为了支持本课程的教学内容和教学方法的实施,将准备以下教学资源:1.教材:《图论与算法导论》;2.参考书:《计算机网络》、《数据结构与算法》;3.多媒体资料:PPT课件、教学视频;4.实验设备:计算机、网络设备。

通过以上教学资源的使用,丰富学生的学习体验,提高学生的学习效果。

五、教学评估本课程的教学评估将采取多元化、全过程的方式进行,以全面、客观、公正地评价学生的学习成果。

数据结构之的拓扑排序算法拓扑排序算法的实现和性能分析

数据结构之的拓扑排序算法拓扑排序算法的实现和性能分析

数据结构之的拓扑排序算法拓扑排序算法的实现和性能分析数据结构之拓扑排序算法拓扑排序算法的实现和性能分析拓扑排序是一种常用的图算法,用于对有向无环图(DAG)进行排序。

拓扑排序的主要应用包括任务调度、编译顺序、依赖关系管理等方面。

本文将介绍拓扑排序算法的实现及其性能分析。

一、拓扑排序算法的实现拓扑排序算法一般采用深度优先搜索(DFS)或广度优先搜索(BFS)来实现。

下面将以DFS实现为例进行介绍。

1. 创建图数据结构在进行拓扑排序之前,首先需要创建图的数据结构。

可以使用邻接表或邻接矩阵来表示图。

以邻接表为例,可以使用一个字典来表示每个节点和其相邻节点的关系。

2. 初始化标记数组为了保证每个节点只被访问一次,需要使用一个标记数组来记录节点的访问状态。

可以使用布尔数组或整数数组来表示,将未访问的节点标记为false或0,已访问的节点标记为true或1。

3. 实现拓扑排序函数拓扑排序函数的主要功能是对图进行遍历,并将节点按照拓扑排序的顺序输出。

拓扑排序函数通常使用递归的方式实现。

4. 输出排序结果拓扑排序算法完成后,可以将排序的结果输出。

按照拓扑排序的定义,输出的结果应该是一个拓扑有序的节点列表。

二、拓扑排序算法的性能分析拓扑排序算法的性能取决于图的规模和结构。

下面将从时间复杂度和空间复杂度两个方面进行性能分析。

1. 时间复杂度分析拓扑排序算法的时间复杂度主要取决于图的节点数和边数。

在最坏情况下,每个节点都需要遍历一次,而每个节点的边数是有限的,所以拓扑排序的时间复杂度为O(V+E),其中V表示节点数,E表示边数。

2. 空间复杂度分析拓扑排序算法的空间复杂度主要取决于存储图和标记数组的空间。

在使用邻接表表示图时,需要额外的空间来存储每个节点及其相邻节点的关系。

同时,需要使用标记数组来记录节点的访问状态。

所以拓扑排序的空间复杂度为O(V+E+V),即O(V+E),其中V表示节点数,E表示边数。

三、总结拓扑排序是一种常用的图算法,可以对有向无环图进行排序。

求拓扑排序序列课程设计

求拓扑排序序列课程设计

求拓扑排序序列课程设计一、教学目标本节课的教学目标是让学生掌握拓扑排序序列的概念、性质和求解方法,能够运用拓扑排序解决实际问题。

具体分为以下三个部分:1.知识目标:学生能够理解拓扑排序的定义,了解拓扑排序的性质和应用场景,掌握拓扑排序的求解方法。

2.技能目标:学生能够运用拓扑排序解决实际问题,如任务调度、项目规划等,提高问题解决的效率。

3.情感态度价值观目标:培养学生对计算机科学和图论的兴趣,培养学生的逻辑思维和创新能力。

二、教学内容本节课的教学内容主要包括以下三个方面:1.拓扑排序的定义和性质:介绍拓扑排序的定义,解释拓扑排序的性质,如无环性、唯一性等。

2.拓扑排序的求解方法:讲解拓扑排序的求解方法,如DFS、BFS等,并通过实例进行演示。

3.拓扑排序的应用:介绍拓扑排序在实际问题中的应用,如任务调度、项目规划等,并通过实例进行讲解。

三、教学方法为了提高学生的学习兴趣和主动性,本节课将采用以下教学方法:1.讲授法:讲解拓扑排序的定义、性质和求解方法,为学生提供系统的知识结构。

2.案例分析法:通过分析实际问题,让学生了解拓扑排序的应用,提高学生的解决问题的能力。

3.实验法:让学生动手实践,求解实际问题,培养学生的实际操作能力。

四、教学资源为了支持教学内容和教学方法的实施,丰富学生的学习体验,我们将准备以下教学资源:1.教材:为学生提供系统的知识结构,方便学生课后复习。

2.多媒体资料:通过动画、图片等形式,直观地展示拓扑排序的概念和性质,提高学生的学习兴趣。

3.实验设备:为学生提供实际操作的机会,培养学生的实际操作能力。

五、教学评估本节课的评估方式包括以下几个方面:1.平时表现:通过观察学生在课堂上的参与程度、提问回答等情况,评估学生的学习态度和理解程度。

2.作业:布置相关的拓扑排序题目,评估学生对拓扑排序概念和求解方法的理解和应用能力。

3.考试:设计考试题目,全面考察学生对拓扑排序的定义、性质、求解方法和应用的掌握程度。

数据结构之拓扑排序算法详解

数据结构之拓扑排序算法详解

数据结构之拓扑排序算法详解拓扑排序算法是一种常用于有向无环图(DAG)的排序算法,它可以将图中的顶点按照一定的顺序进行排序,使得图中任意一条有向边的起点在排序结果中都排在终点的前面。

在实际应用中,拓扑排序算法常用于解决任务调度、依赖关系分析等问题。

本文将详细介绍拓扑排序算法的原理、实现方法以及应用场景。

### 一、拓扑排序算法原理拓扑排序算法的原理比较简单,主要包括以下几个步骤:1. 从DAG图中选择一个入度为0的顶点并输出。

2. 从图中删除该顶点以及以该顶点为起点的所有有向边。

3. 重复步骤1和步骤2,直到图中所有顶点都被输出。

### 二、拓扑排序算法实现下面以Python语言为例,给出拓扑排序算法的实现代码:```pythondef topological_sort(graph):in_degree = {v: 0 for v in graph}for u in graph:for v in graph[u]:in_degree[v] += 1queue = [v for v in graph if in_degree[v] == 0] result = []while queue:u = queue.pop(0)result.append(u)for v in graph[u]:in_degree[v] -= 1if in_degree[v] == 0:queue.append(v)if len(result) == len(graph):return resultelse:return []# 测试代码graph = {'A': ['B', 'C'],'B': ['D'],'C': ['D'],'D': []}print(topological_sort(graph))```### 三、拓扑排序算法应用场景拓扑排序算法在实际应用中有着广泛的应用场景,其中包括但不限于以下几个方面:1. 任务调度:在一个任务依赖关系图中,拓扑排序可以确定任务的执行顺序,保证所有任务按照依赖关系正确执行。

课程设计拓扑排序摘要

课程设计拓扑排序摘要

课程设计拓扑排序摘要一、教学目标本课程的教学目标是使学生掌握拓扑排序的基本概念和方法,能够运用拓扑排序解决实际问题。

具体分为以下三个部分:1.知识目标:学生需要理解拓扑排序的定义、特点和应用场景,掌握拓扑排序算法的实现和优化。

2.技能目标:学生能够运用拓扑排序算法解决基本的图论问题,如任务调度、课程安排等。

3.情感态度价值观目标:通过学习拓扑排序,学生能够培养逻辑思维能力、问题解决能力和创新意识,提高对计算机科学和图论的兴趣。

二、教学内容本课程的教学内容主要包括拓扑排序的定义和性质、拓扑排序算法的实现和优化、拓扑排序的应用场景。

具体安排如下:1.第一章:拓扑排序的定义和性质,介绍拓扑排序的基本概念和特点,分析拓扑排序的性质和限制。

2.第二章:拓扑排序算法的实现和优化,讲解常见的拓扑排序算法,如Kahn算法和Dijkstra算法,探讨算法的效率和优化方法。

3.第三章:拓扑排序的应用场景,介绍拓扑排序在任务调度、课程安排等实际问题中的应用,并通过案例分析让学生掌握拓扑排序的运用。

三、教学方法为了激发学生的学习兴趣和主动性,本课程将采用多种教学方法相结合的方式进行教学。

具体包括:1.讲授法:通过讲解拓扑排序的基本概念、算法和应用,使学生掌握拓扑排序的理论基础。

2.案例分析法:通过分析实际问题案例,让学生了解拓扑排序在实际中的应用和解决问题的方式。

3.实验法:安排课后实验,让学生动手实现拓扑排序算法,培养学生的实际操作能力和问题解决能力。

四、教学资源为了支持教学内容和教学方法的实施,丰富学生的学习体验,我们将准备以下教学资源:1.教材:选择一本关于图论和拓扑排序的经典教材,作为学生学习的基础资料。

2.参考书:提供一些相关领域的参考书籍,供学生深入学习和拓展知识。

3.多媒体资料:制作PPT、教学视频等多媒体资料,帮助学生更好地理解和掌握拓扑排序的知识。

4.实验设备:准备计算机实验室,让学生能够进行课后实验和实践操作。

拓扑排序课程设计报告

拓扑排序课程设计报告

沈阳航空航天大学课程设计报告课程设计名称:数据结构课程设计课程设计题目:拓扑排序算法院(系):计算机学院专业:计算机科学与技术(嵌入式系统方向)班级:14010105班学号:2011040101221姓名:王芃然指导教师:丁一军目录1 课程设计介绍 (1)1.1课程设计内容 (1)1.2课程设计要求 (1)2 课程设计原理 (2)2.1课设题目粗略分析 (2)2.2原理图介绍 (2)2.2.1 功能模块图 (2)2.2.2 流程图分析 (3)3 数据结构分析 (7)3.1存储结构 (7)3.2算法描述 (7)4 调试与分析 (12)4.1调试过程 (12)4.2程序执行过程 (12)参考文献 (14)附录(关键部分程序清单) (15)1 课程设计介绍1.1 课程设计内容由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。

若在图一的有向图上人为的加一个表示V2<=V3的弧(“<=”表示V2领先于V3)则图一表示的亦为全序且这个全序称为拓扑有序,而由偏序定义得到拓扑有序的操作便是拓扑排序。

在AOV网中为了更好地完成工程,必须满足活动之间先后关系,需要将各活动排一个先后次序即为拓扑排序。

编写算法建立有向无环图,主要功能如下:1.能够求解该有向无环图的拓扑排序并输出出来;2.拓扑排序应该能处理出现环的情况;3.顶点信息要有几种情况可以选择。

1.2 课程设计要求1.输出拓扑排序数据外,还要输出邻接表数据;2.参考相应的资料,独立完成课程设计任务;3.交规范课程设计报告和软件代码。

2 课程设计原理2.1 课设题目粗略分析本课设题目要求编写算法能够建立有向无环图,有向无环图,顾名思义,即一个无环的有向图,是一类较有向图更一般的特殊有向图。

其功能要求及个人在写程序时对该功能的实现作如下分析:1. 将图以合适的方式存储起来。

图有多种存储方式,其中最常用的存储方式有图的邻接矩阵和邻接表。

拓扑排序(算法与数据结构课程设计)

拓扑排序(算法与数据结构课程设计)

拓扑排序一、问题描述在AOV网中为了更好地完成工程,必须满足活动之间先后关系,需要将各活动排一个先后次序即为拓扑排序。

拓扑排序可以应用于教学计划的安排,根据课程之间的依赖关系,制定课程安排计划。

按照用户输入的课程数,课程间的先后关系数目以及课程间两两间的先后关系,程序执行后会给出符合拓扑排序的课程安排计划。

二、基本要求1、选择合适的存储结构,建立有向无环图,并输出该图;2、实现拓扑排序算法;3、运用拓扑排序实现对教学计划安排的检验。

三、算法思想1、采用邻接表存储结构实现有向图;有向图需通过顶点数、弧数、顶点以及弧等信息建立。

2、拓扑排序算法void TopologicalSort(ALGraph G) 中,先输出入度为零的顶点,而后输出新的入度为零的顶点,此操作可利用栈或队列实现。

考虑到教学计划安排的实际情况,一般先学基础课(入度为零),再学专业课(入度不为零),与队列先进先出的特点相符,故采用队列实现。

3、拓扑排序算法void TopologicalSort(ALGraph G),大体思想为:1)遍历有向图各顶点的入度,将所有入度为零的顶点入队列;2)队列非空时,输出一个顶点,并对输出的顶点数计数;3)该顶点的所有邻接点入度减一,若减一后入度为零则入队列;4)重复2)、3),直到队列为空,若输出的顶点数与图的顶点数相等则该图可拓扑排序,否则图中有环。

4、要对教学计划安排进行检验,因此编写了检测用户输入的课程序列是否是拓扑序列的算法void TopSortCheck(ALGraph G),大体思想为:1)用户输入待检测的课程序列,将其存入数组;2)检查课程序列下一个元素是否是图中的顶点(课程),是则执行3),否则输出“课程XX 不存在”并跳出;3)判断该顶点的入度是否为零,是则执行4),否则输出“入度不为零”并跳出;4)该顶点的所有邻接点入度减一;5)重复2)、3)、4)直到课程序列中所有元素均被遍历,则该序列是拓扑序列,否则不是拓扑序列。

数据结构课程设计——拓扑排序

数据结构课程设计——拓扑排序

数据结构课程设计——拓扑排序数据结构课程设计——拓扑排序1、引言拓扑排序是一种对有向无环图(DAG)进行排序的算法,它可以用来确定一组任务的执行顺序,或者检测图中是否存在环。

本文档旨在介绍拓扑排序的基本概念、算法原理以及实现过程。

2、基本概念2.1 有向图有向图是由一组顶点和一组有向边组成的图,每条边都有一个方向。

在有向图中,顶点表示实体,有向边表示实体之间的关系。

2.2 DAGDAG(Directed Acyclic Graph)是一种无环有向图,即不存在从某个顶点出发经过若干个有向边后能够回到该顶点的路径。

3、算法原理拓扑排序算法基于有向无环图的性质,通过选择没有前驱的顶点,将该顶点及其对应的边从图中删除,并将该顶点加入到排序结果中。

重复这个过程,直到所有顶点都被加入到排序结果中,或者图中存在环。

4、算法步骤4.1 初始化创建一个数组inDegree,并将所有顶点的入度初始化为0。

创建一个队列queue,并将所有入度为0的顶点入队。

4.2 执行拓扑排序4.2.1 从队列中取出一个顶点vertex。

4.2.2 将vertex加入到排序结果中。

4.2.3 遍历vertex的所有邻接顶点neighbor。

\t- 将neighbor的入度减1:\t- 如果neighbor的入度为0,将其入队。

4.2.4 重复步骤4.2.1至4.2.3,直到队列为空。

5、实现过程5.1 定义数据结构我们可以使用一个邻接表来表示有向图,其中每个顶点对应一个链表,链表中存储了该顶点指向的邻接顶点。

5.2 实现拓扑排序算法```function topologicalSort(graph):inDegree = new Array(graph:numOfVertices):fill(0) queue = new Queue()result = []// 初始化入度数组for each vertex in graph:vertices:for each neighbor in vertex:neighbors:inDegree[neighbor]++// 将入度为0的顶点入队for each vertex in graph:vertices:if inDegree[vertex] == 0:queue:enqueue(vertex)// 执行拓扑排序while queue is not empty:vertex = queue:dequeue()result:push(vertex)for each neighbor in vertex:neighbors:inDegree[neighbor]--if inDegree[neighbor] == 0: queue:enqueue(neighbor) return result```6、附件本文档不涉及任何附件。

拓扑排序c语言课程设计

拓扑排序c语言课程设计

拓扑排序c语言课程设计一、课程目标知识目标:1. 学生理解拓扑排序的概念,掌握其在图论中的应用。

2. 学生掌握使用C语言实现拓扑排序算法的基本步骤和关键代码。

3. 学生能够解释拓扑排序结果的意义,并分析其在实际问题中的应用。

技能目标:1. 学生能够运用C语言编写实现拓扑排序的程序,并对给定的有向无环图进行排序。

2. 学生通过实际操作,培养解决复杂问题的编程能力和逻辑思维能力。

3. 学生学会使用调试工具检测并修正程序中的错误,提高程序调试能力。

情感态度价值观目标:1. 学生在探究拓扑排序的过程中,培养对数据结构和算法的热爱,激发对计算机科学的兴趣。

2. 学生在合作交流中,培养团队协作精神和分享意识,提高沟通能力。

3. 学生通过解决实际问题,体会编程的魅力,增强自信心和自主学习能力。

课程性质:本课程为计算机科学与技术学科的课程设计,旨在让学生掌握拓扑排序的原理和C语言实现方法。

学生特点:学生已具备C语言基础,具有一定的编程能力和逻辑思维能力,对图论相关概念有一定了解。

教学要求:教师需引导学生通过实例分析,动手实践,掌握拓扑排序的编程方法,并在实际应用中提高解决问题的能力。

教学过程中注重培养学生的团队合作意识和自主学习能力。

通过本课程的学习,使学生在知识、技能和情感态度价值观方面取得具体的学习成果。

二、教学内容1. 图的基本概念复习:回顾图的定义、有向图和无向图、顶点和边、邻接矩阵和邻接表等基础知识。

教材章节:第二章 图的基本概念2. 拓扑排序的概念与性质:介绍拓扑排序的定义、特点和应用场景,讨论拓扑排序与有向无环图的关系。

教材章节:第五章 图的算法应用3. 拓扑排序算法原理:讲解拓扑排序的算法思想、关键步骤以及时间复杂度分析。

教材章节:第五章 图的算法应用4. C语言实现拓扑排序:详细讲解如何使用C语言实现拓扑排序,包括数据结构设计、函数定义和逻辑实现。

教材章节:实验指导书第四章 图的算法实现5. 拓扑排序实例分析:通过具体实例,分析拓扑排序在实际问题中的应用,如任务调度、项目规划等。

拓扑排序课程设计报告

拓扑排序课程设计报告

拓扑排序课程设计报告拓扑排序⼀问题描述本次课程设计题⽬是:编写函数实现图的拓扑排序⼆概要设计1.算法中⽤到的所有各种数据类型的定义在该程序中⽤邻接表作为图的存储结构。

⾸先,定义表结点和头结点的结构类型,然后定义图的结构类型。

创建图⽤邻接表存储的函数,其中根据要求输⼊图的顶点和边数,并根据要求设定每条边的起始位置,构建邻接表依次将顶点插⼊到邻接表中。

拓扑排序的函数在该函数中⾸先要对各顶点求⼊度,其中要⽤到求⼊度的函数,为了避免重复检测⼊度为零的顶点,设置⼀个辅助栈,因此要定义顺序栈类型,以及栈的函数:⼊栈,出栈,判断栈是否为空。

2.各程序模块之间的层次调⽤关系第⼀部分,void CreatGraph(ALGraph *G)函数构建图,⽤邻接表存储。

这个函数没有调⽤函数。

第⼆部分,void TopologicalSort(ALGraph *G)输出拓扑排序函数,这个函数⾸先调⽤FindInDegree(G,indegree)对各顶点求⼊度indegree[0……vernum-1];然后设置了⼀个辅助栈,调⽤InitStack(&S)初始化栈,在调⽤Push(&S,i)⼊度为0者进栈,while(!StackEmpty(&S))栈不为空时,调⽤Pop(&sS,&n)输出栈中顶点并将以该顶点为起点的边删除,⼊度indegree[k]--,当输出某⼀⼊度为0的顶点时,便将它从栈中删除。

第三部分,主函数,先后调⽤void CreatGraph(ALGraph *G)函数构建图、void TopologicalSort(ALGraph *G)函数输出拓扑排序实现整个程序。

3.设计的主程序流程三详细设计1.实现概要设计中定义的所有数据类型#include#include#include#define MAX_VEXTEX_NUM 20 //*定义点最⼤的数值为顶30*// #define M 20#define STACK_INIT_SIZE 100 //*定义点最⼤的数值为顶30*//#define STACKINCREMENT 10 //*定义栈的增量为10*//#define OK 1#define ERROR 0typedef char ElemType; //*定义栈顶元素类型*//typedef struct ArcNode{int adjvex; //该弧所指向的顶点的位置//struct ArcNode *nextarc; //指向下⼀条弧的指针//}ArcNode; //*表结点*//typedef struct VNode{char data; //顶点信息ArcNode *firstarc; //指向第⼀条依附该顶点的弧的指针// }VNode,AdjList[MAX_VEXTEX_NUM];typedef struct{AdjList vertices;int vexnum, arcnum; //图的当前顶点数和弧数//}ALGraph;typedef struct //构建栈//{ElemType *base;//*在栈构造之前的指针*//ElemType *top;//*栈顶指针*//int stacksize;//*定义所分配的存储空间*//}SqStack;//*顺序栈*//2.算法和各模块的代码程序中各函数算法思想如下:○1void InitStack(SqStack *S)初始化栈将栈的空间设为STACK-INIT-SIZE。

数据结构拓扑排序课程设计

数据结构拓扑排序课程设计

数据结构拓扑排序课程设计正文:1:引言1.1 研究背景在计算机科学领域中,数据结构是描述和组织数据的方式。

而拓扑排序是一种常用的数据结构算法,用于对有向图中的节点进行排序。

本文将介绍拓扑排序的算法原理以及如何实现一个拓扑排序算法。

1.2 研究目的本文的目的是设计一个高效的拓扑排序算法,用于解决日常生活中一些实际问题。

2:拓扑排序原理2.1 有向图有向图是由节点和边组成的图,边表示节点之间的关系,并且有方向性。

在有向图中,每个节点都有一个入度和一个出度。

2.2 拓扑排序定义拓扑排序是一种将有向无环图(DAG)中的节点线性排序的算法。

排序的结果满足:若节点 A 在排序结果中位于节点 B 之前,则在图中不存在一条从节点 B 指向节点 A 的路径。

2.3 拓扑排序算法步骤:1) 初始化一个队列,将所有入度为 0 的节点入队。

2) 当队列不为空时,执行以下操作:a) 取出队首节点,并将其加入排序结果中。

b) 将该节点的所有邻居节点的入度减 1:c) 若邻居节点的入度为 0,则将其入队。

3) 若排序结果中的节点数等于图中的节点数,则排序成功;否则,图中存在环,排序失败。

3:拓扑排序的实现3.1 数据结构设计为了实现拓扑排序算法,我们需要定义两个数据结构:节点和图。

节点类包含以下属性:- 节点标识符- 节点的入度- 节点的邻居列表图类包含以下方法:- 添加节点- 添加边- 拓扑排序3.2 代码实现示例代码如下:```pythonclass Node:def __init__(self, id): self:id = idself:indegree = 0 self:neighbors = [] class Graph:def __init__(self):self:nodes = []def addNode(self, id):self:nodes:append(Node(id)) def addEdge(self, id1, id2):node1 = self:getNode(id1)node2 = self:getNode(id2)node2:indegree += 1node1:neighbors:append(node2) def getNode(self, id):for node in self:nodes:if node:id == id:return nodereturn Nonedef topologicalSort(self):queue = []result = []for node in self:nodes:if node:indegree == 0:queue:append(node)while queue:currNode = queue:pop(0)result:append(currNode)for neighbor in currNode:neighbors: neighbor:indegree -= 1if neighbor:indegree == 0:queue:append(neighbor)if len(result) == len(self:nodes):return resultelse:return None```4:实例应用4.1 任务调度拓扑排序可以用于任务调度,其中每个节点表示一个任务,边表示任务之间的依赖关系。

课程设计实现拓扑排序算法

课程设计实现拓扑排序算法

课程设计实现拓扑排序算法一、课程目标知识目标:1. 学生能理解拓扑排序的概念,掌握拓扑排序算法的基本原理和应用场景。

2. 学生能描述有向无环图(DAG)的特点,并识别出给定图中的关键路径。

3. 学生能运用所学知识,对实际问题进行拓扑排序,解决项目管理、任务调度等实际问题。

技能目标:1. 学生能通过分析问题,构建出相应的有向无环图,并进行拓扑排序。

2. 学生能运用编程语言实现拓扑排序算法,解决具体问题。

3. 学生能通过实例分析,培养解决问题的能力和逻辑思维能力。

情感态度价值观目标:1. 学生通过学习拓扑排序算法,体验算法在实际问题中的应用价值,增强学习兴趣和动力。

2. 学生在团队协作中,培养沟通能力、合作精神和集体荣誉感。

3. 学生在学习过程中,树立正确的价值观,认识到科学技术的进步对社会发展的重要意义。

课程性质:本课程属于数据结构与算法领域,旨在帮助学生掌握拓扑排序这一重要算法,提高解决实际问题的能力。

学生特点:学生具备一定的编程基础和图论知识,具有一定的抽象思维和逻辑分析能力。

教学要求:结合学生特点和课程性质,教师应注重启发式教学,引导学生通过实例分析、编程实践等方式,掌握拓扑排序算法,提高实际应用能力。

同时,关注学生的情感态度价值观培养,激发学生的学习兴趣和动力。

在教学过程中,将课程目标分解为具体的学习成果,以便进行有效的教学设计和评估。

二、教学内容1. 图的基本概念复习:介绍图的相关术语,如顶点、边、邻接点、度等,回顾有向图和无向图的特点。

2. 有向无环图(DAG)的判定:讲解DAG的定义,引导学生识别DAG及其在实际问题中的应用。

3. 拓扑排序的概念与算法:介绍拓扑排序的定义,阐述拓扑排序的算法步骤,分析拓扑排序与DAG的关系。

4. 拓扑排序算法的实现:结合教材,教授编程语言实现拓扑排序算法,包括邻接表和邻接矩阵两种表示方法。

5. 拓扑排序的应用案例:分析拓扑排序在项目管理、任务调度等领域的应用,结合实际案例进行讲解。

拓扑排序课程设计报告

拓扑排序课程设计报告

拓扑排序课程设计报告拓扑排序一目的通过课程设计,加深对《程序设计语言》和《软件技术基础》课程所学知识的理解,熟练掌握和巩固C语言的基本知识和语法规范,包括:数据类型(整形、实型、字符型、指针、数组、结构等);运算类型(算术运算、逻辑运算、自增自减运算、赋值运算等);程序结构(顺序结构、判断选择结构、循环结构);库函数应用等;复杂任务功能分解方法(自顶向下逐步求精、模块化设计、信息隐藏等),熟练掌握和巩固三种基本图形结构的逻辑结构、存储结构以及相关运算和应用。

学会编制结构清晰、风格良好、数据结构适当的C语言程序,从而具备利用计算机编程分析解决综合性实际问题的初步能力。

二需求分析题目描述:判断一个有向图是否存在回路,并求出有向无环图的拓扑序列。

1、输入数据在工程文件中保存输入2个字符串数TXT文件。

第一个为图按次序排列的所有边的前顶点,第二个为相对应的第二个顶点。

2、输出数据图的定点数,边数,每个顶点的信息及入度,构造的邻接表,图的拓扑排序。

3、程序功能已将AOV网存入文件中,运行时从文件读取数据;对一个AOV网,应判断其是否是有向无环图,若是则输出其任意一个拓扑排序序列,不是则进行相关的说明;构造图的邻接表;输出所有顶点的入度。

三概要设计1、全局变量或类型说明//********结构体定义***********//typedef struct A_Node //定义表结点结构{int adjvex; //与vi相邻接的顶点编号struct A_Node *nextarc; //指向下一条弧(边)的指针} A_Node;typedef struct V_Node //定义表头结点结构{int data;A_Node *firstarc; //指向第一条弧(边)的指针} V_Node, AdjList[MAX_NUM];typedef struct //定义邻接表结构{AdjList vertices; //表头结点数组int vex_num, arc_num; //顶点和弧(边)的个数} ALGraph;typedef struct //构件栈{Elem_T *base;Elem_T *top;int stacksize;} Sq;2、模块功能1)void Init(Sq *S);功能:初始化栈。

数据结构课程设计拓扑排序(顺序,逆序输出)

数据结构课程设计拓扑排序(顺序,逆序输出)

目录一.需求分析说明 (1)二.概要设计说明 (1)三.详细设计说明 (2)四.调试分析 (6)五.用户使用说明 (6)六.课程设计总结 (7)七.测试结果 (8)八.参考书目 (9)九. 附录 (10)一、需求分析说明为了更好的学习数据结构,深刻理解数据结构在解决实际问题中的应用,体会其重要性,熟练掌握线性表、栈和队列、串、数组、树、图等常用的数据结构,熟悉各自的特点和应用场合。

同时锻炼自己独立分析理解问题的能力,学会根据不同的问题选择合适的数据结构,然后结合适当的算法解决问题。

锻炼自己的设计和编写程序的技巧,进一步调试和测试自己所写的程序,使其功能更加完善,养成较好的编写程序习惯。

提高综合运用所学的理论知识和方法独立分析和解决问题的能力,训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风。

本课程设计的目的就是要达到理论与实际应用相结合,使同学们能够根据数据对象的特性,学会数据组织的方法,能把现实世界中的实际问题在计算机内部表示出来,并培养基本的、良好的程序设计技能。

设计的基本要求:1)选择邻接表作为有向图的存储结构模拟整个过程,并输出拓扑排序的顶点序列。

2)给出逆向的拓扑有序序列。

二、概要设计说明2.1 算法思想采用邻接表存储结构实现有向图;有向图需通过顶点数、边数、顶点以及边等信息建立。

拓扑排序算法大体思想为:1)遍历有向图各顶点的入度,将所有入度为零的顶点入栈;2)栈非空时,输出一个顶点,并对输出的顶点数计数;3)该顶点的所有邻接点入度减一,若减一后入度为零则入栈;4)重复2)、3),直到栈为空,若输出的顶点数与图的顶点数相等则该图可拓扑排序,否则图中有环;5)重复2)、3)、4)直到序列中所有元素均被遍历,则该序列是拓扑序列,否则不是拓扑序列。

2.2 系统功能模块结构图本程序包括拓扑排序模块和拓扑排序核心算法模块。

3.13.2 数据结构1)图typedef struct stack{int *base;int *top;int stacksize;}sqstack;//栈的结构,存储图的顶点序号typedef struct lnode{int adjvex;struct lnode *next;}ArcNode;//弧结点typedef struct node2{int data;ArcNode *fristarc;}VNode,AdjList[MAX];//顶点数组,fristarc指向与顶点邻接的第一条弧typedef struct{AdjList vertices;int vexnum,arcnum;}Graph;//邻接表图void CreatGraph(Graph &G,int *indegree){cout<<"请输入图的顶点数和边数(且顶点数不能超过"<<MAX<<"个)"<<endl;cin>>G.vexnum>>G.arcnum;cout<<"请输入各个顶点值(整形):"<<endl;for(int i=0;i<G.vexnum;i++)//输入图的顶点{cin>>G.vertices[i].data;G.vertices[i].fristarc=NULL;indegree[i]=0;}for(i=0;i<G.arcnum;i++)//输入图的边{int m,n;ArcNode *p;cout<<"请输入第"<<i+1<<"条边的头结点和尾结点:"<<endl;cin>>m>>n;p=new ArcNode;if(!p)exit(0);indegree[n-1]++;//求每个顶点的入度值p->adjvex=n-1;p->next=G.vertices[m-1].fristarc;G.vertices[m-1].fristarc=p;}}2)栈void Initstack(sqstack &s){s.base=new int;if(!s.base)exit(0);s.top=s.base;s.stacksize= STACK_INIT_SIZE;}void Push(sqstack &s,int &e){*s.top++=e;}int Emptystack(sqstack &s){if(s.base==s.top)return 1;elsereturn 0;}int Pop(sqstack &s,int &e){if(s.base==s.top)return ERROR;e=*--s.top;}3.3 具体实现函数1)程序所需头文件及全局变量#include<iostream>using namespace std;const int MAX=30;const int STACK_INIT_SIZE=100;const int ERROR=0;2)栈的操作①void Initstack(sqstack &s)功能:初始化栈,构造一个空栈S参数:S待初始化的栈②i nt Emptystack(sqstack &s)功能:判断栈是否为空参数:S 待判断的栈返回值:栈为空返回1,栈非空返回0③void Push(sqstack &s,int &e)功能:元素入栈参数:S 待操作的栈:插入元素e为新的栈顶元素④int Pop(sqstack &s,int &e)功能:元素出栈参数:S 待操作的栈:若栈不空,则删除S的栈顶元素,用e返回其值,并返回1,否则返回03)图的建立void CreatGraph(Graph &G,int *indegree)功能:建立有向图,并记录每个节点的入度值参数:G 待建立的图:用indegree记录节点的入度值4)拓扑排序int Toposort(Graph &G,int *indegree)功能:对有向图进行拓扑排序,对排序结果进行顺序和逆序输出参数:G 待排序的图:indegree是节点的入度值5)主函数int main()对各个函数进行调用,实现程序功能判断是否排序成功四、调试分析4.1 数据测试1、对存在环的有向图进行测试有向图的顶点数和边数:4 4各顶点的值:1 2 3 4第一条边1 2第二条边的头结点和尾结点:2 3第三条边的头结点和尾结点:3 4第四条边的头结点和尾结点:4 1测试结果:拓扑排序不成功。

数据结构拓扑排序课程设计

数据结构拓扑排序课程设计

课题二拓扑排序2.1 问题的提出2.1 问题的提出任务:编写函数实现图的拓扑排序。

程序所实现的功能:建立对应的邻接表,对该图进行拓扑排序,并显示排序结果。

输入:顶点数, 边数及各顶点信息(数据格式为整形)输出:拓扑排序结果。

2. 2 概要设计1.拓扑排序是指由某个集合上的一个偏序得到该集合上的一个全序。

更直观地讲,一个偏序是自反的、反对称的,用图表示时每个点都有环且只有单向边。

拓扑排序的任务是在这个偏序上得到一个全序,即得到一个完成整个项目的各步骤的序列。

2.解决拓扑排序的方法如下:(1)在有向图中选一个没有前驱的顶点且输出之。

(2)从图中删除该顶点和所有以它为尾的弧。

重复上述两步,直至全部顶点均已输出,或者当前图中不存在无前驱的顶点为止。

后一种情况则说明有向图中存在环。

具体的算法实现参照源程序。

3.构造邻接表图:typedef struct{AdjList vertices;int vexnum,arcnum;}Graph;//邻接表图4.为了避免重复检测入度为零的顶点,源程序中设了一个栈,暂存所有入度为零的顶点:typedef struct stack{int *base;int *top;int stacksize;}sqstack;//栈的结构,存储图的顶点序号2.3 流程图2.根据算法思想,画流程图如下:2.4 源代码//采用尾插法创的邻接图#include<iostream>using namespace std;const int MAX=20;const int STACK_INIT_SIZE=100;const int ERROR=0;typedef struct stack{int *base;int *top;int stacksize;}sqstack;//栈的结构,存储图的顶点序号typedef struct lnode{int adjvex;struct lnode *next;}ArcNode;//弧结点typedef struct node2{char data;ArcNode *fristarc;}VNode,AdjList[MAX];//顶点数组,fristarc指向与顶点邻接的第一条弧typedef struct{AdjList vertices;int vexnum,arcnum;}Graph;//邻接表图void Initstack(sqstack &s){s.base=new int;if(!s.base)exit(0);s.top=s.base;s.stacksize= STACK_INIT_SIZE;}void Push(sqstack &s,int &e){*s.top++=e;}int Emptystack(sqstack &s){if(s.base==s.top)return 1;elsereturn 0;}int Pop(sqstack &s,int &e){if(s.base==s.top)return ERROR;e=*--s.top;}void CreatGraph(Graph &G,int *indegree){cout<<"请输入图的顶点数和弧数(且顶点数不能超过"<<MAX<<")"<<endl; cin>>G.vexnum>>G.arcnum;cout<<"请输入顶点值:"<<endl;for(int i=0;i<G.vexnum;i++)//输入图的顶点{cin>>G.vertices[i].data;G.vertices[i].fristarc=NULL;indegree[i]=0;}for(i=0;i<G.arcnum;i++)//输入图的弧{int m,n;ArcNode *p;cout<<"请输入第"<<i+1<<"条弧的弧尾和弧头:"<<endl;cin>>m>>n;p=new ArcNode;if(!p)exit(0);indegree[n-1]++;//求每个顶点的入度值p->adjvex=n-1;p->next=G.vertices[m-1].fristarc;G.vertices[m-1].fristarc=p;}}int Toposort(Graph &G,int *indegree){sqstack S;Initstack(S);for(int i=0;i<G.vexnum;i++)//0入度顶点入栈{if(!indegree[i])Push(S,i);}int count=0;while(!Emptystack(S)){Pop(S,i);cout<<G.vertices[i].data<<" ";count++;//记录输出的顶点数for(ArcNode *p=G.vertices[i].fristarc;p;p=p->next)//把与顶点{ //相邻接的顶点的入度int k=p->adjvex;if(!(--indegree[k]))Push(S,k);}}if(count<G.vexnum)return 0;elsereturn 1;}int main(){Graph G;int *indegree;indegree=new int;CreatGraph(G,indegree);if(!Toposort(G,indegree)){cout<<endl;cout<<"拓扑排序不成功!"<<endl;}else{cout<<endl;cout<<"拓扑排序成功!"<<endl;}return 0;}2.5 结果与分析2.4 测试及性能分析1.它的时间复杂度是O(G.vexnum+G.arcnum)。

数据结构课程设计——拓扑排序

数据结构课程设计——拓扑排序

. . .. . .课程设计任务书学生:专业班级:指导教师:工作单位:计算机科学系题目: 拓扑排序初始条件:(1)采用邻接表作为有向图的存储结构;(2)给出所有可能的拓扑序列。

(3)测试用例见严蔚敏《数据结构习题集(C语言版)》p48题7.9图要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)课程设计报告按学校规定格式用A4纸打印(书写),并应包含如下容:1. 问题描述简述题目要解决的问题是什么。

2. 设计存储结构设计、主要算法设计(用类C/C++语言或用框图描述)、测试用例设计;3. 调试报告调试过程中遇到的问题是如何解决的;对设计和编码的讨论和分析。

4. 经验和体会(包括对算法改进的设想)5. 附源程序清单和运行结果。

源程序要加注释。

如果题目规定了测试数据,则运行结果要包含这些测试数据和运行输出。

说明:1. 设计报告、程序不得相互抄袭和拷贝;若有雷同,则所有雷同者成绩均为0分。

2. 凡拷贝往年任务书或课程设计充数者,成绩一律无效,以0分记。

时间安排:1.第17周完成,验收时间由指导教师指定2.验收地点:实验中心3.验收容:可执行程序与源代码、课程设计报告书。

指导教师签名:2013年6月14日系主任(或责任教师)签名:年月日拓扑排序目录1问题描述2具体设计2.1存储结构设计2.2主要算法设计2.2.1拓扑排序的算法总体设计2.2.2将有向图表示为邻接表2.2.3拓扑排序函数的设计2.2.4顺序表的运算设计2.3测试用例设计3调试报告3.1设计和编码的分析3.2调试过程问题及解决4经验与体会5用户使用说明6参考文献7附录源代码与运行结果1问题描述题目:拓扑排序如果用有向图表示一个工程,在这种有向图中,用顶点表示活动,用有向边<vi,vj>表示活动vi必须先于活动vj进行,这种有向图叫做顶点表示活动的网络,记作AOV 网络。

对一个有向无环图G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得AOV网络中的所有应存在前驱和后继的关系都能得到满足,这种构造AOV网络全部顶点的拓扑有序序列的运算叫做拓扑排序。

吉林大学数据结构-拓扑排序

吉林大学数据结构-拓扑排序
环图,故访问过程中,经历的顶点不能再次
出现;又G的顶点个数有限,故该过程一定能
够终止,且终止的顶点的入度为零。
证毕。▐
• 需要注意的是,并非所有AOV网的顶点都可排成
拓扑序列。对于存在回路的网,就无法找到其顶
点的拓扑排序。
• 如下图所示的AOV网,它的拓扑序列应该满足:
_x001A__x001B_0_x001B_在
_x001A__x001B_1_x001B_之前,
_x001A__x001B_1_x001B_在
_x001A__x001B_2_x001B_之前,
_x001A__x001B_2_x001B_在
_x001A__x001B_0_x001B_之前,显然不存在这样
的线性序列。
• 对于任何无回路的AOV网, 其顶点均可排成
IF count[k] = 0 THEN
(count[k] top.
top k.)
p link (p).
)
)▐
• 定理5.2 设G=(V, E)是非循环图, V(G)={1,
2 ,…, n}, e=|E(G)|. 则算法TopoOrder是正确
的且算法的时间复杂性为(+) .
拓扑排序
1
5
3
1
2
4
7
6
顶点表示活动(或任务), 有向边表示活动(或任务)
之间的先后关系, 称这样的有向图为AOV网(Activity On
Vertex Network)。
• 所谓拓扑序列,就是把AOV网中的所有顶点
排成一个线性序列,该序列满足如下条件:
若AOV网中存在边<Vi, Vj> ,则在该序列中,
拓扑排序算法,事先需做好两项准备工作:
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

拓扑排序一、问题描述在AOV网中为了更好地完成工程,必须满足活动之间先后关系,需要将各活动排一个先后次序即为拓扑排序。

拓扑排序可以应用于教学计划的安排,根据课程之间的依赖关系,制定课程安排计划。

按照用户输入的课程数,课程间的先后关系数目以及课程间两两间的先后关系,程序执行后会给出符合拓扑排序的课程安排计划。

二、基本要求1、选择合适的存储结构,建立有向无环图,并输出该图;2、实现拓扑排序算法;3、运用拓扑排序实现对教学计划安排的检验。

三、算法思想1、采用邻接表存储结构实现有向图;有向图需通过顶点数、弧数、顶点以及弧等信息建立。

2、拓扑排序算法void TopologicalSort(ALGraph G) 中,先输出入度为零的顶点,而后输出新的入度为零的顶点,此操作可利用栈或队列实现。

考虑到教学计划安排的实际情况,一般先学基础课(入度为零),再学专业课(入度不为零),与队列先进先出的特点相符,故采用队列实现。

3、拓扑排序算法void TopologicalSort(ALGraph G),大体思想为:1)遍历有向图各顶点的入度,将所有入度为零的顶点入队列;2)队列非空时,输出一个顶点,并对输出的顶点数计数;3)该顶点的所有邻接点入度减一,若减一后入度为零则入队列;4)重复2)、3),直到队列为空,若输出的顶点数与图的顶点数相等则该图可拓扑排序,否则图中有环。

4、要对教学计划安排进行检验,因此编写了检测用户输入的课程序列是否是拓扑序列的算法void TopSortCheck(ALGraph G),大体思想为:1)用户输入待检测的课程序列,将其存入数组;2)检查课程序列下一个元素是否是图中的顶点(课程),是则执行3),否则输出“课程XX不存在”并跳出;3)判断该顶点的入度是否为零,是则执行4),否则输出“入度不为零”并跳出;4)该顶点的所有邻接点入度减一;5)重复2)、3)、4)直到课程序列中所有元素均被遍历,则该序列是拓扑序列,否则不是拓扑序列。

四、数据结构1、链式队列的存储类型为:typedef int ElemType;typedef struct QNode{ ElemType data;struct QNode *next;} QNode,*QueuePtr;typedef struct{ QueuePtr front;QueuePtr rear;} LinkQueue;2、图的类型(邻接表存储结构)为:typedef char VertexType[20];//顶点信息(名称)typedef struct ArcNode//链表结点{ int vexpos;//该弧所指向的顶点在数组中的位置struct ArcNode *next;//指向当前起点的下一条弧的指针} ArcNode;typedef struct VNode//头结点{ VertexType name;//顶点信息(名称)int indegree;//顶点入度ArcNode *firstarc;//指向当前顶点的第一条弧的指针} VNode,AdjList[MAX_VERTEX_NUM];typedef struct{ AdjList vexhead;//邻接表头结点数组int vexnum,arcnum;//图的顶点数和弧数} ALGraph;五、模块划分1、链式队列操作1) void InitQueue(LinkQueue *Q)功能:初始化链式队列参数:*Q 待初始化的队列2) int QueueEmpty(LinkQueue Q)功能:判断空队列参数:Q 待判断的队列返回值:队列为空返回 1;队列非空返回 03) void EnQueue(LinkQueue *Q, ElemType e)功能:元素入队列参数:*Q 待操作的队列;e 要入队列的元素4) void DeQueue(LinkQueue *Q, ElemType *e)功能:元素出队列参数:*Q 待操作的队列;*e 记录出队列元素的变量2、有向图(DAG)邻接表存储结构(ALG)的操作1) int LocateVex(ALGraph G,VertexType v)功能:顶点在头结点数组中的定位参数:G 待操作的图;v 要在图中定位的顶点返回值:顶点存在则返回在头结点数组中的下标;否则返回图的顶点数2) int CreateGraph(ALGraph *G)功能:建立图函数内包含了由用户输入顶点数、弧数、顶点以及弧的操作参数:*G 待操作的图返回值:图建立成功返回1;图建立失败返回0错误判断:包含顶点数、弧数是否正确的判断;包含用户输入的弧的顶点是否存在的判断3) void PrintGraph(ALGraph G)功能:输出有向图参数:G 待输出的图4) int CreateGraph2(ALGraph *G)功能:建立预置课程图(输出函数内预置课程信息,并自动建立有向图)参数:*G 待操作的图返回值:图建立成功返回1;图建立失败返回0错误判断:包含顶点数、弧数是否正确的判断包含弧的顶点是否存在的判断5) void PrintGraph2(ALGraph G)功能:输出预置课程图参数:G 待输出的图3、拓扑排序及拓扑检测算法1) void TopologicalSort(ALGraph G)功能:实现拓扑排序参数:G 待进行拓扑排序的图错误判断:包含有向图是否有环的判断2) void TopSortCheck(ALGraph G)功能:运用拓扑排序的思想检测教学计划函数内包含了由用户输入待检测的课程序列的操作参数:G 待操作的图错误判断:包含用户输入的课程是否存在的判断包含不是拓扑序列的原因(该课程有多少个先决课程未学)4、主函数void main()功能:主函数利用while语句和switch语句实现菜单化调用函数六、源程序#include "stdlib.h"#include "stdio.h"#include "string.h"/*******************************************//* 以下为链式队列操作 *//*******************************************//* 定义链式队列类型 */typedef int ElemType;typedef struct QNode{ ElemType data;struct QNode *next;} QNode,*QueuePtr;typedef struct{ QueuePtr front;QueuePtr rear;} LinkQueue;/* 1.初始化链式队列 */void InitQueue(LinkQueue *Q){ Q->front=Q->rear=(QueuePtr)malloc(sizeof(QNode));if (!(Q->front)) exit(0);Q->front->next=NULL; }/* 2.判断空队列 */int QueueEmpty(LinkQueue Q){ if(Q.front==Q.rear)return 1;elsereturn 0; }/* 3.入队列 */void EnQueue(LinkQueue *Q, ElemType e){ QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));if (!p) exit(0);p->data=e; p->next=NULL;Q->rear->next=p;Q->rear=p; }/* 4.出队列 */void DeQueue(LinkQueue *Q, ElemType *e){ QueuePtr p;if(Q->front!=Q->rear){ p=Q->front->next;*e=p->data;Q->front->next=p->next;if (Q->rear==p) Q->rear=Q->front;free(p); }}/****************************************************//* 以下为有向图(DAG)邻接表存储结构(ALG)的操作 *//****************************************************/#define MAX_VERTEX_NUM 20 //最大顶点个数typedef char VertexType[20]; //顶点信息(名称)/* 图的类型定义(邻接表存储结构) */typedef struct ArcNode //链表结点{ int vexpos; //该弧所指向的顶点在数组中的位置struct ArcNode *next; //指向当前起点的下一条弧的指针} ArcNode;typedef struct VNode //头结点{ VertexType name; //顶点信息(名称)int indegree; //顶点入度ArcNode *firstarc; //指向当前顶点的第一条弧的指针} VNode,AdjList[MAX_VERTEX_NUM];typedef struct{ AdjList vexhead; //邻接表头结点数组int vexnum,arcnum; //图的顶点数和弧数} ALGraph;/* 5.顶点在头结点数组中的定位 */int LocateVex(ALGraph G,VertexType v){ int i;for(i=0;i<G.vexnum;i++)if(strcmp(v,G.vexhead[i].name)==0) break;return i; }/* 6.建立图(邻接表) */int CreateGraph(ALGraph *G) //成功建立返回1,不成功则返回0 { int i,j,k; VertexType v1,v2;ArcNode *newarc;printf("\n输入有向图顶点数和弧数vexnum,arcnum:"); //输入顶点数和弧数scanf("%d,%d",&(*G).vexnum,&(*G).arcnum); //输入并判断顶点数和弧数是否正确if((*G).vexnum<0||(*G).arcnum<0||(*G).arcnum>(*G).vexnum*((*G).vexnum-1)) { printf("\n顶点数或弧数不正确,有向图建立失败!\n");return 0; } printf("\n输入 %d 个顶点:",(*G).vexnum); //输入顶点名称for(i=0;i<(*G).vexnum;i++){ scanf("%s",(*G).vexhead[i].name); }printf("\n顶点列表:\n共有%d个顶点: ",(*G).vexnum);//输出顶点名称for(i=0;i<(*G).vexnum;i++)printf("%s ",(*G).vexhead[i].name);for(i=0;i<(*G).vexnum;i++) //邻接表初始化{ (*G).vexhead[i].firstarc=NULL;(*G).vexhead[i].indegree=0;}printf("\n\n输入 %d 条边:vi vj\n",(*G).arcnum); //输入有向图的边for(k=0;k<(*G).arcnum;k++){ scanf("%s%s",v1,v2); //v1是弧的起点(先决条件),v2是弧的终点i=LocateVex(*G,v1);j=LocateVex(*G,v2); //定位顶点并判断顶点是否存在if(i>=(*G).vexnum){ printf("顶点%s不存在,有向图建立失败!\n",v1);return 0; } if(j>=(*G).vexnum){ printf("顶点%s不存在,有向图建立失败!\n",v2);return 0; } newarc=(ArcNode*)malloc(sizeof(ArcNode)); //前插法建顶点链表newarc->vexpos=j;if((*G).vexhead[i].firstarc==NULL){ newarc->next=NULL;(*G).vexhead[i].firstarc=newarc; }else{ newarc->next=(*G).vexhead[i].firstarc->next;(*G).vexhead[i].firstarc->next=newarc; }(*G).vexhead[j].indegree++; //对应顶点入度计数加1}printf("\n有向图建立成功!\n");return 1;}/* 7.按邻接表方式输出有向图 */void PrintGraph(ALGraph G){ int i;ArcNode *p;printf("\n输出有向图:\n");for(i=0; i<G.vexnum; i++){ printf("\n顶点:%s ",G.vexhead[i].name);printf("入度:%3d\n",G.vexhead[i].indegree);p=G.vexhead[i].firstarc;printf("邻接点:");while(p!=NULL){ printf("%s ",G.vexhead[p->vexpos].name);p=p->next; }printf("\n");}}//为避免演示时要输入过多数据,以下函数将课程编号、课程间的先后关系通过数组预置/* 8.建立预置课程图(邻接表) */int CreateGraph2(ALGraph *G) //成功建立返回1,不成功则返回0{ int i,j,k; VertexType v1,v2; ArcNode *newarc;VertexType SubjectName[12]={ "C1","C2","C3","C4", //课程名称"C5","C6","C7","C8","C9","C10","C11","C12" },RelationV1[16]={ "C1","C1","C2","C1", //基础课"C3","C4","C11","C5","C3","C3","C6","C9","C9","C9","C10","C11"},RelationV2[16]={ "C2","C3","C3","C4", //以上面课程为基础的课"C5","C5","C6","C7","C7","C8","C8","C10","C11","C12","C12","C12",};/* 输出本程序使用的课程及先后关系表 */printf("\n本程序预置了如下课程及先后关系:\n");printf("\n课程编号课程名称先决条件\n\C1 程序设计基础无\n\C2 离散数学 C1\n\C3 数据结构 C1,C2\n\C4 汇编语言 C1\n\C5 语言的设计和分析 C3,C4\n\C6 计算机原理 C11\n\C7 编译原理 C5,C3\n\C8 操作系统 C3,C6\n\C9 高等数学无\n\C10 线性代数 C9\n\C11 普通物理 C9\n\C12 数值分析 C9,C10,C1\n");system("PAUSE");(*G).vexnum=12; (*G).arcnum=16;if((*G).vexnum<0||(*G).arcnum<0||(*G).arcnum>(*G).vexnum*((*G).vexnum-1)) { printf("\n课程数或先后关系不正确,有向图建立失败!\n");return 0;} //判断课程数和弧数是否正确for(i=0;i<(*G).vexnum;i++){ strcpy((*G).vexhead[i].name,SubjectName[i]); }for(i=0;i<(*G).vexnum;i++) //邻接表初始化{ (*G).vexhead[i].firstarc=NULL;(*G).vexhead[i].indegree=0; }for(k=0;k<(*G).arcnum;k++){ strcpy(v1,RelationV1[k]); strcpy(v2,RelationV2[k]);i=LocateVex(*G,v1);j=LocateVex(*G,v2); //定位课程并判断课程是否存在if(i>=(*G).vexnum){ printf("课程%s不存在,有向图建立失败!\n",v1);return 0; } if(j>=(*G).vexnum){ printf("课程%s不存在,有向图建立失败!\n",v2);return 0; } newarc=(ArcNode*)malloc(sizeof(ArcNode)); //前插法建课程链表newarc->vexpos=j;if((*G).vexhead[i].firstarc==NULL){ newarc->next=NULL;(*G).vexhead[i].firstarc=newarc; }else{ newarc->next=(*G).vexhead[i].firstarc->next;(*G).vexhead[i].firstarc->next=newarc; }(*G).vexhead[j].indegree++; //对应课程入度计数加1}printf("\n有向图建立成功!\n");return 1;}/* 9.按邻接表方式输出预置课程图 */void PrintGraph2(ALGraph G){ int i;ArcNode *p;printf("\n输出有向图:\n");for(i=0; i<G.vexnum; i++){ printf("\n课程:%s ",G.vexhead[i].name);printf("入度:%3d\n",G.vexhead[i].indegree);p=G.vexhead[i].firstarc;printf("以本课程为基础的课程:");while(p!=NULL){ printf("%s ",G.vexhead[p->vexpos].name);p=p->next;}printf("\n");}}/**********************************//* 以下为拓扑排序算法 *//**********************************//* 10.拓扑排序 */void TopologicalSort(ALGraph G){ int i,k,count;ElemType e;ArcNode *p;LinkQueue Q; /*定义队列*/InitQueue(&Q);for(i=0; i<G.vexnum; i++) //零入度课程入队列if(!G.vexhead[i].indegree) EnQueue(&Q,i);count=0; //对输出课程计数变量初始化printf("\n\n\n以上课程的一个拓扑排序序列为:\n");while(!QueueEmpty(Q)){ DeQueue(&Q,&e); //先将入度为零的课程输出printf("%s ",G.vexhead[e].name);count++; //对输出的顶点计数for(p=G.vexhead[e].firstarc;p;p=p->next) //遍历当前课程的邻接点{ k=p->vexpos; //邻接点位置if(!(--G.vexhead[k].indegree)) //每个邻接点入度减1后若为零则入队列EnQueue(&Q,k);}}printf("\n");if(count<G.vexnum){ printf("\n该有向图有回路,无法完成拓扑排序!\n"); }}/**********************************//* 以下为拓扑检测算法 *//**********************************//* 11.运用拓扑排序的思想检测教学计划 */void TopSortCheck(ALGraph G){ int i,k; ArcNode *p; VertexType v,CheckList[12];//待检测序列TopologicalSort(G);printf("\n输入待检测的课程序列:\n");for(i=0; i<G.vexnum; i++) //输入待检测序列scanf("%s",CheckList[i]);for(i=0; i<G.vexnum; i++){ strcpy(v,CheckList[i]);k=LocateVex(G,v);if(k>=G.vexnum) //判断课程是否存在{ printf("课程%s不存在!\n",v);return; }if(G.vexhead[k].indegree!=0) //判断课程入度是否为零{ printf("学习课程%s时,还有%d门先决课程未学!\n",v,G.vexhead[k].indegree);printf("本课程序列不是拓扑序列\n\n");return; }else{ for(p=G.vexhead[LocateVex(G,v)].firstarc;p;p=p->next)//遍历此课程邻接点{ k=p->vexpos; //邻接点位置G.vexhead[k].indegree--;} //每个邻接点入度减1}}printf("本课程序列符合拓扑序列\n\n");}/*******************************************//* 12.主函数 *//*******************************************/void main(){ ALGraph G; int menu,menu2;while(1){printf("\n **********************************************\n");printf(" * 1.建立有向图并输出 *\n");printf(" * 2.建立有向图并求一个拓扑排序序列 *\n");printf(" * 3.检测用户输入的课程安排 *\n");printf(" * 4.清屏 *\n");printf(" * 5.退出 *\n");printf(" **********************************************\n");printf(" 请输入你的选择:");scanf("%d",&menu);switch(menu){case 1:if(CreateGraph(&G)){system("PAUSE");PrintGraph(G);}//有向图建成则执操作break;case 2:if(CreateGraph(&G)) //有向图建成则执操作{ system("PAUSE");PrintGraph(G);system("PAUSE");TopologicalSort(G); }break;case 3:if(CreateGraph2(&G)){ //有向图建成则执操作system("PAUSE");PrintGraph2(G); system("PAUSE");while(1){TopSortCheck(G);printf("\n ************************************\n");printf(" * 1.检测其他课程序列 *\n");printf(" * 2.完成检测 *\n");printf(" ************************************\n");printf(" 请输入你的选择:");scanf("%d",&menu2);if(menu2!=1) break; }}break;case 4:system("CLS");break;case 5:return;}}}七、测试数据1、对“建立有向图并输出”的测试1) 正确的有向图信息顶点数和弧数:4,3顶点:A B C D边: A B B C C D2) 错误的边顶点数和弧数:4,3顶点:A B C D边: A B B C C E3) 错误的顶点数或弧数顶点数和弧数:3,72、对“建立有向图并求一个拓扑排序序列”的测试1) 有向图能实现拓扑排序顶点数和弧数:5,5顶点:A B C D E边:A D D C C B E A E C2) 有向图不能实现拓扑排序顶点数和弧数:5,5顶点:A B C D E边:A D D C C B E A B A3、对“检测用户输入的课程安排”的测试1) 课程序列符合拓扑序列课程序列:C9 C10 C11 C6 C1 C12 C4 C2 C3 C5 C7 C8 2) 课程序列中有课程不存在课程序列:C9 C10 C11 C6 C1 C12 C4 C2 C13 C5 C7 C8 3) 课程序列不是拓扑序列课程序列:C9 C10 C11 C1 C8 C6 C12 C4 C2 C3 C5 C7八、测试情况程序初始执行界面(以下测试编号与本文第七节测试数据编号一一对应)1、对“建立有向图并输出”的测试1) 正确的有向图信息有向图信息正确的情况下,程序显示“有向图建立成功”,并输出有向图。

相关文档
最新文档