数据结构课程设计:拓扑排序和关键路径
数据结构的应用的拓扑排序与关键路径算法

数据结构的应用的拓扑排序与关键路径算法拓扑排序与关键路径算法是数据结构中重要的应用之一。
拓扑排序通过对有向图的节点进行排序,使得对于任意一条有向边(u,v),节点 u 在排序中都出现在节点 v 之前。
关键路径算法则是用来确定一个项目的关键活动和最短完成时间。
拓扑排序的实现可以通过深度优先搜索或者广度优先搜索来完成。
深度优先搜索是递归地访问节点的所有未访问过的邻居节点,直到没有未访问过的邻居节点为止,然后将该节点添加到拓扑排序的结果中。
广度优先搜索则是通过使用队列来实现的,将节点的邻居节点逐个入队并进行访问,直到队列为空为止。
无论使用哪种方法,拓扑排序都可以通过判断节点的入度来进行。
拓扑排序在很多实际问题中都有广泛应用。
比如在任务调度中,拓扑排序可以用来确定任务间的依赖关系和执行顺序;在编译原理中,拓扑排序可以用来确定程序中变量的定义和使用顺序。
关键路径算法用于确定项目中的关键活动和最短完成时间。
它通过计算每个活动的最早开始时间和最晚开始时间,以及每个活动的最早完成时间和最晚完成时间来实现。
具体步骤如下:1. 构建有向加权图,其中节点表示项目的活动,有向边表示活动间的先后关系,边的权重表示活动的持续时间。
2. 进行拓扑排序,确定活动的执行顺序。
3. 计算每个活动的最早开始时间,即从起始节点到该节点的最长路径。
4. 计算每个活动的最晚开始时间,即从终止节点到该节点的最长路径。
5. 根据每个活动的最早开始时间和最晚开始时间,可以确定关键活动,即最早开始时间与最晚开始时间相等的活动。
6. 计算整个项目的最短完成时间,即从起始节点到终止节点的最长路径。
拓扑排序与关键路径算法在工程管理、任务调度、生产流程优化等领域都有重要应用。
它们能够帮助我们有效地组织和管理复杂的项目,提高工作效率和资源利用率。
在实际应用中,我们可以借助计算机编程以及各种图算法库来实现这些算法,从而更快速、准确地解决实际问题。
综上所述,拓扑排序与关键路径算法是数据结构的重要应用之一。
数据结构课程设计

