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

拓扑排序[基本要求] 用邻接表建立一个有向图的存储结构。
利用拓扑排序算法输出该图的拓扑排序序列。
[编程思路]首先图的创建,采用邻接表建立,逆向插入到单链表中,特别注意有向是不需要对称插入结点,且要把输入的字符在顶点数组中定位(LocateVex(Graph G,char *name),以便后来的遍历操作,几乎和图的创建一样,图的顶点定义时加入int indegree,关键在于indegree 的计算,而最好的就是在创建的时候就算出入度,(没有采用书上的indegree【】数组的方法,那样会增加一个indegree算法,而是在创建的时候假如一句计数的代码(G.vertices[j].indegree)++;)最后调用拓扑排序的算法,得出拓扑序列。
[程序代码]头文件:#define MAX_VERTEX_NUM 30#define STACKSIZE 30#define STACKINCREMENT 10#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2#define TRUE 1#define FALSE 0typedef int Status;typedef int InfoType;typedef int Status;typedef int SElemType;/* 定义弧的结构*/typedef struct ArcNode{int adjvex; /*该边所指向的顶点的位置*/struct ArcNode *nextarc; /*指向下一条边的指针*/InfoType info; /*该弧相关信息的指针*/}ArcNode;/*定义顶点的结构*/typedef struct VNode{int indegree;char data[10]; /*顶点信息*/ArcNode *firstarc; /*指向第一条依附该顶点的弧的指针*/ }VNode,AdjList[MAX_VERTEX_NUM];/*定义图的结构*/typedef struct {AdjList vertices;int vexnum,arcnum; /*图的当前顶点数和弧数*/int kind; /*图的类型标志*/}Graph;/*定义栈的结构*/typedef struct{SElemType *base;SElemType *top;int stacksize;}Stack;/*顶点定位*/int LocateVex(Graph G,char *name);/*创建有向图*/void CreateGraph(Graph &G);/*拓扑排序*/StatusTopologicalSort(Graph G);/*初始化栈*/Status InitStack(Stack &s) ;/*判断空*/Status EmptyStack(Stack s);/*压栈*/Status Push(Stack &s,int e);/*出栈*/Status Pop(Stack &s,int &e);实现文件:#include <stdio.h>#include"malloc.h"#include "tuopupaixuhead.h"#include "stdlib.h"#include "string.h"bool visited[MAX_VERTEX_NUM];/************************************************************ 顶点定位,返回位序 ************************************************************/int LocateVex(Graph G,char *name){int i;for(i=1;i<=G.vexnum;i++)if(strcmp(name,G.vertices[i].data)==0) //返回数组的位置return i;return -1;}/************************************************************ 创建有向图 ************************************************************/void CreateGraph(Graph &G){ArcNode *p;char name1[10],name2[10];int i,j,k;printf(" 请输入顶点数,按回车键结束:");scanf("%d",&G.vexnum);printf(" 请输入弧数,按回车键结束:");scanf("%d",&G.arcnum);printf(" 请依次输入顶点名(用空格分开且字符小于10),按回车键结束:\n"); printf(" ");for(i=1;i<=G.vexnum;i++) //初始化{scanf("%s",G.vertices[i].data);G.vertices[i].firstarc=NULL;G.vertices[i].indegree=0; //度数均初始化为0}printf("\n\n\n\n");printf(" ………………………………………输入小提示………………………………………\n");printf(" &&&&1 为避免输入遗漏,最好从选择任意一点,输入所有相邻边\n"); printf(" &&&&2 输入边时格式(用空格分开,即格式为顶点(空格)顶点(空格))\n");printf(" ………………………………………输入小提示………………………………………\n\n\n\n");for(k=0;k<G.arcnum;k++){printf(" 请输入相邻的两个顶点,按回车键结束:");scanf("%s%s",name1,name2);i=LocateVex(G,name1);j=LocateVex(G,name2);(G.vertices[j].indegree)++; //每次作为弧的邻接点,则度数加1p=(ArcNode *)malloc(sizeof(ArcNode)); //申请边节点p->adjvex=j; //插入到邻接表中,注意此处为逆向插入到单链表中p->nextarc=G.vertices[i].firstarc;G.vertices[i].firstarc=p;}}/************************************************************ 初始化栈 ************************************************************/Status InitStack(Stack &s) //创建一个空栈{s.base=(int*)malloc(STACKSIZE*sizeof(int));if(!s.base)return (OVERFLOW);s.top=s.base;s.stacksize=STACKSIZE;return OK;}/************************************************************ 判空 ************************************************************/Status EmptyStack(Stack s){if(s.base==s.top)return 1;elsereturn 0;}/************************************************************ 压栈 ************************************************************/Status Push(Stack &s,int e){if((s.top-s.base)>s.stacksize){s.base=(SElemType*)realloc(s.base,(STACKSIZE+STACKINCREMENT)*sizeof(SElemType) );if(!s.base)return(OVERFLOW);s.top=s.base+s.stacksize;s.stacksize+=STACKINCREMENT;}*s.top++=e;return OK;}/************************************************************ 出栈 ************************************************************/Status Pop(Stack &s,int &e){e=*--s.top;return OK;}/************************************************************ 拓扑排序 ************************************************************/Status TopologicalSort(Graph G) //拓扑排序函数{int i,j,k,e;int count=0; //用来统计顶点的个数Stack S; //定义一个栈,用来保存入度为0的顶点InitStack(S); //初始化栈for(i=1;i<=G.vexnum;++i)if(G.vertices[i].indegree==0) //若第i个顶点的入度为0 ,i表示顶点在图中的位置Push(S,i); //将第i个顶点入栈while(!EmptyStack(S)){Pop(S,e); // 将为入度0的顶点位置出栈j=e;count++; //统计顶点的个数printf("%s ",G.vertices[j].data); //输出入度为0的顶点ArcNode *p;for(p=G.vertices[j].firstarc; p ;p=p->nextarc) //找与第j个顶点的邻接顶点,并将其入度减1{k=p->adjvex;--(G.vertices[k].indegree);if(G.vertices[k].indegree==0) //如果入度为0,就入栈Push(S,k);}}return OK;if(count<G.vexnum) //count小于顶点的个数时候,说明有环,不符合拓扑排序的要求{printf("\n不是有向无环图!\n");return ERROR; //退出}}主文件:#include <stdio.h>#include"malloc.h"#include "tuopupaixuhead.h"#include "stdlib.h"#include "string.h"/************************************************************ 界面控制 ************************************************************/void main(){Graph G;printf("\n################################# 拓扑排序#################################\n");printf("\n $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n"); printf("\n");CreateGraph(G);printf("各点入度分布如下:\n\n");for(int i=1;i<=G.vexnum;i++){ //输出顶点的度数printf("第%d个顶点%s的度数是%d\n",i,G.vertices[i].data,G.vertices[i].indegree ); }printf("\n\n\n");printf("有向图所有顶点的拓扑排序:\n");TopologicalSort(G);printf("\n");}[实验数据与结果]测试数据:实验结果。
拓扑排序实验报告

数学与计算机学院数据结构实验报告年级09数计学号2009432125 姓名刘宝成绩专业数电实验地点主楼401 指导教师苗秀芬实验项目拓扑排序实验日期10年12月24日一、实验目的1掌握图的存储结构及其基本操作,学会定义图的邻接表存储结构,并能在实际问题中灵活运用。
2掌握拓扑排序算法。
3、通过本实验的具体应用实例,灵活运用拓扑排序并进一步巩固队列/栈的运用。
二、实验问题描述1简介:用邻接表形式存储实验中的有向无环图,此有向无环图称为:AOV网,若网中每一个顶点都在他的拓扑排序中,则说明不存在环。
2步骤:①从AOV网中选出一个没有前驱的结点,并输出他;②从网中删除此结点,并且删除从该顶点发出的所有有向边(邻接点的入度-1)③重复以上两步,直到途中不存在入度为0的顶点为止三、实验步骤1、实验问题分析(1)顶点表typedef struct//顶点表结点{int in;//入度int vertex;//顶点域edgenode * firstedge;//边表头指针}vertexnode;(2)边表typedef struct node //边表结点{int adjvex;//邻接点域struct node * next;//指向下一个邻接点的指针域}edgenode;(3)以邻接表类型存储的图类型typedef struct{Adjlist adjlist; //邻接表int vnum,Enum; //顶点数和边数}Algraph;2、功能(函数)设计(1)建立一个以邻接表存储的有向图函数原型:void creatalgraph(Algraph *G)(2)拓扑排序函数原型:void TopoSort(Algraph *G)四、实验结果(程序)及分析1、实验主要模块代码(带注释!)或模块的流程图(1)建立一个以邻接表存储的有向图void creatalgraph(Algraph *G)//创建邻接链表{int i,k,j;edgenode *s;cout<<"该AOV网的顶点数和边数:"<<endl;cin>>G->vnum>>G->Enum; //读入顶点数和边数cout<<"请输入顶点信息:"<<endl;for(i=0;i<G->vnum;i++) //建立有vnum个顶点的顶点表{cin>>G->adjlist[i].vertex; //读入顶点信息G->adjlist[i].in=0;G->adjlist[i].firstedge=NULL; //顶点的边表头指针设为空}cout<<"请输入边的信息:"<<endl; //for(k=0;k<G->Enum;k++) //建立边表{cout<<"依次输入每一条边:"<<endl;cout<<"从";cin>>i;cout<<"邻接到";cin>>j;cout<<endl;//读入边<vi,vj>的顶点对应的序号s=new edgenode; //生成新的边表结点s->adjvex=j; //邻接点的序号为js->next=G->adjlist[i].firstedge; //将新边表结点s插入到顶点vi的边表头部G->adjlist[i].firstedge=s;}}(2)拓扑排序int toposort(Algraph *G){int i,j,k;int m=0,top;edgenode *ptr;top=-1;for(i=0;i<G->vnum;i++)if(G->adjlist[i].in==0){ G->adjlist[i].in=top;top=i;}while(top!=-1){j=top;top=G->adjlist[top].in;cout<<G->adjlist[j].vertex<<endl;m++;ptr=G->adjlist[j].firstedge;while(ptr!=NULL){k=ptr->adjvex;G->adjlist[k].in--;if(G->adjlist[k].in==0){G->adjlist[k].in=top;top=k;}ptr=ptr->next;//头插入}}if(m<G->vnum){cout<<"此图中存在环!无法进行拓扑排序"<<endl;return 0;//返回错误代码0}elsereturn 1;//成功返回1}2、测试数据3、调试过程中出现的问题以及解决策略。
拓扑排序实验报告

实验题目:图的应用实验目的:(1)熟练掌握图的基本存储方法;(2)熟练掌握图的深度优先和广度优先搜索方法;(3)掌握AOV网和拓扑排序算法;(4)掌握AOE网和关键路径。
实验内容:拓扑排序。
任意给定一个有向图,设计一个算法,对它进行拓扑排序。
拓扑排序算法思想:a.在有向图中任选一个没有前趋的顶点输出;b.从图中删除该顶点和所有以它为尾的弧;c.重复上述a、b,直到全部顶点都已输出,此时,顶点输出序列即为一个拓朴有序序列;或者直到图中没有无前趋的顶点为止,此情形表明有向图中存在环。
设计分析:为实现对无权值有向图进行拓扑排序,输出拓扑序列,先考虑如何存储这个有向图。
拓扑排序的过程中要求找到入度为0的顶点,所以要采用邻接表来存储有向图,而要得到邻接表,则先要定义有向图的邻接矩阵结构,再把邻接矩阵转化成邻接表。
在具体实现拓扑排序的函数中,根据规则,当某个顶点的入度为0(没有前驱顶点)时,就将此顶点输出,同时将该顶点的所有后继顶点的入度减1,为了避免重复检测入度为0的顶点,设立一个栈St,以存放入度为0的顶点。
源程序代码:#include<stdio.h>#include<stdlib.h>#define MAXV 10 // 最大顶点个数typedef struct{int edges[MAXV][MAXV]; // 邻接矩阵的边数组int n; // 顶点数}MGraph;typedef struct ANode{int adjvex; // 该弧的终点位置struct ANode * nextarc; // 指向下一条弧的指针}ArcNode;typedef struct{int no; // 顶点信息int count; // 顶点入度ArcNode * firstarc; // 指向第一条弧}VNode, AdjList[MAXV];typedef struct{AdjList adjlist; // 邻接表int n; // 图的顶点数}ALGraph;void MatTolist(MGraph g, ALGraph * &G){int i, j, n=g.n;ArcNode * p;G = (ALGraph *)malloc(sizeof(ALGraph));for (i=0; i<n; i++)G->adjlist[i].firstarc = NULL;for (i=0; i<n; i++)for (j=n-1; j>=0; j--)if (g.edges[i][j]!=0){p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex = j;p->nextarc = G->adjlist[i].firstarc;G->adjlist[i].firstarc = p;}G->n=n;}void TopSort(ALGraph * G){int i,j,flag=0,a[MAXV];int St[MAXV], top = -1; // 栈St的指针为topArcNode * p;for (i=0; i<G->n; i++) // 入度置初值为0 G->adjlist[i].count = 0;for (i=0; i<G->n; i++) // 求所有顶点的入度{p=G->adjlist[i].firstarc;while (p!=NULL){G->adjlist[p->adjvex].count++;p=p->nextarc;}}for (i=0; i<G->n; i++)if (G->adjlist[i].count==0) // 入度为0的顶点进栈{top++; St[top] = i;}while (top>-1) // 栈不为空时循环{i = St[top]; top--; // 出栈a[flag++]=i; // 输出顶点p=G->adjlist[i].firstarc; // 找第一个相邻顶点while (p!=NULL){j = p->adjvex;G->adjlist[j].count--;if (G->adjlist[j].count==0){top++; St[top] = j; // 入度为0的相邻顶点进栈}p = p->nextarc; // 找下一个相邻顶点}}if (flag<G->n)printf("该图存在回路,不存在拓扑序列!\n");else{printf("该图的一个拓扑序列为:");for(i=0; i<flag; i++)printf("%d", a[i]);printf("\n");}}void main(){int i, j;MGraph g;ALGraph * G;G=(ALGraph *)malloc(sizeof(ALGraph));printf("请输入图的顶点数:");scanf("%d", &g.n);printf("请输入图的邻接矩阵:\n");for(i=0; i<g.n; i++)for(j=0; j<g.n; j++)scanf("%d", &g.edges[i][j]);MatTolist(g, G);TopSort(G);} 测试用例:对图7-1所示的有向图进行拓扑排序的测试结果如下:图7-1图7-2程序执行界面,提示输入图的顶点数,输入之后又提示输入其邻接矩阵,对图7-1所示的有向图的邻接矩阵输入如图7-2所示。
拓扑排序的实现实验报告

拓扑排序的实现实验报告GDOU-B-11-112广东海洋大学学生实验报告书(学生用表)实验名称拓扑排序的实现课程名称数据结构与算法教程课程号学院(系) 数学与计算机专业软件工程班级学生姓名学号实验地点实验日期一、实验内容、目的掌握拓扑排序的原理和方法。
二、实验原理a)算法基本思想用Kahn算法。
先使用一个栈保存入度为0 的顶点,然后输出栈顶元素并且将和栈顶元素有关的边删除,减少和栈顶元素有关的顶点的入度数量并且把入度减少到0的顶点也入栈。
b)实验程序说明1.创建栈。
2.计算每个顶点的入度,保存在数组中。
3.将入度为0的顶点入栈。
4.创建循环,将栈顶元素出栈,输出拓扑序列,再创建循环,顶点入度减1,若为0则入栈。
5.判断图是否有环,若有则失败。
三、程序流程图四、实现步骤1.在有向图中选一个没有前驱的顶点并且输出2.从图中删除该顶点和所有以它为尾的弧(白话就是:删除所有和它有关的边)3.重复上述两步,直至所有顶点输出,或者当前图中不存在无前驱的顶点为止,后者代表我们的有向图是有环的,因此,也可以通过拓扑排序来判断一个图是否有环。
五、实验结果一个有向无环图,输入6 81 21 31 43 23 54 56 46 5六、操作说明需要对有向无环图分解,顶点个数,边条数,每条边的起点终点编号,然后再输入。
七、附录:代码bool Graph_DG::topological_sort() {cout << "图的拓扑序列为:" << endl;//栈s用于保存栈为空的顶点下标stack s;int i;ArcNode * temp;//计算每个顶点的入度,保存在indgree数组中for (i = 0; i != this->vexnum; i++) {temp = this->arc[i].firstarc;while (temp) {++this->indegree[temp->adjvex];temp = temp->next;}}//把入度为0的顶点入栈for (i = 0; i != this->vexnum; i++) {if (!indegree[i]) {s.push(i);}}//count用于计算输出的顶点个数int count=0;while (!s.empty()) {//如果栈为空,则结束循环i = s.top();s.pop();//保存栈顶元素,并且栈顶元素出栈cout << this->arc[i].data<<" ";//输出拓扑序列temp = this->arc[i].firstarc;while (temp) {if (!(--this->indegree[temp->adjvex])) {//如果入度减少到为0,则入栈s.push(temp->adjvex);}temp = temp->next;}++count;}if (count == this->vexnum) {cout << endl;return true;}cout << "此图有环,无拓扑序列" << endl; return false;//说明这个图有环}成绩指导教师日期注:请用A4纸书写,不够另附纸。
【数据结构算法】实验9 图的拓扑排序问题(附源代码)

浙江大学城市学院实验报告课程名称数据结构与算法实验项目名称实验九图的拓扑排序问题实验成绩指导老师(签名)日期一.实验目的和要求1.掌握拓扑排序概念。
2.理解并能实现拓扑排序算法(采用邻接表表示图)。
二. 实验内容1、编写用邻接表表示有向无权图时图的基本操作的实现函数,具体包括:①初始化用邻接表表示的有向无权图void InitAdjoin(adjlist G);②建立用邻接表表示的有向无权图void CreateAdjoin (adjlist G, int n) (即通过输入图的每条边建立图的邻接表);③输出用邻接表表示的有向无权图void PrintAdjoin (adjlist G, int n) (即输出图的每条边)。
把邻接表的结构定义及这些基本操作实现函数存放在头文件Graph3.h中。
2、编写拓扑排序算法void Toposort( adjlist G, int n) (输入为图的邻接表,输出为相应的拓扑序列)。
3、编写测试程序(即主函数),首先建立并输出有向无权图,然后进行拓扑排序。
要求:把拓扑排序函数Toposort以及主函数存放在主文件test9_3.cpp中。
测试数据如下:4、填写实验报告,实验报告文件取名为report9.doc。
5、上传实验报告文件report9.doc与源程序文件test9_3.cpp及Graph3.h到Ftp服务器上自己的文件夹下。
三. 函数的功能说明及算法思路包括每个函数的功能说明,及一些重要函数的算法实现思路【结构说明】const int MaxVertexNum =10; //图的最大顶点数const int MaxEdgeNum =100; //边数的最大值struct EdgeNode{ //链表边结点,表示弧int adjvex; //存放与头结点顶点有关的另一个顶点在邻接表(数组)中的下标。
EdgeNode *next; //指向链表下一个结点};typedef struct VNode{ //邻接表,表示顶点int data; // 顶点数据,顶点名称EdgeNode *firstarc; // 指向边结点链表第一个结点} adjlist[MaxVertexNum];【函数说明】①void InitAdjoin(adjlist G)功能:初始化用邻接表表示的有向无权图思路:将邻接表的所有顶点置为-1,边结点链表指针置为NULL②void CreateAdjoin (adjlist &G, int n)功能:建立用邻接表表示的有向无权图(即通过输入图的每条边建立图的邻接表)思路:按照输入的顶点信息,新建边结点链入邻接表中对应位置③void PrintAdjoin (adjlist G, int n)功能:输出用邻接表表示的有向无权图(即输出图的每条边)思路:按照一定的格式输出邻接表④void Toposort( adjlist G, int n)功能:输入图的邻接表,输出相应的拓扑序列思路:初始化数组d[ ],利用数组的空间建立入度为零的顶点栈并设置栈顶指针。
数据结构拓扑排序实验报告

数据结构拓扑排序实验报告一、实验目的本次实验的主要目的是深入理解和掌握数据结构中的拓扑排序算法,并通过实际编程实现来验证其有效性和应用场景。
拓扑排序在解决有向无环图(DAG)中的依赖关系问题上具有重要作用,例如任务调度、工程流程规划等。
二、实验环境本次实验使用的编程语言为 Python,开发环境为 PyCharm。
Python具有简洁易懂的语法和丰富的库函数,能够方便地实现拓扑排序算法。
三、实验原理拓扑排序是对有向无环图的顶点进行排序,使得对于图中的每条有向边(u, v),顶点 u 都在顶点 v 之前。
其基本思想是选择一个入度为0 的顶点,将其输出,并删除与其相关的边,从而更新其他顶点的入度,重复这个过程直到图中所有顶点都被输出。
实现拓扑排序的常见方法有两种:基于深度优先搜索(DFS)和基于广度优先搜索(BFS)。
四、实验步骤1、构建有向无环图的数据结构我们使用邻接表来表示有向图,其中每个顶点对应一个列表,存储其指向的顶点。
2、计算顶点的入度遍历邻接表,统计每个顶点的入度。
3、执行拓扑排序基于 BFS 的方法:创建一个队列,将入度为 0 的顶点入队。
然后不断取出队首顶点,输出,并更新与其相邻顶点的入度。
若有新的入度为 0 的顶点,则入队。
基于 DFS 的方法:使用递归函数,从一个未访问的顶点开始,访问其相邻顶点,并在回溯时输出顶点。
4、输出排序结果五、实验代码以下是基于 BFS 实现拓扑排序的 Python 代码示例:```pythonfrom collections import dequeclass Graph:def __init__(self, vertices):selfvertices = verticesselfadjacency_list = for _ in range(vertices)selfindegree = 0 verticesdef add_edge(self, source, destination):selfadjacency_listsourceappend(destination) selfindegreedestination += 1def topological_sort_bfs(self):queue = deque()for vertex in range(selfvertices):if selfindegreevertex == 0:queueappend(vertex)sorted_order =while queue:current_vertex = queuepopleft()sorted_orderappend(current_vertex)for adjacent_vertex in selfadjacency_listcurrent_vertex: selfindegreeadjacent_vertex = 1if selfindegreeadjacent_vertex == 0: queueappend(adjacent_vertex)if len(sorted_order)!= selfvertices:print("Graph contains a cycle Topological sort is not possible")else:print("Topological Sort:", sorted_order)测试示例g = Graph(6)gadd_edge(5, 2)gadd_edge(5, 0)gadd_edge(4, 0)gadd_edge(4, 1)gadd_edge(2, 3)gadd_edge(3, 1)gtopological_sort_bfs()```以下是基于 DFS 实现拓扑排序的 Python 代码示例:```pythonclass Graph:def __init__(self, vertices):selfvertices = verticesselfadjacency_list = for _ in range(vertices) selfvisited = False verticesselfstack =def add_edge(self, source, destination):selfadjacency_listsourceappend(destination) def topological_sort_dfs(self, vertex):selfvisitedvertex = Truefor adjacent_vertex in selfadjacency_listvertex: if not selfvisitedadjacent_vertex: selftopological_sort_dfs(adjacent_vertex) selfstackappend(vertex)def perform_topological_sort(self):for vertex in range(selfvertices):if not selfvisitedvertex:selftopological_sort_dfs(vertex)print("Topological Sort:", selfstack::-1)测试示例g = Graph(6)gadd_edge(5, 2)gadd_edge(5, 0)gadd_edge(4, 0)gadd_edge(4, 1)gadd_edge(2, 3)gadd_edge(3, 1)gperform_topological_sort()```六、实验结果分析1、基于 BFS 的方法对于上述测试示例,输出的拓扑排序结果为 4, 5, 0, 2, 3, 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. 结果分析可以看出,根据有向图的依赖关系,拓扑排序算法能够将顶点按照合理的顺序进行排序。
拓扑排序的结果可以作为图中顶点的执行顺序,具有重要的应用价值。
五、实验总结通过本次实验,我们深入学习了拓扑排序算法,并成功实现了拓扑排序的过程。
拓扑排序在图论和数据结构中具有广泛的应用,对于理解和解决与图相关的问题具有重要意义。
六、附件本文档没有涉及附件内容。
七、法律名词及注释本文档没有涉及法律名词及注释。
拓扑排序课程设计报告

沈阳航空航天大学课程设计报告课程设计名称:数据结构课程设计课程设计题目:拓扑排序算法院(系):计算机学院专业:计算机科学与技术(嵌入式系统方向)班级: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. 将图以合适的方式存储起来。
图有多种存储方式,其中最常用的存储方式有图的邻接矩阵和邻接表。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
拓扑排序[基本要求] 用邻接表建立一个有向图的存储结构。
利用拓扑排序算法输出该图的拓扑排序序列。
[编程思路]首先图的创建,采用邻接表建立,逆向插入到单链表中,特别注意有向是不需要对称插入结点,且要把输入的字符在顶点数组中定位(LocateVex(Graph G,char *name),以便后来的遍历操作,几乎和图的创建一样,图的顶点定义时加入int indegree,关键在于indegree 的计算,而最好的就是在创建的时候就算出入度,(没有采用书上的indegree【】数组的方法,那样会增加一个indegree算法,而是在创建的时候假如一句计数的代码(G.vertices[j].indegree)++;)最后调用拓扑排序的算法,得出拓扑序列。
[程序代码]头文件:#define MAX_VERTEX_NUM 30#define STACKSIZE 30#define STACKINCREMENT 10#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2#define TRUE 1#define FALSE 0typedef int Status;typedef int InfoType;typedef int Status;typedef int SElemType;/* 定义弧的结构*/typedef struct ArcNode{int adjvex; /*该边所指向的顶点的位置*/struct ArcNode *nextarc; /*指向下一条边的指针*/InfoType info; /*该弧相关信息的指针*/}ArcNode;/*定义顶点的结构*/typedef struct VNode{int indegree;char data[10]; /*顶点信息*/ArcNode *firstarc; /*指向第一条依附该顶点的弧的指针*/ }VNode,AdjList[MAX_VERTEX_NUM];/*定义图的结构*/typedef struct {AdjList vertices;int vexnum,arcnum; /*图的当前顶点数和弧数*/int kind; /*图的类型标志*/}Graph;/*定义栈的结构*/typedef struct{SElemType *base;SElemType *top;int stacksize;}Stack;/*顶点定位*/int LocateVex(Graph G,char *name);/*创建有向图*/void CreateGraph(Graph &G);/*拓扑排序*/StatusTopologicalSort(Graph G);/*初始化栈*/Status InitStack(Stack &s) ;/*判断空*/Status EmptyStack(Stack s);/*压栈*/Status Push(Stack &s,int e);/*出栈*/Status Pop(Stack &s,int &e);实现文件:#include <stdio.h>#include"malloc.h"#include "tuopupaixuhead.h"#include "stdlib.h"#include "string.h"bool visited[MAX_VERTEX_NUM];/*********************************************************** * 顶点定位,返回位序* ***********************************************************/ int LocateVex(Graph G,char *name){int i;for(i=1;i<=G.vexnum;i++)if(strcmp(name,G.vertices[i].data)==0) //返回数组的位置return i;return -1;}/************************************************************ 创建有向图************************************************************/void CreateGraph(Graph &G){ArcNode *p;char name1[10],name2[10];int i,j,k;printf(" 请输入顶点数,按回车键结束:");scanf("%d",&G.vexnum);printf(" 请输入弧数,按回车键结束:");scanf("%d",&G.arcnum);printf(" 请依次输入顶点名(用空格分开且字符小于10),按回车键结束:\n");printf(" ");for(i=1;i<=G.vexnum;i++) //初始化{scanf("%s",G.vertices[i].data);G.vertices[i].firstarc=NULL;G.vertices[i].indegree=0; //度数均初始化为0}printf("\n\n\n\n");printf(" ………………………………………输入小提示………………………………………\n");printf(" &&&&1 为避免输入遗漏,最好从选择任意一点,输入所有相邻边\n");printf(" &&&&2 输入边时格式(用空格分开,即格式为顶点(空格)顶点(空格))\n");printf(" ………………………………………输入小提示………………………………………\n\n\n\n");for(k=0;k<G.arcnum;k++){printf(" 请输入相邻的两个顶点,按回车键结束:");scanf("%s%s",name1,name2);i=LocateVex(G,name1);j=LocateVex(G,name2);(G.vertices[j].indegree)++; //每次作为弧的邻接点,则度数加1p=(ArcNode *)malloc(sizeof(ArcNode)); //申请边节点p->adjvex=j; //插入到邻接表中,注意此处为逆向插入到单链表中p->nextarc=G.vertices[i].firstarc;G.vertices[i].firstarc=p;}}/************************************************************ 初始化栈************************************************************/Status InitStack(Stack &s) //创建一个空栈{s.base=(int*)malloc(STACKSIZE*sizeof(int));if(!s.base)return (OVERFLOW);s.top=s.base;s.stacksize=STACKSIZE;return OK;}/************************************************************ 判空************************************************************/Status EmptyStack(Stack s){if(s.base==s.top)return 1;elsereturn 0;}/************************************************************ 压栈************************************************************/Status Push(Stack &s,int e){if((s.top-s.base)>s.stacksize){s.base=(SElemType*)realloc(s.base,(STACKSIZE+STACKINCREMENT)*sizeof(SElemTyp e));if(!s.base)return(OVERFLOW);s.top=s.base+s.stacksize;s.stacksize+=STACKINCREMENT;}*s.top++=e;return OK;}/************************************************************ 出栈************************************************************/Status Pop(Stack &s,int &e){e=*--s.top;return OK;}/************************************************************ 拓扑排序************************************************************/Status TopologicalSort(Graph G) //拓扑排序函数{int i,j,k,e;int count=0; //用来统计顶点的个数Stack S; //定义一个栈,用来保存入度为0的顶点InitStack(S); //初始化栈for(i=1;i<=G.vexnum;++i)if(G.vertices[i].indegree==0) //若第i个顶点的入度为0 ,i表示顶点在图中的位置Push(S,i); //将第i个顶点入栈while(!EmptyStack(S)){Pop(S,e); // 将为入度0的顶点位置出栈j=e;count++; //统计顶点的个数printf("%s ",G.vertices[j].data); //输出入度为0的顶点ArcNode *p;for(p=G.vertices[j].firstarc; p ;p=p->nextarc) //找与第j个顶点的邻接顶点,并将其入度减1 {k=p->adjvex;--(G.vertices[k].indegree);if(G.vertices[k].indegree==0) //如果入度为0,就入栈Push(S,k);}}return OK;if(count<G.vexnum) //count小于顶点的个数时候,说明有环,不符合拓扑排序的要求{printf("\n不是有向无环图!\n");return ERROR; //退出}}主文件:#include <stdio.h>#include"malloc.h"#include "tuopupaixuhead.h"#include "stdlib.h"#include "string.h"/************************************************************ 界面控制************************************************************/void main(){Graph G;printf("\n################################# 拓扑排序#################################\n");printf("\n $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");printf("\n");CreateGraph(G);printf("各点入度分布如下:\n\n");for(int i=1;i<=G.vexnum;i++){ //输出顶点的度数printf("第%d个顶点%s的度数是%d\n",i,G.vertices[i].data,G.vertices[i].indegree ); } printf("\n\n\n");printf("有向图所有顶点的拓扑排序:\n");TopologicalSort(G);printf("\n");}[实验数据与结果]测试数据:实验结果。