第1关:求AOV网(邻接矩阵存储)的拓扑排序算法
编程要求
有向图的存储结构为邻接矩阵,编写函数实现图的拓扑排序算法:
- int TopologicalSort(MGraph G);// 有向图G采用邻接矩阵存储结构。若G无回路,则输出G的顶点的一个拓扑序列并返回1,否则返回0
测试说明
平台会对你编写的代码进行测试:
测试输入: 0
lt6.txt
输入说明: 第一行输入
0
,表示输入图的类型为有向图。 第二行输入文件名,该文件里保存了图的数据信息,内容如下: 7 7 高等数学 程序设计 离散数学 数据结构 编译原理 操作系统 计算机组成原理 高等数学 离散数学 离散数学 数据结构 数据结构 操作系统 数据结构 编译原理 程序设计 计算机组成原理 程序设计 编译原理 计算机组成原理 操作系统
第1行为图的顶点的个数n; 第2行为图的边的条数m; 第3行至第n+2行是n个顶点的数据; 第n+3行至第n+m+2行是m条边的数据;
预期输出: 有向图
7个顶点7条边。顶点依次是: 高等数学 程序设计 离散数学 数据结构 编译原理 操作系统 计算机组成原理
图的邻接矩阵:
0 0 1 0 0 0 0
0 0 0 0 1 0 1
0 0 0 1 0 0 0
0 0 0 0 1 1 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 1 0
输出有向图g的拓扑序列:
程序设计 计算机组成原理 高等数学 离散数学 数据结构 操作系统 编译原理
输出说明: 第一行输出图的类型。 第二部分起输出图的顶点和边的数据信息。 第三部分输出有向图的一个拓扑序列,若有回路,则输出提示此有向图有回路。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<limits.h> #include"MGraph.h" #include"sqstack.h" void FindInDegree(MGraph G,int indegree[]); // 求顶点的入度 int TopologicalSort(MGraph G);// 有向图G采用邻接矩阵存储结构。若G无回路,则输出G的顶点的一个拓扑序列并返回1,否则返回0 int main() { MGraph g; CreateGraphF(g); // 利用数据文件创建无向图 Display(g); // 输出无向图 printf("输出有向图g的拓扑序列:\n"); TopologicalSort(g); // 输出有向图f的拓扑序列 return 0; } void FindInDegree(MGraph G,int indegree[]) { //计算图G每个顶点的入度,并且保存在indegree数组 int i,j; for(i=0;i<G.vexnum;i++) indegree[i]=0; /* 赋初值 */ for(i=0;i<G.vexnum;i++) for(j=0;j<G.vexnum;j++) if( G.arcs [j][i].adj == 1) indegree[i]++; } int TopologicalSort(MGraph G) { // 有向图G采用邻接矩阵存储结构。 // 若G无回路,则输出G的顶点的一个拓扑序列并返回1,否则返回0。 /********** Begin **********/ int i,k,count=0; // 已输出顶点数,初值为0 int indegree[MAX_VERTEX_NUM]; // 入度数组,存放各顶点当前入度数 SqStack S; FindInDegree(G,indegree); // 对各顶点求入度indegree[] InitStack(S); // 初始化零入度顶点栈S for(i=0;i<G.vexnum;++i) // 对所有顶点i if(!indegree[i]) // 若其入度为0 Push(S,i); // 将i入零入度顶点栈S while(!StackEmpty(S)) { // 当零入度顶点栈S不空 Pop(S,i); // 出栈1个零入度顶点的序号,并将其赋给i printf("%s ",G.vexs [i]); // 输出i号顶点 ++count; // 已输出顶点数+1 for(k=0;k<G.vexnum ;k++) // // 对i号顶点的每个邻接顶点其序号为k { if(G.arcs [i][k].adj == 1 ) if(!(--indegree[k])) // k的入度减1,若减为0,则将k入栈S Push(S,k); } } if(count<G.vexnum) // 零入度顶点栈S已空,图G还有顶点未输出 { printf("\n此有向图有回路\n"); return 0; } else return 1; /********** End **********/ }
第2关:求AOV网(邻接表存储)的拓扑排序算法
编程要求
有向图的存储结构为邻接表,编写函数实现图的拓扑排序算法:
- int TopologicalSort(ALGraph G);// 有向图G采用邻接表存储结构。若G无回路,则输出G的顶点的一个拓扑序列并返回1,否则返回0
如果此有向图没有回路,则此有向图为AOV网。
测试说明
平台会对你编写的代码进行测试:
测试输入:
0
lt6.txt
输入说明: 第一行输入
0
,表示输入图的类型为有向图。 第二行输入文件名,该文件里保存了图的数据信息,内容如下: 7 7 高等数学 程序设计 离散数学 数据结构 编译原理 操作系统 计算机组成原理 高等数学 离散数学 离散数学 数据结构 数据结构 操作系统 数据结构 编译原理 程序设计 计算机组成原理 程序设计 编译原理 计算机组成原理 操作系统第1行为图的顶点的个数n; 第2行为图的边的条数m; 第3行至第n+2行是n个顶点的数据; 第n+3行至第n+m+2行是m条边的数据;
预期输出:
有向图
7个顶点:
高等数学 程序设计 离散数学 数据结构 编译原理 操作系统 计算机组成原理
7条弧(边):
高等数学→离散数学
程序设计→编译原理 程序设计→计算机组成原理
离散数学→数据结构
数据结构→编译原理 数据结构→操作系统
计算机组成原理→操作系统
输出有向图g的拓扑序列:
程序设计 计算机组成原理 高等数学 离散数学 数据结构 操作系统 编译原理
输出说明: 第一行输出图的类型。 第二部分起输出图的顶点和边的数据信息。 第三部分输出有向图的一个拓扑序列,若有回路,则输出提示此有向图有回路。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<limits.h> #include<iostream> using namespace std; #define INFINITY 4270000 // 用整型最大值代替∞ #include"ALGraph.h" #include"sqstack.h" void FindInDegree(ALGraph G,int indegree[]); // 求顶点的入度 int TopologicalSort(ALGraph G);// 有向图G采用邻接表存储结构。若G无回路,则输出G的顶点的一个拓扑序列并返回1,否则返回0 int main() { ALGraph g; CreateGraphF(g); // 利用数据文件创建无向图 Display(g); // 输出无向图 printf("输出有向图g的拓扑序列:\n"); TopologicalSort(g); // 输出有向图f的1个拓扑序列 return 0; } void FindInDegree(ALGraph G,int indegree[]) { //计算图G每个顶点的入度,并且保存在indegree数组 int i; ArcNode *p; for(i=0;i<G.vexnum;i++) indegree[i]=0; /* 赋初值 */ for(i=0;i<G.vexnum;i++) { p=G.vertices[i].firstarc; while(p) { indegree[p->data.adjvex]++; p=p->nextarc; } } } int TopologicalSort(ALGraph G) { // 有向图G采用邻接表存储结构。 // 若G无回路,则输出G的顶点的一个拓扑序列并返回1,否则返回0。 /********** Begin **********/ int i,k,count=0; // 已输出顶点数,初值为0 int indegree[MAX_VERTEX_NUM]; // 入度数组,存放各顶点当前入度数 SqStack S; ArcNode *p; FindInDegree(G,indegree); // 对各顶点求入度indegree[] InitStack(S); // 初始化零入度顶点栈S for(i=0;i<G.vexnum;++i) // 对所有顶点i if(!indegree[i]) // 若其入度为0 Push(S,i); // 将i入零入度顶点栈S while(!StackEmpty(S)) { // 当零入度顶点栈S不空 Pop(S,i); // 出栈1个零入度顶点的序号,并将其赋给i printf("%s ",G.vertices[i].data); // 输出i号顶点 ++count; // 已输出顶点数+1 for(p=G.vertices[i].firstarc; p; p=p->nextarc) { // 对i号顶点的每个邻接顶点 k=p->data.adjvex; // 其序号为k if(!(--indegree[k])) // k的入度减1,若减为0,则将k入栈S Push(S,k); } } if(count<G.vexnum) { // 零入度顶点栈S已空,图G还有顶点未输出 printf("\n此有向图有回路\n"); return 0; } else return 1; /********** End **********/ }