前一部分为郝斌视频简单记录,后一部分为ppt内容,郝斌讲过的后面ppt中不再重复int * pArr = (int *)malloc(sizeof(int) * len);不同的存储结构算法也不同泛型模块一:线性结构连续存储【数组】程序Arr 视频12,13 (首地址长度有效值的个数)优点存取速度快缺点插入删除元素很慢空间通常是有限制的需要大块连续的内存事先必须知道数组的长度离散存储【链表】1.定义n个节点离散分配/ 彼此通过指针相连/ 每个节点只有一个前驱节点只有一个后续节点,首节点没有前驱节点,尾节点没有后续节点首节点(第一个有效节点)尾节点头结点(数据类型和首节点相同,第一个有效节点之前的节点,不存放有效数据,为了方便对链表的操作)头指针(指向头节点的指针变量)尾指针确定一个链表需要几个参数:只需要一个参数即头指针通过头指针可以推算出链表其他的所有信息(头结点可能占太多内存)Node 节点的生成节点的数据类型如何表示typedef struct Node{int data;//数据域struct Node * pNext;//指针域和结构体本身的类型相同}NODE, *PNODE;//NODE等价于struct Node ,PNODE等价于struct Node *2.分类单链表双链表每一个节点有两个指针域循环链表能通过任何一个节点能找到其他所有的节点非循环链表3.算法# include <stdio.h># include <malloc.h># include <stdlib.h>typedef struct Node{int data;struct Node * pNext;}NODE, *PNODE;//函数声明PNODE creat_list(void);void traverse_list(PNODE pHead);int main(void){PNODE pHead = NULL;pHead = creat_list();//creat_list() 功能:创建一个非循环单链表,并将该链表的首地址赋给pHeadtraverse_list(pHead);return 0;}PNODE creat_list(void){int len;int i;int val;//分配了一个不存放有效数据的头结点PNODE pHead = (PNODE)malloc(sizeof(NODE));if (NULL == pHead){printf("分配失败,退出程序!\n");exit(-1);}PNODE pTail = pHead;pTail->pNext = NULL;printf("请输入节点的个数: len = ");scanf("%d", &len);for (i=0; i<len; i++){printf("请输入第%d个节点的值:", i+1);scanf("%d", &val);PNODE pNew = (PNODE)malloc(sizeof(NODE));if (NULL == pNew){printf("分配失败,退出程序!\n");exit(-1);}pNew->data = val;pTail->pNext = pNew;//把每个新生成的节点挂到尾节点pTail上pNew->pNext = NULL;pTail = pNew;}return pHead;}void traverse_list(PNODE pHead){PNODE p = pHead->pNext;while (NULL != p){printf("%d ", p->data);p = p->pNext;}printf("\n");return;}遍历查找清空销毁求长度排序删除节点r = p->pnext;p->pnext = p->pnext->pnext;free(r); 注意不能直接free(p->pnext)否则第二个节点丢失,链会断开插入节点(头结点后面插入p所指向的那个节点)p->next = head->next;head->next = p;算法:狭义的算法是与数据的存储方式密切相关广义的算法是与数据的存储方式无关泛型:利用某种技术达到的效果就是:不同的存储方式,执行的操作是一样的即同一种逻辑结构,无论该逻辑结构物理存储是什么样子的我们都可以对它执行相同的操作可以利用c++中函数重载,来定义函数使其完成不同数据类型的操作的处理,即:++(){p = p->pNext; //链表,区别于数组可以直接进行++运算,但此时他们的操作是}4.优缺点优点没有空间限制插入删除元素很快缺点存取速度很慢,需进行遍历才能找到栈和队列是两种常用的数据类型线性结构两种常见的应用之一栈stack定义一种可以实现“先进后出”的存储结构Top Bottom/Base指针由栈顶元素指向栈底元素分类静态栈以数组为内核动态栈以链表为内核,相当于一个操作受限的链表算法出栈压栈应用函数调用中断表达式求值-----计算器,课本程序内存分配缓冲处理迷宫静态内存栈程序自动分配压栈出栈的方式分配内存都是分配内存的方式动态内存堆如malloc 程序员申请的堆排序的方式分配内存课本讲解的两个应用1数制转换2表达式求值(需要操作数栈和运算符栈(栈底为#))前缀式的运算规则为:运算符在式中出现的顺序恰为表达式的运算顺序;连续出现的两个操作数和在它们之前且紧靠它们的运算符构一个最小表达式;后缀式的运算规则为:运算符在式中出现的顺序恰为表达式的运算顺序;每个运算符和在它之前出现且紧靠它的两个操作数构成一个最小表达式。
课设题目

数据结构课程设计题目1.八皇后问题设计要求:在棋盘上摆放八个皇后,使任意两个不在同一行,同一列,及同一对斜线上。
皇后的摆位任意,由用户设定,程序给出剩余皇后的摆位。
2.哈夫曼编/译码器;设计要求:针对字符集A及其各字符的频率值(可统计获得)给出其中给字符哈夫曼编码,并针对一段文本(定义在A上)进行编码和译码,实现一个哈夫曼编码/译码系统。
3.关键路径设计要求:对于任何大型工程项目(由若干小工程组成),求其关键路径。
4.最小生成树问题设计要求:在n个城市之间建设网络,只需保证连通即可,求最经济的架设方法。
5.最短路径问题设计要求:对给定有向图,设计图的存储结构,求出各顶点之间最短路径。
5.校园导航问题设计要求:设计你的学校的平面图,至少包括10个以上的场所,每两个场所间可以有不同的路,且路长也可能不同,找出从任意场所到达另一场所的最佳路径(最短路径)。
6.一元多项式的代数运算设计要求:计算任意两个一元多项式的加法、减法以及乘法。
7.算术表达式求值设计要求:将任意一个算术表达式转化为逆波兰表示,并根据逆波兰表示计算表达是的值。
8、运动会分数统计任务:参加运动会有n个学校,学校编号为1……n。
比赛分成m个男子项目,和w个女子项目。
项目编号为男子1……m,女子m+1……m+w。
不同的项目取前五名或前三名积分;取前五名的积分分别为:7、5、3、2、1,前三名的积分分别为:5、3、2;哪些取前五名或前三名由学生自己设定。
(m<=20,n<=20)要求:1).可以输入各个项目的前三名或前五名的成绩;2).能统计各学校总分,3).可以按学校编号、学校总分、男女团体总分排序输出;4).可以按学校编号查询学校某个项目的情况;可以按项目编号查询取得前三或前五名的学校。
9、订票系统任务:通过此系统可以实现如下功能:录入:可以录入航班情况查询:可以查询某个航线的情况(如,输入航班号,查询起降时间,起飞抵达城市,航班票价,票价折扣,确定航班是否满仓);可以输入起飞抵达城市,查询飞机航班情况;订票:(订票情况可以存在一个数据文件中,结构自己设定)可以订票,如果该航班已经无票,可以提供相关可选择航班;退票:可退票,退票后修改相关数据文件;客户资料有姓名,证件号,订票数量及航班情况,订单要有编号。
信息学奥赛一本通 第4章 第7节 拓扑排序与关键路径(C++版)

