-
数据结构课程设计
设计说明书
有向图拓扑排序算法的实现
学
生
姓
名
学
班
成
号
级
绩
樊
佳
佳
1318064017
网
络
工
程
1301
申
静
指
p>
导
教
师
数学与计算机科学学院
2016
年
1
月
4
日
课程设计任务书
< br>2015
—
2016
学年第一学
期
课程设计名称:
数据结构课程设计
课程设计题目:
图的拓扑排序算法的实现
完成期限:
设计内容:
1
、设计任务
(
1
)给出一个有向无环图,遍历所有的节点;
(
2
)能够实现对所有顶点的拓扑;
(3)
界面友好,可
操作性强。
2
、需求分析
< br>对系统的功能及性能要求进行分析,
写出需求规格说明书
(可行性分析报告、
系统的分层
DFD
图)
。
3
、软件设计
软件设计分两个阶段进行:总体设计和详细设计;
总体设计:确定系统总体设计方案,完成系统的模块结构图及模块的功能说明;
详细设计:对模块内部过程及数据结构进行设计,以及进行数据库设计、用户界面
设计等编写
出该项目的详细设计报告;
4
、具体编码
编写程序,要求给出详细的注释,包括:模块名、模块功能、中间过程的功能、变量说明等。
< br>同时编写用户使用手册、程序模块说明等文档;
5
、软件测试
所有测试过程要求采用综合测试策略:先作静态分析,再作动态测试。应事先制订测试计划,
< br>并要求保留所有测试用例,完成测试报告。
指导教师:申静教研室负责人:申静
自
2015
年
12
月
20
日至
2016
年
1
月
3
日共
2
周
课程设计评阅
评语:
指导教师签名:
年月日
摘要
设计了一个对有向图进行拓扑排
序的算法,该算法首先用邻接表构造有向图的存储结构,然后对此
有向图进行拓扑排序,
输出拓扑排序的结果。
用
VC++
p>
作为软件开发环境,
以邻接表作为图的存储结构,
< br>将图中所有顶点排成一个线性序列,输出拓扑排序结果。拓扑排序常用来确定一个依赖关系集中,事物 p>
发生的顺序。
拓扑排序是对有向无环图的顶点的一种排序,
它使得如果存在一条从顶点
A
到顶点
B
的路
径,那么在排序中
B
出现在
A
的后面。
< br>
关键词
:邻接表;有向无环
图;拓扑排序
目录
1
课题描述
.
.....................................
..................................................
............................
1
2
问题分析和任务定义
.
.............................................
..................................................
2
3
逻辑设计
.
..................................................
..................................................
...............
3
3.1
程序模块功能图
.
.................................
..................................................
...........
3
3.2
抽象数据类型
.
................................................ .................................................
3
4
详细设计
.
..................................................
..................................................
...............
4
4.1 C
语言定义的相关数据类型
.
...........................
...............................................
4
4.2
主要模块的伪码算法
.
.............................................
........................................
4
4.2.1
主函数伪码算法
.
...............................
..................................................
...
4
4.2.2
邻接表伪码算法
.
...............................
..................................................
...
4
4.2.3
拓扑排序的伪码算法:
<
/p>
.
............................
............................................
5
4.3
主函数流程图
.
................................................ .................................................
6
5
程序编码
.
..................................................
..................................................
...............
7
6
程序调试与测试
.
..................................
..................................................
.................
1
3
7
结果分析
.
.....................................
..................................................
..........................
1
6
8
总结
.
..
..................................................
..................................................
...................
1
7
参考文献
.
..................................................
..................................................
.................
1
8
1
课题描述
根根据设计要求运用
C
语言程序设计了一个对有向图进行拓扑排序的算法,
该算法首
先用邻接表构造有向图的存储结构,
然后对此
有向图进行拓扑排序,
输出拓扑排序的结果。
如给定一个有向无环图如图
1.1
所示。在此图中,从
入度为
0
的顶点出发,删除此顶
点和所
有以它为尾的弧;重复直至全部顶点均已输出;或者当图中不存在无前驱的顶点为
止。<
/p>
3
2
1
4
5
图
1.1
有向无环图
开发工具:
Visual C++
6.0
第
1
页共
18
页
2
问题分析和任务定义
对一个有向无环
图
G
进行拓扑排序,
是将
G
中所有顶点排成一个线性序列,
使得图中
任意一对由某个集合上的一个偏序得到该集合上的一个全序,
这个操作就
称之为拓扑排序。
偏序集合中仅有部分成员之间颗比较,而全序指集合中全体成员之间均
可比较,而由偏序
定义得到拓扑有序的操作便是拓扑排序。
<
/p>
一个表示偏序的有向图可用来表示一个流程图,通过抽象出来就是
AOV-
网,若从顶
点
i
到顶点
j
有一条有向路径,则
i
是
j
的前驱,
j
是
i
的后继。若(
i
,
j
)是一条弧,则
p>
i
是
j
的直接前驱
;
j
是
i
的直
接后继。
在
AOV-
网中,不应该出现有向环,用拓扑排序就可以判断网中是否有环,若网中所
有顶
点都在它的拓扑有序序列中,则该
AOV-
网必定不存在环。<
/p>
第
2
页共
18
页
3
逻辑设计
3.1
程序模块功能图
主函数
节
点
入
度
有
向
图
p>
初
始
化
创
建
邻
接
表
栈
< br>的
初
始
化
拓
扑
排
序
图
3.1
程
序模块功能图
3.2
抽象数据类型
ADT
ALGraph
{
数据对象:
p>
D={V|V
是具有相同特性的数据元素的集合,即顶点集
}
数据关系:
<
br>的弧 <
br>i
<
br>第一条弧的头结点
R={
∈
V
,
表示顶点
v
到顶点
w
}
基本操作
P:
CreatGraphlist(ALGraph *G)
初
始条件:成对输入顶点集
V
中的点。
操作结果:构造图
G
的邻接表。
FindInDegree(ALGraph G,
intindegree[])
初始条件:图
G
的邻接表中存在结点
V
。
操作结果:找到图中入度为
0
结点。<
/p>
Initgraph()
操作结果:完成图形初始化。
TopologicalSort(ALGraph G)
初
始条件:构造的有向图
G
已初始化。
操作结果:对于有向图
G
根据邻接存储
表进行拓扑排序。
}
第
3
页共
18
页
4
详细设计
4.1
C
语言定义的相关数据类型
#define max_vextex_num 20
/*
宏定义最大顶点个数
*/
#define stack_init_size 100
/*
宏定义栈的存储空间大小
*/
typedefintElemType;
typedefstructVNode
/*
邻接表头结点的类型
*/
{
int data; /*
顶点信息
,
数据域
*/
}VNode,
AdjList[MAX_VEXTEX_NUM];
/*AdjList
是邻接表类型
*/
typedefstruct
{
AdjList vertices;
/*
邻接表
*/
intvexnum, arcnum; /*
图中顶点数
p>
vexn
和边数
arcn*/
}ALGraph;
/*
图的类型
*/
typedefstruct
//
构建栈
{
ElemType *base;
/*
数据域
*/
ElemType *top;
/*
栈指针域
*/
intstacksize;
}SqStack;
4.2
主要模块的伪码算法
4.2.1
主函数伪码算法:
开始
{
创建及输出邻接表
CreatGraphlist(&G);
输出排序后的输出序列
TopologicalSort(G)
;
}
结束
4.2.2
邻接表伪码算法:
#define MAX_VEXTEX_NUM 20
typedefstructVNode
/*
邻接表头结点的类型
*/
{
int data; /*
顶点信息
,
数据域
*/
第
4
页共
18
页
ArcNode *firstarc;
/*
指向第一条弧
*/
}VNode, AdjList[MAX_VEXTEX_NUM];
/*AdjList
是邻接表类型
*/
typedefstruct
{
AdjList vertices;
/*
邻接表
*/
intvexnum, arcnum; /*
图中顶点数
p>
vexn
和边数
arcn*/
}ALGraph;
/*
图的类型
*/
开始
{
定义一个指针
P
置
的初值为
1
邻接表中所有头结点指针置初值
当<
/p>
i<=G-vexnum
时自加,执行下面操作:
输出数据域里的顶点信息
使指针
p
指向顶点
i
输出访问顶点
使指针
p
指向顶点
i
的下一条弧的头
结点
类此循环到输出最后一个顶点
}
结束
4.2.3
拓扑排序的伪码算法
开始
{
引入栈操作函数和入度操作函数
访问邻接存储表中的顶点
n
If
该顶点入度为
0
顶点进栈
循环操作到所有顶点入栈
当栈不为空
顶点出栈
}
结束
第
5
页共
18
页
4.3
主函数流程图
主函数流程图如图
4.3
所示
开始
输入顶点数
和弧数
输入
判断是否满足条件
Y
根据输入信息建立邻接表
建栈
N
在邻接表中寻找入度为零的顶点,使其入栈
N
输出栈顶元素,
打印,
将与栈顶元素邻接的
顶点的入度减
1
判断是否空栈
Y
结束
图
4.3
主函数程序流程图
第
6
页共
18
页
5
程序编码
#include
#include
#define
true 1
#define false 0
#define MAX_VEXTEX_NUM 20
#define M 20
#define
STACK_INIT_SIZE 100
#define
STACKINCREMENT 10
/*-------
----------------
图的邻接表存储结构
---
---------------------*/
typedefstructArcNode
/*
弧结点结构类型
*/
{
intadjvex;
/*
该弧指向的顶点的位置
*/
structArcNode *nextarc;
/*
指向下一条弧的指针
*/
}ArcNode;
typedefstructVNode
/*
邻接表头结点类型
*/
{
int data;
/*
顶点信息
*/
ArcNode *firstarc;
p>
/*
指向第一条依附于该点的弧的指针
*/
}VNode,AdjList[MAX_VEXTEX_NUM];
/*AdjList
为邻接表类型
*/
typedefstruct
{
AdjList vertices;
intvexnum,
arcnum;
}ALGraph;
/*--------
--------------------------------------------------
------*/
void CreatGraph(ALGraph *G)
p>
/*
通过用户交互产生一个图的邻接表
*/
{
int m, n, i;
ArcNode *p;
pri
ntf(
printf(
输入顶点数
:
scanf(
printf(
输入边数
:
scanf(
printf(
for
(i=1; i<=G->vexnum;i++)
/*
初始化各顶点
*/
{
G->vertices[i].data=i;
/*
编写顶点的位置序号
*/
G->vertices[i].firstarc=NULL;
第
7
页共
18
页