ImageVerifierCode 换一换
格式:DOCX , 页数:16 ,大小:97.82KB ,
资源ID:9851173      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/9851173.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(拓扑排序.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

拓扑排序.docx

1、拓扑排序数据结构课程设计 -拓扑排序一 需求分析1.问题描述 本次课程设计题目是:用邻接表构造图 然后进行拓扑排序,输出拓扑排序序列拓扑排序的基本思想为: 1).从有向图中选一个无前驱的顶点输出; 2).将此顶点和以它为起点的弧删除; 3). 重复1),2)直到不存在无前驱的顶点; 4). 若此时输出的顶点数小于有向图中的顶点数,则说明有向图中存在回路,否则输出的顶点的顺序即为一个拓扑序列。 2.基于邻接表的存储结构 入度为零的顶点即为没有前驱的顶点, 我们可以附设一个存放各顶点入度的数组indegree ,于是有(1)找G中无前驱的顶点查找indegreei为零的顶点vi;(2)删除以i为起

2、点的所有弧对链在顶点i后面的所有邻接顶点k,将对应的indegreek 减1。 为了避免重复检测入度为零的顶点,可以再设置一个辅助栈,若某一顶点的入度减为0,则将它入栈。每当输出某一入度为0的顶点时,便将它从栈中删除。 3基本要求(1)输入的形式和输入值的范围; 首先是输入要排序的顶点数和弧数,都为整型,中间用分隔符隔开;再输入各顶点的值,为正型,中间用分隔符隔开;然后输入各条弧的两个顶点值,先输入弧头,再输入弧尾,中间用分隔符隔开,输入的值只能是开始输入的顶点值否则系统会提示输入的值的顶点值不正确,请重新输入,只要继续输入正确的值就行。(2)输出的形式; 首先输出建立的邻接表,然后是最终各顶

3、点的出度数,再是拓扑排序的序列,并且每输出一个顶点,就会输出一次各顶点的入度数。(3) 程序所能达到的功能; 因为该程序是求拓扑排序,所以算法的功能就是要输出拓扑排序的序列,在一个有向图中,若用顶点表示活动,有向边就表示活动间先后顺序,那么输出的拓扑序列就表示各顶点间的关系为反映出各点的存储结构,以邻接表存储并输出各顶点的入度。二 概要设计1. 算法中用到的所有各种数据类型的定义在该程序中用邻接表作为图的存储结构。首先,定义表结点和头结点的结构类型,然后定义图的结构类型。创建图用邻接表存储的函数,其中根据要求输入图的顶点和边数,并根据要求设定每条边的起始位置,构建邻接表依次将顶点插入到邻接表中

4、。拓扑排序的函数在该函数中首先要对各顶点求入度,其中要用到求入度的函数,为了避免重复检测入度为零的顶点,设置一个辅助栈,因此要定义顺序栈类型,以及栈的函数:入栈,出栈,判断栈是否为空。2.各程序模块之间的层次调用关系 第一部分,void CreatGraph(ALGraph *G)函数构建图,用邻接表存储。这个函数没有调用函数。 第二部分,void TopologicalSort(ALGraph *G)输出拓扑排序函数,这个函数首先调用FindInDegree(G,indegree)对各顶点求入度indegree0vernum-1;然后设置了一个辅助栈,调用InitStack(&S)初始化栈,