拓扑排序算法
【参考程序】 //gentree #include<cstdio> #include<iostream> using namespace std; int a[101][101],c[101],r[101],ans[101]; int i,j,tot,temp,num,n,m; int main() { freopen("gentree.in","r",stdin); freopen("gentree.out","w",stdout); cin >> n; for (i = 1; i <= n; i++) { do { cin >> j; if (j !=0 ) { c[i]++; //c[i]用来存点i的出度 a[i][c[i]] = j; r[j]++; //r[i]用来存点i的入度。 } } while (j != 0); }
拓扑排序算法
【数据规模】 80%的数据满足n<=1000,m<=2000;100%的数据满足n<=10000,m<=20000。 【算法分析】 首先构图,若存在条件“a的钱比b多”则从b引一条有向指向a;然后拓扑排序, 若无法完成排序则表示问题无解(存在圈);若可以得到完整的拓扑序列,则按序 列顺序进行递推: 设f[i]表示第i个人能拿的最少奖金数; 首先所有f[i]=100(题目中给定的最小值); 然后按照拓扑顺序考察每个点i,若存在有向边(j,i),则表示f[i]必须比f[j] 大,因此我们令f[i] = Max { f[i] , f[j]+1 }即可; 递推完成之后所有f[i]的值也就确定了,而答案就等于f[1]+…+f[n]。
拓扑排序及关键路径

2.有向图在实际问题中的应用 一个有向图可以表示一个施工流程图,或产品生产流程
图,或数据流图等。设图中每一条有向边表示两个子工程之 间的先后次序关系。
若以有向图中的顶点来表示活动,以有向边来表示活动 之间的先后次序关系,则这样的有向图称为顶点表示活动的 网 (Activity On Vertex Network),简称AOV网。
这样,每个活动允许的时间余量就是l(i) - e(i)。而关键活动 就是l(i) - e(i) = 0的那些活动,即可能的最早开始时间e(i)等于 允许的最晚开始时间l(i)的那些活动就是关键活动。
4.寻找关键活动的算法 求AOE网中关键活动的算法步骤为: (1)建立包含n+1个顶点、e条有向边的AOE网。其中,顶
(4)从汇点vn开始,令汇点vn的最晚发生时间vl[n]=ve[n], 按逆拓扑序列求其余各顶点k(k=n-1,n-2,…,2,1,0)的最晚发生 时间vl[k];
(5)计算每个活动的最早开始时间e[k] (k=1,2,3,…,e); (6)计算每个活动的最晚开始时间l[k] (k=1,2,3,…,e); (7)找出所有e[k]= l[k]的活动k,这些活动即为AOE网的 关键活动。
上述算法仅能得到有向图的一个拓扑序列。改进上述 算法,可以得到有向图的所有拓扑序列。
如果一个有向图存在一个拓扑序列,通常表示该有向 图对应的某个施工流程图的一种施工方案切实可行;而 如果一个有向图不存在一个拓扑序列,则说明该有向图 对应的某个施工流程图存在设计问题,不存在切实可行 的任何一种施工方案。
事件可能的最早开始时间υe(k):对于顶点υk代表的事件, υe(k)是从源点到该顶点的最大路径长度。在一个有n+1个事 件的AOE网中, 源点υ0的最早开始时间υe(0)等于0。事件υk (k=1,2,3,…,n)可能的最早开始时间υe(k)可用递推公式表 示为:
数据结构关键路径

