拓扑排序-数据结构实验

合集下载

数据结构(牛小飞)3 拓扑排序

数据结构(牛小飞)3 拓扑排序

2021/8/5
25
5
拓扑排序-定义
拓扑排序是对有向无圈图的顶点的一种排序,使 得如果存在一条从vi到vj的路径,那么在排序中vj 就出现在vi的后面。
✓ 显然,如果图中含有圈,那么拓扑排序是不可能的, 因为对于圈上的两个顶点v和w,v优先于w同时w又优 先于v。
2021/8/5
6
拓扑排序-举例
B
A
D
C
不能求得它的拓扑有序序列。
// 对尚未访问的顶点调用DFS
}
while(!Empty(S)) //输出拓扑排序的结果
System.out.print(S.pop());
} 2021/8/5
21
拓扑排序-方法2
void DFS-T(int v) { // 从顶点v出发,深度优先搜索遍历连通图 vertexs[v].visited = true; for(w=FirstAdjVex(v);w>=0; w=NextAdjVex(v,w)) { if (!vertexs[w].visited) DFS-T(w); } // 对v的尚未访问的邻接顶点w递归调用DFS-T S.push(v); //顶点v的DFS函数执行完毕
q.enqueue(v);
while (!q.isEmpty( ) { //如果队列非空
…………
}
if (counter!=NUM_VERTICES) //有圈
throw new CycleFoundException( );
}
2021/8/5
15
拓扑排序-方法1
void topsort( ) throws CycleFoundException { …….
} // DFS-T

数据结构排序实验报告

数据结构排序实验报告

数据结构排序实验报告数据结构排序实验报告引言:数据结构是计算机科学中的重要概念之一,它涉及到数据的组织、存储和操作方式。

排序是数据结构中的基本操作之一,它可以将一组无序的数据按照特定的规则进行排列,从而方便后续的查找和处理。

本实验旨在通过对不同排序算法的实验比较,探讨它们的性能差异和适用场景。

一、实验目的本实验的主要目的是通过实际操作,深入理解不同排序算法的原理和实现方式,并通过对比它们的性能差异,选取合适的排序算法用于不同场景中。

二、实验环境和工具实验环境:Windows 10 操作系统开发工具:Visual Studio 2019编程语言:C++三、实验过程1. 实验准备在开始实验之前,我们需要先准备一组待排序的数据。

为了保证实验的公正性,我们选择了一组包含10000个随机整数的数据集。

这些数据将被用于对比各种排序算法的性能。

2. 实验步骤我们选择了常见的五种排序算法进行实验比较,分别是冒泡排序、选择排序、插入排序、快速排序和归并排序。

- 冒泡排序:该算法通过不断比较相邻元素的大小,将较大的元素逐渐“冒泡”到数组的末尾。

实现时,我们使用了双重循环来遍历整个数组,并通过交换元素的方式进行排序。

- 选择排序:该算法通过不断选择数组中的最小元素,并将其放置在已排序部分的末尾。

实现时,我们使用了双重循环来遍历整个数组,并通过交换元素的方式进行排序。

- 插入排序:该算法将数组分为已排序和未排序两部分,然后逐个将未排序部分的元素插入到已排序部分的合适位置。

实现时,我们使用了循环和条件判断来找到插入位置,并通过移动元素的方式进行排序。

- 快速排序:该算法通过选取一个基准元素,将数组分为两个子数组,并对子数组进行递归排序。

实现时,我们使用了递归和分治的思想,将数组不断划分为更小的子数组进行排序。

- 归并排序:该算法通过将数组递归地划分为更小的子数组,并将子数组进行合并排序。

实现时,我们使用了递归和分治的思想,将数组不断划分为更小的子数组进行排序,然后再将子数组合并起来。

拓扑排序的原理及其实现

拓扑排序的原理及其实现

拓扑排序的原理及其实现取材自以下材料:/wiki/Topological_sorting/wiki/Hamiltonian_path定义和前置条件:定义:将有向图中的顶点以线性方式进行排序。

即对于任何连接自顶点u到顶点v的有向边uv,在最后的排序结果中,顶点u总是在顶点v的前面。

如果这个概念还略显抽象的话,那么不妨考虑一个非常非常经典的例子——选课。

我想任何看过数据结构相关书籍的同学都知道它吧。

假设我非常想学习一门“机器学习”的课程,但是在修这么课程之前,我们必须要学习一些基础课程,比如:计算机科学概论,C语言程序设计,数据结构,算法等等。

那么这个制定选修课程顺序的过程,实际上就是一个拓扑排序的过程,每门课程相当于有向图中的一个顶点,而连接顶点之间的有向边就是课程学习的先后关系。

只不过这个过程不是那么复杂,从而很自然的在我们的大脑中完成了。

将这个过程以算法的形式描述出来的结果,就是拓扑排序。

那么是不是所有的有向图都能够被拓扑排序呢?显然不是。

继续考虑上面的例子,如果告诉你在选修“计算机科学概论”这门课之前需要你先学习“机器学习”,你是不是会被弄糊涂?在这种情况下,就无法进行拓扑排序,因为它中间存在互相依赖的关系,从而无法确定谁先谁后。

在有向图中,这种情况被描述为存在环路。

因此,一个有向图能被拓扑排序的充要条件就是它是一个有向无环图(DAG:Directed Acyclic Graph)。

偏序/全序关系:偏序和全序实际上是离散数学中的概念。

这里不打算说太多形式化的定义,形式化的定义教科书上或者上面给的链接中就说的很详细。

还是以上面选课的例子来描述这两个概念。

假设我们在学习完了算法这门课后,可以选修“机器学习”或者“计算机图形学”。

这个“或者”表示,学习“机器学习”和“计算机图形学”这两门课之间没有特定的先后顺序。

因此,在我们所有可以选择的课程中,任意两门课程之间的关系要么是确定的(即拥有先后关系),要么是不确定的(即没有先后关系),绝对不存在互相矛盾的关系(即环路)。

图的搜索与应用实验报告(附源码)(word文档良心出品)

图的搜索与应用实验报告(附源码)(word文档良心出品)

哈尔滨工业大学计算机科学与技术学院实验报告课程名称:数据结构与算法课程类型:必修实验项目名称:图的搜索与应用实验题目:图的深度和广度搜索与拓扑排序设计成绩报告成绩指导老师一、实验目的1.掌握图的邻接表的存储形式。

2.熟练掌握图的搜索策略,包括深度优先搜索与广度优先搜索算法。

3.掌握有向图的拓扑排序的方法。

二、实验要求及实验环境实验要求:1.以邻接表的形式存储图。

2.给出图的深度优先搜索算法与广度优先搜索算法。

3.应用搜索算法求出有向图的拓扑排序。

实验环境:寝室+机房+编程软件(NetBeans IDE 6.9.1)。

三、设计思想(本程序中的用到的所有数据类型的定义,主程序的流程图及各程序模块之间的调用关系)数据类型定义:template <class T>class Node {//定义边public:int adjvex;//定义顶点所对应的序号Node *next;//指向下一顶点的指针int weight;//边的权重};template <class T>class Vnode {public:T vertex;Node<T> *firstedge;};template <class T>class Algraph {public:Vnode<T> adjlist[Max];int n;int e;int mark[Max];int Indegree[Max];};template<class T>class Function {public://创建有向图邻接表void CreatNalgraph(Algraph<T>*G);//创建无向图邻接表void CreatAlgraph(Algraph<T> *G);//深度优先递归搜索void DFSM(Algraph<T>*G, int i);void DFS(Algraph<T>* G);//广度优先搜索void BFS(Algraph<T>* G);void BFSM(Algraph<T>* G, int i);//有向图的拓扑排序void Topsort(Algraph<T>*G);/得到某个顶点内容所对应的数组序号int Judge(Algraph<T>* G, T name); };主程序流程图:程序开始调用关系:主函数调用五个函数 CreatNalgraph(G)//创建有向图 DFS(G) //深度优先搜索 BFS(G) //广度优先搜索 Topsort(G) //有向图拓扑排序 CreatAlgraph(G) //创建无向图其中 CreatNalgraph(G) 调用Judge(Algraph<T>* G, T name)函数;DFS(G)调用DFSM(Algraph<T>* G , int i)函数;BFS(G) 调用BFSM(Algraph<T>* G, int k)函数;CreatAlgraph(G) 调选择图的类型无向图有向图深 度 优 先 搜 索广度优先搜索 深 度 优 先 搜 索 广度优先搜索拓 扑 排 序程序结束用Judge(Algraph<T>* G, T name)函数。

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

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

数据结构之的拓扑排序算法拓扑排序算法的实现和性能分析数据结构之拓扑排序算法拓扑排序算法的实现和性能分析拓扑排序是一种常用的图算法,用于对有向无环图(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表示边数。

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

数据结构课设——有向图的深度、广度优先遍历及拓扑排序

数据结构课设——有向图的深度、广度优先遍历及拓扑排序

数据结构课设——有向图的深度、⼴度优先遍历及拓扑排序任务:给定⼀个有向图,实现图的深度优先, ⼴度优先遍历算法,拓扑有序序列,并输出相关结果。

功能要求:输⼊图的基本信息,并建⽴图存储结构(有相应提⽰),输出遍历序列,然后进⾏拓扑排序,并测试该图是否为有向⽆环图,并输出拓扑序列。

按照惯例,先上代码,注释超详细:#include<stdio.h>#include<stdlib.h>#include<malloc.h>#pragma warning(disable:4996)#define Max 20//定义数组元素最⼤个数(顶点最⼤个数)typedef struct node//边表结点{int adjvex;//该边所指向结点对应的下标struct node* next;//该边所指向下⼀个结点的指针}eNode;typedef struct headnode//顶点表结点{int in;//顶点⼊度char vertex;//顶点数据eNode* firstedge;//指向第⼀条边的指针,边表头指针}hNode;typedef struct//邻接表(图){hNode adjlist[Max];//以数组的形式存储int n, e;//顶点数,边数}linkG;//以邻接表的存储结构创建图linkG* creat(linkG* g){int i, k;eNode* s;//边表结点int n1, e1;char ch;g = (linkG*)malloc(sizeof(linkG));//申请结点空间printf("请输⼊顶点数和边数:");scanf("%d%d", &n1, &e1);g->n = n1;g->e = e1;printf("顶点数:%d 边数:%d\n", g->n, g->e);printf("请输⼊顶点信息(字母):");getchar();//因为接下来要输⼊字符串,所以getchar⽤于承接上⼀条命令的结束符for (i = 0; i < n1; i++){scanf("%c", &ch);g->adjlist[i].vertex = ch;//获得该顶点数据g->adjlist[i].firstedge = NULL;//第⼀条边设为空}printf("\n打印顶点下标及顶点数据:\n");for (i = 0; i < g->n; i++)//循环打印顶点下标及顶点数据{printf("顶点下标:%d 顶点数据:%c\n", i, g->adjlist[i].vertex);}getchar();int i1, j1;//相连接的两个顶点序号for (k = 0; k < e1; k++)//建⽴边表{printf("请输⼊对<i,j>(空格分隔):");scanf("%d%d", &i1, &j1);s = (eNode*)malloc(sizeof(eNode));//申请边结点空间s->adjvex = j1;//边所指向结点的位置,下标为j1s->next = g->adjlist[i1].firstedge;//将当前s的指针指向当前顶点上指向的结点g->adjlist[i1].firstedge = s;//将当前顶点的指针指向s}return g;//返回指针g}int visited[Max];//标记是否访问void DFS(linkG* g, int i)//深度优先遍历{eNode* p;printf("%c ", g->adjlist[i].vertex);visited[i] = 1;//将已访问过的顶点visited值改为1p = g->adjlist[i].firstedge;//p指向顶点i的第⼀条边while (p)//p不为NULL时(边存在){if (visited[p->adjvex] != 1)//如果没有被访问DFS(g, p->adjvex);//递归}p = p->next;//p指向下⼀个结点}}void DFSTravel(linkG* g)//遍历⾮连通图{int i;printf("深度优先遍历;\n");//printf("%d\n",g->n);for (i = 0; i < g->n; i++)//初始化为0{visited[i] = 0;}for (i = 0; i < g->n; i++)//对每个顶点做循环{if (!visited[i])//如果没有被访问{DFS(g, i);//调⽤DFS函数}}}void BFS(linkG* g, int i)//⼴度优先遍历{int j;eNode* p;int q[Max], front = 0, rear = 0;//建⽴顺序队列⽤来存储,并初始化printf("%c ", g->adjlist[i].vertex);visited[i] = 1;//将已经访问过的改成1rear = (rear + 1) % Max;//普通顺序队列的话,这⾥是rear++q[rear] = i;//当前顶点(下标)队尾进队while (front != rear)//队列⾮空{front = (front + 1) % Max;//循环队列,顶点出队j = q[front];p = g->adjlist[j].firstedge;//p指向出队顶点j的第⼀条边while (p != NULL){if (visited[p->adjvex] == 0)//如果未被访问{printf("%c ", g->adjlist[p->adjvex].vertex);visited[p->adjvex] = 1;//将该顶点标记数组值改为1rear = (rear + 1) % Max;//循环队列q[rear] = p->adjvex;//该顶点进队}p = p->next;//指向下⼀个结点}}}void BFSTravel(linkG* g)//遍历⾮连通图{int i;printf("⼴度优先遍历:\n");for (i = 0; i < g->n; i++)//初始化为0{visited[i] = 0;}for (i = 0; i < g->n; i++)//对每个顶点做循环{if (!visited[i])//如果没有被访问过{BFS(g, i);//调⽤BFS函数}}}//因为拓扑排序要求⼊度为0,所以需要先求出每个顶点的⼊度void inDegree(linkG* g)//求图顶点⼊度{eNode* p;int i;for (i = 0; i < g->n; i++)//循环将顶点⼊度初始化为0{g->adjlist[i].in = 0;}for (i = 0; i < g->n; i++)//循环每个顶点{p = g->adjlist[i].firstedge;//获取第i个链表第1个边结点指针while (p != NULL)///当p不为空(边存在){g->adjlist[p->adjvex].in++;//该边终点结点⼊度+1p = p->next;//p指向下⼀个边结点}printf("顶点%c的⼊度为:%d\n", g->adjlist[i].vertex, g->adjlist[i].in);}void topo_sort(linkG *g)//拓扑排序{eNode* p;int i, k, gettop;int top = 0;//⽤于栈指针的下标索引int count = 0;//⽤于统计输出顶点的个数int* stack=(int *)malloc(g->n*sizeof(int));//⽤于存储⼊度为0的顶点for (i=0;i<g->n;i++)//第⼀次搜索⼊度为0的顶点{if (g->adjlist[i].in==0){stack[++top] = i;//将⼊度为0的顶点进栈}}while (top!=0)//当栈不为空时{gettop = stack[top--];//出栈,并保存栈顶元素(下标)printf("%c ",g->adjlist[gettop].vertex);count++;//统计顶点//接下来是将邻接点的⼊度减⼀,并判断该点⼊度是否为0p = g->adjlist[gettop].firstedge;//p指向该顶点的第⼀条边的指针while (p)//当p不为空时{k = p->adjvex;//相连接的顶点(下标)g->adjlist[k].in--;//该顶点⼊度减⼀if (g->adjlist[k].in==0){stack[++top] = k;//如果⼊度为0,则进栈}p = p->next;//指向下⼀条边}}if (count<g->n)//如果输出的顶点数少于总顶点数,则表⽰有环{printf("\n有回路!\n");}free(stack);//释放空间}void menu()//菜单{system("cls");//清屏函数printf("************************************************\n");printf("* 1.建⽴图 *\n");printf("* 2.深度优先遍历 *\n");printf("* 3.⼴度优先遍历 *\n");printf("* 4.求出顶点⼊度 *\n");printf("* 5.拓扑排序 *\n");printf("* 6.退出 *\n");printf("************************************************\n");}int main(){linkG* g = NULL;int c;while (1){menu();printf("请选择:");scanf("%d", &c);switch (c){case1:g = creat(g); system("pause");break;case2:DFSTravel(g); system("pause");break;case3:BFSTravel(g); system("pause");break;case4:inDegree(g); system("pause");break;case5:topo_sort(g); system("pause");break;case6:exit(0);break;}}return0;}实验⽤图:运⾏结果:关于深度优先遍历 a.从图中某个顶点v 出发,访问v 。

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

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

数据结构之拓扑排序算法详解拓扑排序算法是一种常用于有向无环图(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. 任务调度:在一个任务依赖关系图中,拓扑排序可以确定任务的执行顺序,保证所有任务按照依赖关系正确执行。

数据结构拓扑排序实验报告

数据结构拓扑排序实验报告

数据结构拓扑排序实验报告正文:一、实验目的本实验旨在通过实现拓扑排序算法来加深对数据结构中图的相关概念的理解,掌握拓扑排序的具体步骤与实现方法。

二、实验原理拓扑排序是一种对有向无环图进行排序的算法,它可以将有向无环图的顶点按照线性的顺序排列出来,使得对于任何一个有向边(u, v),都有顶点 u 在排列中出现在顶点 v 之前。

拓扑排序常用于表示图中的依赖关系,如任务调度、编译顺序等场景。

三、实验步骤1. 构建有向图根据实际需求构建有向图,可以使用邻接表或邻接矩阵等数据结构来表示有向图。

2. 执行拓扑排序算法利用拓扑排序算法对构建的有向图进行排序,可选择使用深度优先搜索(DFS)或广度优先搜索(BFS)等算法实现。

3. 输出排序结果将排序后的顶点按照线性的顺序输出,得到拓扑排序的结果。

四、实验结果与分析1. 实验数据以图 G = (V, E) 的顶点集合 V 和边集合 E,构建了如下的有向图:V = {A, B, C, D, E, F}E = {(A, C), (B, C), (C, D), (D, E), (E, F)}2. 拓扑排序结果经过拓扑排序算法的处理,得到的拓扑排序结果如下: A, B, C, D, E, F3. 结果分析可以看出,根据有向图的依赖关系,拓扑排序算法能够将顶点按照合理的顺序进行排序。

拓扑排序的结果可以作为图中顶点的执行顺序,具有重要的应用价值。

五、实验总结通过本次实验,我们深入学习了拓扑排序算法,并成功实现了拓扑排序的过程。

拓扑排序在图论和数据结构中具有广泛的应用,对于理解和解决与图相关的问题具有重要意义。

六、附件本文档没有涉及附件内容。

七、法律名词及注释本文档没有涉及法律名词及注释。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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

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

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

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

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

需求分析:(测试数据加强版)
1、输入形式:
第一行是是个整数t,表示有t组测试数据;
每一组测试数据的第一行是一个整数n,表示结点数目
接下来的n行是n个顶点的信息
接下来的一行是一个整数m,表示有向边的数目
接下来是m行数据每一行是一条有向边的起止结点信息
2、输出形式:
如果可以实现拓扑排序,输出其得到的合法线性序列
否则,输出“Input Error!”;
3、功能描述:
帮助判断当前的课程是否可以安排得当;
如果得当,输出一个合法的修读顺序;
4、样例输入输出:
输入:
2
5
Math
English
Physics
Chinese
Music
5
Math English
Math Physics
English Chinese
Physic Chinese
Chinese Music
5
Math
English
Physics
Chinese
Music
4
Math English
Math Physics
English Chinese
Physic 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>、重复上述步骤,直到全部顶点都已经输出了或者图中剩下的顶点
都不满足上述的两个条件位置。

后者说明有向图中存在环。

详细设计:
通过一下函数分块、分步的实现:
void creat() function:建立邻接表
int find(char *str) function:在顶点集中查找信息为str的顶点的编号,
并返回之
void update(int node) function:没输出一个顶点的时候要相应的调用该函
数更新顶点入度信息在main()函数内调用上述函数实现功能描述
C++代码详见:code 10.cpp
#include<iostream>
#include<cstring>
#include<stdlib.h>
using namespace std;
# define Max 1001
int n,m;
typedef struct Arc* link;
struct Arc
{
char info[15];
int adjvex;
link nextarc;
};
struct Vex
{
char info[15];
int indgree;
link firstarc;
}v[Max];
int find(char *str)
{
for(int i=1;i<=n;i++)
if(!strcmp(str,v[i].info))
return i;
}
void creat()
{
cout<<"课程总数:"<<endl;
cin>>n;
cout<<"请输入各个顶点信息(即课程的编号):"<<endl; for(int i=1;i<=n;i++)
{
cin>>v[i].info;
v[i].indgree=0;
v[i].firstarc=NULL;
}
cout<<"请输入有向边数目:";
cin>>m;
cout<<"输入有向边(先修课程编号在前):"<<endl;
for(int i=0;i<m;i++)
{
char ss[15],tt[15];
cin>>ss>>tt;
int s=find(ss),t=find(tt);
v[t].indgree++;
link p=(link)malloc(sizeof(Arc));
strcpy(p->info,v[t].info);
p->adjvex=t;
p->nextarc=v[s].firstarc;
v[s].firstarc=p;
}
}
void update(int node)
{
link p=v[node].firstarc;
while(p)
{
if(v[p->adjvex].indgree>0) v[p->adjvex].indgree--; p=p->nextarc;
}
}
int main()
{
int rel[Max],len=0,t;
cout<<"请输入测试数据数目:"<<endl;
cin>>t;
while(t--)
{
creat();
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
if(!v[i].indgree)
{
rel[len++]=i;
v[i].indgree=-1;
update(i);
}
cout<<"------------------------"<<endl;
if(len<n) cout<<"Input Error!"<<endl; else
{
for(int i=0;i<len;i++)
cout<<v[i].info<<" ";
cout<<endl;
}
cout<<"------------------------"<<endl; }
system("pause");
return 0;
}
/*
2
5
Math
English
Physics
Chinese
Music
5
Math English
Math Physics
English Chinese
Physic Chinese
Chinese Music
5
Math
English
Physics
Chinese
Music
4
Math English
Math Physics
English Chinese
Physic Chinese
*/
调试分析:
调试过程中没有发现什么问题。

测试结果:
用户使用说明:
本程序只支持1000以内的科目数对应的操作。

相关文档
最新文档