5、在调用Push(&S,i)入度为0者进栈,while(!StackEmpty(&S)栈不为空时,调用Pop(&sS,&n)输出栈中顶点并将以该顶点为起点的边删除,入度indegreek-,当输出某一入度为0的顶点时,便将它从栈中删除。 第三部分,主函数,先后调用void CreatGraph(ALGraph *G)函数构建图、void TopologicalSort(ALGraph *G)函数输出拓扑排序实现整个程序。3.设计的主程序流程(见附页)三 详细设计 (实现概要设计中定义的所有数据类型,对每个操作写出伪码算法;对主程序和其他模块也都需要写出伪码算法(伪码算法达到的详细程度建议为;按照

6、伪码算法可以在计算机键盘直接输入高级程序设计语言程序);写出出函数和过程的调用关系。)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

7、ArcNodeint adjvex; /该弧所指向的顶点的位置/ struct ArcNode *nextarc; /指向下一条弧的指针/ArcNode; /*表结点*/typedef struct VNodechar data; /顶点信息 ArcNode *firstarc; /指向第一条依附该顶点的弧的指针/VNode,AdjListMAX_VEXTEX_NUM;typedef structAdjList vertices; int vexnum, arcnum; /图的当前顶点数和弧数/ALGraph;typedef struct /构建栈/ElemType *base;/*在栈构造之

8、前的指针*/ ElemType *top;/*栈顶指针*/int stacksize;/*定义所分配的存储空间*/SqStack;/*顺序栈*/2.算法和各模块的代码程序中各函数算法思想如下:2.1 void InitStack(SqStack *S) 初始化栈将栈的空间设为 STACK-INIT-SIZE。2.2 int Pop(SqStack *S,ElemType *e)出栈操作,若站不空,删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR。2.3 void Push(SqStack *S,ElemType e) 进栈操作,插入元素e为新的栈顶元素。2.4 int Stack

9、Empty(SqStack *S) 判断栈是否为空,语句if (S-top=S-base )判断,若栈不为空,则删除S的栈顶元素,并返回OK;否则返回ERROR。2.5 void CreatGraph (ALGraph *G) 构建图,用邻接表存储,首先定义邻接表指针变量,输入顶点数和弧数,初始化邻接表,将表头向量域置空,输入存在弧的点集合,当输入顶点值超出输入值的范围就会出错,否则依次插入进邻接表,最后输出建立好的邻接表。2.6 void FindInDegree(ALGrap G, int indegreee)求入度操作,设一个存放各顶点入度的数组indegreee,然后indegreee

10、i=0赋初值,for循环indegreee+,存储入度数。2.7 void TopologicalISort(ALGraph G)输出拓扑排序函数。其思路是若G无回路,则输出G的顶点的一个拓扑序列并返回OK,否则返回ERROR。首先由于邻接表的存储结构入度为零的顶点即为没有前驱的顶点,我们可以附设一个存放个顶点入度的数组,调用FindInDegree( G, indegreee)对各顶点求入度;为了避免重复检测入度为零0的顶点,设置一个栈,调用InitStack(&S)初始化栈,在调用Push(&S,i)入度为0者进栈,while(!StackEmpty(&S)栈不为空时,调用Pop(&sS,

11、&n)输出栈中顶点并将以该顶点为起点的边删除,入度indegreek-,当输出某一入度为0的顶点时,便将它从栈中删除。3.算法的时间复杂度和空间复杂度 拓扑排序实际是对邻接表表示的图G进行遍历的过程,每次访问一个入度为零的顶点,若图G中没有回路,则需扫描邻接表中的所有边结点,在算法开始时,为建立入度数组D需访问表头向量中的所有边结点,算法的时间复杂度为O(n+e)。四 测试与分析对有向无环图【下图】进行拓扑排序。输入:结果如下:五 总结拓扑排序就是对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和

12、v,若 E(G),则u在线性序列中出现在v之前。在进行课程设计中,更好的认识了拓扑排序。理清了各个模块之间算法之间的条理。认识了伪代码(Pseudocode)是一种算法描述语言。使用伪代码的目的是为了使被描述的算法可以容易地以任何一种编程语言(Pascal,C,Java,etc)实现。因此,伪代码必须结构清晰、代码简单、可读性好,并且类似自然语言。 介于自然语言与编程语言之间。它是一种让人便于理解的代码。不依赖于语言的,用来表示程序执行过程,而不一定能编译运行的代码。在数据结构讲算法的时候用的很多。在设计中,我们遇到了程序正确,却对某些无向图无法进行拓扑排序的问题。多次对程序进行修改后,才可以

13、进行拓扑排序。问题出在调用函数的错误理解,模块之间的联系模糊不清。 六附录:源程序清单#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

14、; /*该弧所指向的顶点的位置*/ struct ArcNode *nextarc; /*指向下一条弧的指针*/ArcNode; /*表结点*/typedef struct VNode char data; /*顶点信息*/ ArcNode *firstarc; /*指向第一条依附该顶点的弧的指针*/VNode,AdjListMAX_VEXTEX_NUM;typedef struct AdjList vertices; int vexnum, arcnum; /*图的当前顶点数和弧数*/ALGraph;typedef struct /*构建栈*/ ElemType *base;/*在栈构造之前

15、的指针*/ ElemType *top;/*栈顶指针*/int stacksize;/*定义所分配的存储空间*/SqStack;/*顺序栈*/void InitStack(SqStack *); /*函数声明*/int Pop(SqStack *, ElemType &);void Push(SqStack *,ElemType );int StackEmpty(SqStack *);void CreatGraph(ALGraph *);void FindInDegree(ALGraph , int * );void TopologicalSort(ALGraph );void InitSta

16、ck(SqStack *S) /*初始化栈*/ S-base=(ElemType *)malloc(STACK_INIT_SIZE*sizeof(ElemType); /*申请新的结点并由s-base指向*/ if(!S-base) /*存储分配失败*/ printf(memory allocation failed, goodbye); exit(1); S-top=S-base; /*空栈之前的指针赋给头指针*/ S-stacksize=STACK_INIT_SIZE; /*栈的空间设为Stack_init_size*/int Pop(SqStack *S,ElemType &e) /*出

17、栈操作*/ if(S-top=S-base) /*栈空返回OK*/ return ERROR; /*删除S的栈顶元素*/ e=*-S-top; return 0;void Push(SqStack *S,ElemType e) /*进栈操作,插入元素e为新的栈顶元素*/ if(S-top-S-base=S-stacksize) S-base=(ElemType*)realloc(S-base,(S-stacksize+STACKINCREMENT)*sizeof(ElemType); if(!S-base) /*存储分配失败*/ printf(memory allocation failed,

18、 goodbye); exit(1); S-top = S-base+S-stacksize; S-stacksize+=STACKINCREMENT; *S-top+=e;int StackEmpty(SqStack *S) /*判断栈是否为空*/if(S-top=S-base) /*栈不为空,则删除S的栈顶元素,并返回OK;否则返回*/ return OK; else return ERROR;int locatevex(ALGraph G,char u) /*若G图中存在顶点u,则返回该顶点在图中的位置;否则返回-2.*/ int i; for(i=0;ivexnum,&G-arcnum

19、);printf(输入顶点的值(用空格隔开):n);for(i=0;ivexnum;i+) /*构造表头向量*/ scanf(%s,&G-verticesi.data); /*输入顶点的值*/ G-verticesi.firstarc=NULL; /*初始化指针*/ for(k=0;karcnum;k+) char v1,v2; int i,j;loop: printf(输入一条弧的起点和终点(用空格隔开):n); scanf(%s %s,&v1,&v2); i=locatevex(*G,v1); /*确定v1,v2在G中的位置*/ j=locatevex(*G,v2); if(i=-2|j=

20、-2) printf(输入有误!); break; goto loop; ArcNode *p; p = (ArcNode*)malloc(sizeof(ArcNode); if (p = NULL) printf(memory allocation failed,goodbey); exit(1); p-adjvex=j; /*对弧结点赋值*/ p-nextarc=G-verticesi.firstarc; G-verticesi.firstarc=p; /*插入到表头向量后面*/ ArcNode *p; /*定义邻接表指针变量*/ p = (ArcNode*)malloc(sizeof(A

21、rcNode); if (p = NULL) printf(memory allocation failed,goodbey); exit(1); printf(建立的邻接表为:n); /*输出建立好的邻接表*/ for(i = 0; i vexnum; i+) printf(%c,G-verticesi.data); for(p = G-verticesi.firstarc; p; p = p-nextarc) printf(%3d,p-adjvex); printf(n); void FindInDegree(ALGraph G, int indegree) /*求入度操作*/ int i

22、; for (i = 0; i G.vexnum; i+) indegreei = 0; for (i = 0; i adjvex+; G.verticesi.firstarc = G.verticesi.firstarc-nextarc; void TopologicalSort(ALGraph G) /*输出拓扑排序函数。若G无回路,则输出G的顶点的一个拓扑序列并返回OK,否则返回ERROR*/ int indegreeM; int i, k,j; char n; int count = 0; ArcNode *p; SqStack S; FindInDegree(G, indegree)

23、; /*对各顶点求入度indegree0.vernum-1*/ InitStack(&S); /*初始化栈*/ for (i = 0; i G.vexnum; i+) printf(结点%c的入度为%d n, G.verticesi.data, indegreei); printf(n); for ( i = 0; i nextarc) k = p-adjvex; if (!(-indegreek) Push(&S,G.verticesk.data); printf(n); if (count G.vexnum) printf(该图有环,出现错误,无法排序.n); else printf(排序成功n); main() /*主函数*/printf(*建立有向图的拓扑排序,请按如下要求进行输入* n); ALGraph G; /*定义一个图的变量*/CreatGraph(&G); /*调用建图函数*/TopologicalSort(G); /*调用拓扑排序函数*/return 0; 附流程图:

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1