数据结构关键路径 如果在有向⽆环图中⽤有向边表⽰⼀个⼯程中的各项活动(Activity),⽤有向边上的权值表⽰活动的持续时间(duration),⽤顶点表⽰事件(Event),则这种有向图叫做⽤边表⽰活动的⽹络(activity on edges),简称AOE⽹络。
例如: 其中,E i表⽰事件,a k表⽰活动。
E0是源点,E8是汇点。
完成整个⼯程所需的时间等于从源点到汇点的最长路径长度,即该路径中所有活动的持续时间之和最⼤。
这条路径称为关键路径(critical path)。
关键路径上所有活动都是关键活动。
所谓关键活动(critical activity),是不按期完成会影响整个⼯程进度的活动。
只要找到关键活动,就可以找到关键路径。
与计算关键活动有关的量: 1 事件E i的最早可能开始时间:Ee[i]—从源点E0到顶点E i的最长路径长度。
在上图中,Ee[4]=7。
2 事件E i的最迟允许开始时间:El(⼩写L)[i]—在保证汇点E n-1最迟允许开始时间El[n-1]等于整个⼯程所需时间的前提下,等于El[n-1]减去从E i到E n-1的最长路径长度。
3 活动a k的最早可能开始时间:e[k]—设该活动在有向边<E i,E j>上,从源点E0到顶点E i的最长路径长度,即等于Ee[i]。
4 活动a k的最迟允许开始时间:l(⼩写L)[k]—设该活动在有向边<E i,E j>上,在不会引起时间延误的前提下,允许的最迟开始时间。
l[k]=El[j]-dur(<E i,E j>),其中dur(<E i,E j>)是完成该活动所需的时间,即有向边<E i,E j>的权值。
l[k]-e[k]表⽰活动a k的最早可能开始时间和最迟允许开始时间的时间余量,也叫做松弛时间(slack time)。
没有时间余量的活动是关键活动。
算法步骤: 1 输⼊顶点数和边数,再输⼊每条边的起点编号、终点编号和权值。
《数据结构》教案.

教学内容纲要: 第7章 图 7.1 图的定义和术语 (1)图 (2)无向图: (3)有向图:(4)完全图: 7.2 图的存储结构 (1)邻接矩阵 (2)邻接表
1
课程名称:数据结构
总课序
授课 时间
课型 (教法)
多媒体讲授
课题
任课教师 撰写(修改) 讲课内容
7.2.3 — 7.3
《数据结构》教案
广西民族大学数学与计算机学院
课程名称:数据结构
总课序
授课 时间
课型 (教法)
多媒体讲授
课题教具 准备教学 的掌握图的基本概念 掌握图的存储结构
任课教师 撰写(修改) 讲课内容
7.1—7.2.2
图的基本概念、存储结构
教学 重点
教学 难点 与关键
基本概念 图的邻接矩阵存储和邻接表存储
1.拓扑排序 2.关键路径、 7.6 最短路径
4
图的存储结构及遍历
教具 准备
教学 目的
掌握图的遍历 理解图的十字链表和邻接多重表存储结构:
教学 重点
图的深度优先遍历和广度优先遍历
教学 难点 与关键
图的深度优先遍历和广度优先遍历
教学内容纲要: 第7章 图 7.2 图的存储结构 3.十字链表 4.邻接多重表
7.3 图的遍历 1.深度优先遍历 2.广度优先遍历
2
课程名称:数据结构
总课序
授课 时间
课型 (教法)
多媒体讲授
任课教师 撰写(修改) 讲课内容
7.3 —7.4.3
课题
图的生成树、最小生成树
教具 准备
教学 目的
掌握生成树、最小生成树的相关问题
教学 重点
最小生成树的生成
数据结构-chap7 (4)AOV网与拓扑排序

}//for }//while if (count<G.vexnum) return ERROR; //该有向图有回路 else return OK; }//TopologicalSort
自测题2 AOV-网的拓扑排序
v2 v1 v3 v4 v5 v6 v1 v2
1
3 0 1 0 3 S.top S.base
5 4
1
2 3
3
2 1 4 0 2
C2
1
0
5 0
1
4
5
C3
C4
C5
C3 0 C4
5 0
C5 0
while(! StackEmpty(S)){ Pop(S, i); printf(i, G. vertices[i].data); ++count; for (p=G.vertices[i].firstarc; p; p=p->nextarc) { k = p->adjvex; if ( !(- -indegree[k]) ) Push(S, k); }//for }//while data firstarc C0 1 3 0 栈S C1 5 0
Status TopologicalSort(ALGraph G) { FindInDegree(G, indegree); //求各顶点入度indegree[0..vexnum-1] InitStack(S); for(i=0; i<G. vexnum; ++i) if (! indegree[i]) Push(S, i); //入度为0顶点的编号进栈 count = 0; //对输出顶点计数 count=6 while(! StackEmpty(S)){ Pop(S, i); //从零入度顶点栈S 栈顶,获得一入度为零的顶点i printf(i, G. vertices[i].data); ++count; //输出i号顶点的数据,并计数 for (p=G. vertices[i]. firstarc; p; p=p->nextarc) { k = p->adjvex; if ( !(- -indegree[k]) ) Push(S, k); //对i号顶点邻接到的 每个顶点入度减1
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1 ABSTRACT1.1图和栈的结构定义struct SqStack////栈部分{SElemType *base;//栈底指针SElemType *top;//栈顶指针int stacksize;//栈的大小int element_count;//栈中元素个素};/////////AOE网的存储结构struct ArcNode //表结点{int lastcompletetime;//活动最晚开始时间int adjvex; //点结点位置int info; //所对应的弧的权值struct ArcNode *next;//指向下一个表结点指针};struct VNode //点结点{VertexType data; //结点标志int indegree; //该结点入度数int ve; //记录结点的最早开始时间int vl; //记录结点的最晚开始时间struct ArcNode *first_out_arc; //存储下一个出度的表结点struct ArcNode *first_in_arc;//存储下一个入度的表结点};struct ALGraph{ VNode *vertices; //结点数组int vexnum; //结点数int arcnum; //弧数int kind; //该图的类型 };2系统总分析2.1关键路径概念分析2.1.1什么是关键路径关键路径法(Critical Path Method, CPM)最早出现于20世纪50年代,它是通过分析项目过程中哪个活动序列进度安排的总时差最少来预测项目工期的网络分析。
这种方法产生的背景是,在当时出现了许多庞大而复杂的科研和工程项目,这些项目常常需要运用大量的人力、物力和财力,因此如何合理而有效地对这些项目进行组织,在有限资源下以最短的时间和最低的成本费用下完成整个项目就成为一个突出的问题,这样CPM就应运而生了。
对于一个项目而言,只有项目网络中最长的或耗时最多的活动完成之后,项目才能结束,这条最长的活动路线就叫关键路径(Critical Path),组成关键路径的活动称为关键活动。
2.1.2关键路径特点关键路径上的活动持续时间决定了项目的工期,关键路径上所有活动的持续时间总和就是项目的工期。
关键路径上的任何一个活动都是关键活动,其中任何一个活动的延迟都会导致整个项目完工时间的延迟。
关键路径上的耗时是可以完工的最短时间量,若缩短关键路径的总耗时,会缩短项目工期;反之,则会延长整个项目的总工期。
但是如果缩短非关键路径上的各个活动所需要的时间,也不至于影响工程的完工时间。
关键路径上活动是总时差最小的活动,改变其中某个活动的耗时,可能使关键路径发生变化。
可以存在多条关键路径,它们各自的时间总量肯定相等,即可完工的总工期。
关键路径是相对的,也可以是变化的。
在采取一定的技术组织措施之后,关键路径有可能变为非关键路径,而非关键路径也有可能变为关键路径。
2.2关键路径实现过程2.2.1结构选取首先要选取建图的一种算法建立图,有邻接矩阵,邻接表,十字链表,邻接多重表等多种方法,要选取一种适当的方法建立图,才能提高算法效率,降低时间复杂度和空间复杂度。
两个相邻顶点与它们之间的边表示活动,边上的数字表示活动延续的时间。
对于给出的事件AOE网络,要求求出从起点到终点的所有路径,经分析、比较后找出长读最大的路径,从而得出求关键路径的算法,并给出计算机上机实现的源程序。
完成不同路径的活动所需的时间虽然不同,但只有各条路径上所有活动都完成了,这个工程才算完成。
2.2.2具体要解决的问题(1)将项目中的各项活动视为有一个时间属性的结点,从项目起点到终点进行排列;(2)用有方向的线段标出各结点的紧前活动和紧后活动的关系,使之成为一个有方向的网络图;(3)用正推法和逆推法计算出各个活动的最早开始时间,最晚开始时间,最早完工时间和最迟完工时间,并计算出各个活动的时差;(4)找出所有时差为零的活动所组成的路线,即为关键路径;(5)识别出准关键路径,为网络优化提供约束条件;2.2.3算法分析(1)求关键路径必须在拓扑排序的前提下进行,有环图不能求关键路径;(2)只有缩短关键活动的工期才有可能缩短工期;(3)若一个关键活动不在所有的关键路径上,减少它并不能减少工期;(4)只有在不改变关键路径的前提下,缩短关键活动才能缩短整个工期。
(5)关键路径:从源点到汇点的路径长度最长的路径叫关键路径。
(6)活动的最早开始时间e(i);(7)活动的最晚开始时间l(i);(8)定义e(i)=l(i)的活动叫关键活动;(9)事件的最早开始时间ve(i);(10)事件的最晚开始时间vl(i)。
设活动ai由弧<j,k>(即从顶点j到k)表示,其持续时间记为dut(<j,k>),则:e(i)=ve(j)l(i)=vl(k)-dut(<j,k>)求ve(i)和vl(j)分两步:1.从ve(1)=0开始向前递推ve(j)=Max{ ve(i)+dut(<i,j>) }<i,j>T, 2<=j<=n其中,T是所有以j为弧头的弧的集合。
2.从vl(n)=ve(n)开始向后递推vl(i)=Min{ vl(j)-dut(<i,j>) }<i,j>S, 1<=i<=n-1其中,S是所有以i为弧尾的弧的集合。
两个公式是在拓扑有序和逆拓扑有序的前提下进行。
2.2.4 算法步骤(1)输入e条弧<j,k>,建立AOE网的存储结构。
(2)从源点v1出发,令ve(1)=0,求个点的最早开始时间ve(j)。
(3)从汇点vn出发,令vl(n)=最大值,求个点的最晚开始时间vl(j)。
(4)由于各结点的最早开始时间已求出来,所以各活动的最早开始时间即(每条弧s(活动)的最早开始时间)就等于该结点的最早开始时间,并由上可同时求出该活动的最晚开始时间l(j)。
(5)具体表达式为:e(i)=ve(j)l(i)=vl(k)-dut(<j,k>)(6)当结点的最早开始时间ve(j)=最晚开始时间时vl(j),则该结点为关键结点。
(7)当活动的最早开始时间e(j)=最晚开始时间时l(j),则该结点为关键活动。
3 主要功能模块设计3.1程序模块栈部分模块Status InitStack(SqStack &S) //初始化栈Status DestroyStack(SqStack &S)//销毁栈Status ClearStack(SqStack &S)//清空栈Status StackEmpty(SqStack S)//判断是否为空Status StackEmpty(SqStack S)//判断是否为空Status Pop(SqStack &S,SElemType &e) //弹出元素Status GetElement(SqStack &S,int position,SElemType &e) //取元素,非弹出,i为要去元素位置无向图(AOE网)部分模块void CreateALGraph(ALGraph &graph)//初始化AOE网Status TopologicalSort(ALGraph &graph,SqStack &ToPoReverseSort) //求拓扑排序Status PutInfoToPoSort(SqStack temp,ALGraph graph) //输出拓扑顺序排序(当拓扑序列存在时)Status GetVeAndVl(ALGraph &graph,SqStack OrderSort,SqStack RevSort) //求出结点和活动的最晚开始时间和最早开始时间Status CriticalPath(ALGraph &graph,SqStack RevSort) //求出关键活动和关键事件并输出4 系统详细设计4.1主函数模块main函数首先调用SqStack ToPoSort;SqStack ToPoReverseSort;函数来定义栈,调用InitStack(ToPoSort);来初始化存拓扑排序的栈和InitStack(ToPoReverseSort);来初始化逆拓扑排序的栈。
其次调用CreateALGraph(ALGraph &graph)函数定义和初始化AOE网,调用TopologicalSor t(ALGraph &graph,SqStack &ToPoReverseSort) 函数求拓扑序列和调用PutInfoToPoSort(ToPoSort,graph);函数来输出输出拓扑顺序排序。
然后调用GetVeAndVl(graph,ToPoSort,ToPoReverseSort) 函数求结点和活动的最晚开始时间、最早开始时间并输出。
最后调用Status CriticalPath(ALGraph &graph,SqStack RevSort)函数来求关键活动、关键事件并输出。
4.2初始化模块初始化模块用来初始化图,要求用户自己输入数据,并程序构造AOE网。
本程序是用自己改进的邻接表来构造AOE网。
见图2-4-2图2-4-2图2-4-34.3求拓扑序列模块利用栈来存储入度为零的结点,然后逐个弹出,来进行与该结点的出度结点来比较,是否符合拓扑排序的规则,最后用ToPoReverseSort存放拓扑逆序序列来完成整个拓扑排序。
见图2-4-34.4求最晚开始时间和最早开始时间模块(包括结点和活动的最早和最晚开始时间)见图2-4-4图2-4-44.5关键活动和关键事件见图2-4-5N图2-4-54.6输出模块输出相应结点的信息,拓扑序列,以及事件的最早开始时间和最晚开始时间,输出相应的活动的最早开始时间和最晚开始时间,关键活动以及关键事件。
5 测试分析5.1测试内容求的关键路径为:程序输入部分:求拓扑序列部分求结点和活动的最早开始时间和最晚开始时间输出图中的关键事件和关键活动(关键路径)测试关键路径结果:5.2回路测试结果分析:结果完全符合所求,但是输出的方面不够完美,并且自我感觉程序所使用的空间比较大,算法复杂度较高,所以效率比较低下,当程序输入存在有环的时候,程序没有发生任何错误,直接输出“图存在有环”然后退出程序。
由此可见本程序计划实施到完工比较顺利的完成了,并且在程序测试中能够得到预期的结果出来,不过唯一不满意的是程序过于复杂化,使用的太多的空间,致使程序成为一个缺陷。
参考文献[1]严蔚敏,吴伟民.数据结构. 北京:清华大学出版社,2006.[2]谭浩强. C程序设计(第二版)作者:清华大学出版社,2006心得体会经历几天的编程之后,课程设计终于结束了。