数据结构基于紧缩图的邻接表的拓扑排序毕业论文.docx
《数据结构基于紧缩图的邻接表的拓扑排序毕业论文.docx》由会员分享,可在线阅读,更多相关《数据结构基于紧缩图的邻接表的拓扑排序毕业论文.docx(31页珍藏版)》请在冰豆网上搜索。
![数据结构基于紧缩图的邻接表的拓扑排序毕业论文.docx](https://file1.bdocx.com/fileroot1/2023-4/20/6be8554a-5a08-4951-89ab-dbc7a0931e98/6be8554a-5a08-4951-89ab-dbc7a0931e981.gif)
数据结构基于紧缩图的邻接表的拓扑排序毕业论文
东北大学信息科学与工程学院
数据结构课程设计报告
题目基于紧缩图的邻接表的拓扑排序
课题组长宋振
课题组成员常玉颖于红爽
专业名称计算机科学与技术
班级计1307
指导教师杨雷
2015年1月
课程设计任务书
题目:
基于紧缩图的拓扑排序
问题描述:
紧缩邻接表将图的每个顶点的邻接表紧凑的存储在两个向量list和h中。
其中向量list依次存储顶点0,1,…,n-1的邻接顶点。
向量单元h[i]存储顶点i的邻接表在向量list中的起始位置。
设计要求:
设计基于紧缩图的邻接表的拓扑排序程序。
(1)采用STL的图、栈等数据结构。
(2)实现STL的紧缩邻接表结构图类。
(3)实现紧缩图的邻接表结构的拓扑排序。
指导教师签字:
年 月 日
目录
1课题概述
1.1课题任务
1.2课题原理
1.3相关知识
2需求分析
2.1课题调研
2.2用户需求分析
3方案设计
3.1总体功能设计
3.2数据结构设计
3.3函数原型设计
3.4主算法设计
3.5用户界面设计
4方案实现
4.1开发环境与工具
4.2程序设计关键技术
4.3个人设计实现(按组员分工)
4.3.1宋振设计实现
5测试与调试
5.1个人测试(按组员分工)
5.1.1宋振测试
5.2组装与系统测试
5.3系统运行
6课题总结
6.1课题评价
6.2团队协作
6.3团队协作
6.4个人设计小结(按组员分工)
6.4.1宋振设计小结
7附录A课题任务分工
A-1课题程序设计分工
A-2课题报告分工
附录B课题设计文档(光盘)
B-1课程设计报告(电子版)
B-2源程序代码(*.H,*.CPP)
B-3工程与可执行文件)
B-4屏幕演示录像文件(可选)
附录C用户操作手册(可选)
C.1运行环境说明
C.2操作说明
1课题概述
1.1课题任务
基于紧缩图的邻接表的拓扑排序问题
【问题描述】
紧缩邻接表将图的每个顶点的邻接表紧凑的存储在两个向量list和h中。
其中向量list依次存储顶点0,1,…,n-1的邻接顶点。
向量单元h[i]存储顶点i的邻接表在向量list中的起始位置。
【设计要求】
设计基于紧缩图的邻接表的拓扑排序程序。
(1)采用STL的图、栈等数据结构。
(2)实现STL的紧缩邻接表结构图类。
(3)实现紧缩图的邻接表结构的拓扑排序。
1.2课题原理
将图的结点存入两个向量之中,List用以存放全部结点,H用以存放结点间的相互关联关系,通过输入一系列结点信息及其发出弧的信息,确定每个结点的入度,进行拓扑排序序列的输出。
拓扑排序算法boolTopologicalSort(ALGraphG)中,先输出入度为零的顶点,而后输出新的入度为零的顶点,此操作可利用栈实现。
该算法大体思想为:
①遍历有向图各顶点的入度,将所有入度为零的顶点入栈;
②栈非空时,输出一个顶点,并对输出的顶点数计数;
③该顶点的所有邻接点入度减一,若减一后入度为零则入栈;
④重复②、③,直到栈为空,若输出的顶点数与图的顶点数相等则该图可拓扑排序,否则图中有环。
1.3相关知识
数据结构:
栈,拓扑排序。
程序语言:
C++。
STL中的向量模板。
2需求分析
2.1课题调研
对一个有向无环图G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。
通常,这样的线性序列称为满足拓扑次序的序列,简称拓扑序列。
简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。
我们小组内通过查阅书籍课本和网上资料,了解到拓扑排序的概念。
2.2用户需求分析
拓扑排序在大型工程中有广泛的应用拓扑排序常用来确定一个依赖关系集中,事物发生的顺序。
例如,在日常工作中,可能会将项目拆分成A、B、C、D四个子部分来完成,但A依赖于B和D,C依赖于D。
为了计算这个项目进行的顺序,可对这个关系集进行拓扑排序,得出一个线性的序列,则排在前面的任务就是需要先完成的任务。
用户需求如下:
①用户可以通过输入每个结点和弧的信息讲结点放入图中,再通过栈实现拓扑排序序列的输出;②可以在拓扑排序时同时输出结点信息;该程序应该有对用户错误输入的辨别纠错功能;③程序应具有演示功能和调试功能;④程序应具有良好的人机接口。
程序应能所见即所得的输入数据。
这就如同在VS中可视化的开发图形界面一样。
程序应能精确的输入数据。
每一个点的坐标,每条弧的权值都应能由用户精确控制。
⑥程序应能友好的展现结果。
⑦程序应能显示制作者的信息。
3方案设计
3.1总体功能设计
第一部分是根据输入的边的信息情况对各个点进行入度统计;第二部分是实现拓扑排序
功能设计的流程图如下:
3.2数据结构设计
向量结构,用以存储结点顺序及关系;
图类结构,主要用以对用户输入的结点信息进行存储;
栈结构,用来根据图的入度机型拓扑排序输出。
3.3函数原型设计
函数原型
参数说明
功能描述
boolTopologicalSort(Graphv,vectorindegree)
两向量存储的图v和存储入度indegree的向量
在函数中实现拓扑排序,返回是否存在环
boolIsDigit(string&str)
字符类型的&str
判断str是否为数字
3.4主算法设计
在建立邻接表输入之前,表头向量的每个结点的初始状态为数据域VEX(入度)为零,指针域NXET为空,每输入一条弧建立链表的一个结点,同时令k的入度加1,因此在输入结束时,表头的两个域分别表示顶点的入度和指向链表的第一个结点指针。
在拓扑排序的过程之中,输入入度为零(即没有前趋)的顶点,同时将该顶点的直接后继的入度减1。
(1)查邻接表中入度为零的顶点,并进栈。
(2)当栈为空时,进行拓扑排序。
①退栈,输出栈顶元素V。
②在邻接表中查找Vj的直接后继Vk,将Vk的入度减一,并令入
度减至零的顶点进栈。
(3)若栈空时输出的顶点数不是N个则说明有向回路,否则拓扑排序结束。
为建立存放入度为零的顶点的栈,不需要另分配存储单元,即可借入入度为零的数据域。
一方面,入度为零的顶点序号即为表头结点的序号,另一方面,借用入度为零的数据域存放带链栈的指针域(下一个入度的顶点号)。
3.5用户界面设计
本程序使用控制台DOS设计:
4方案实现
4.1开发环境与工具
主要编程环境:
Code:
:
Blocks,MicrosoftVisualStudioC++6.0
编程工具:
C++。
4.2程序设计关键技术
基于紧缩图的拓扑排序:
拓扑排序算法boolTopologicalSort(ALGraphG)中,先输出入度为零的顶点,而后输出新的入度为零的顶点,此操作可利用栈实现。
该算法大体思想为:
①遍历有向图各顶点的入度,将所有入度为零的顶点入栈;
②栈非空时,输出一个顶点,并对输出的顶点数计数;
③该顶点的所有邻接点入度减一,若减一后入度为零则入栈;
④重复②、③,直到栈为空,若输出的顶点数与图的顶点数相等则该图可拓扑排序,否则图中有环。
4.3个人设计实现(按组员分工)
4.3.1宋振设计实现
主程序的实现,定义结构体,根据输入的信息计算节点的入度
include
#include
#include
#include
#include
#include
usingnamespacestd;
structVnode
{
stringvernum;
};
structGraph
{
vectorNode;
vectorList;//存所有节点信息
vectorH;//存i的邻接节点
intNodeNum;//节点数
};
intmain()
{
staticintm;
Graphv;
Vnoden;
intnum;
intcountN,i,j;
stringNode;
vectorindegree;
Clock*clock=newClock();
cout<<"当前进行拓扑排序的时间为:
"<<*clock<cout<<"------------------------------拓扑排序---------------------------"<cout<<"||"<cout<<"|基于紧缩图的邻接表的拓扑排序问题|"<cout<<"||"<cout<<"||"<cout<<"|制作人:
宋振常玉颖于红爽|"<cout<<"||"<cout<<"|-------------------------请输入节点的总数----------------------|"<cin>>Node;
while
(1)
{
if(IsDigit(Node))
{
intb=atoi(Node.c_str());
if(b>0)
{
v.NodeNum=b;
break;
}
else
cout<<"请重新输入大于0的数字"<}
elsecout<<"请输入数字"<cin>>Node;
}
for(i=0;i{
stringtemp;
cout<<"~~~~~~~~~~~~~~~~请输入第"<
cin>>temp;
if(temp=="0")break;
n.vernum=temp;
v.Node.push_back(n);
}
num=v.Node.size();
for(i=0;i{
stringn;
cout<<"第"<
v.H.push_back(m);
for(j=0;;j++)
{
boolNumequal=false;
cin>>n;
if(IsDigit(n))
{
intb=atoi(n.c_str());
if(b<=v.Node.size()&&b>=0)
{
if(b!
=i+1)
{
for(countN=v.H[i];countNif(v.List[countN]==b-1)
Numequal=true;
if(!
Numequal)
{if(b==0)
{
break;
}
b--;
v.List.push_back(b);
m++;
}
elsecout<<"输入重复请重新输入"<}
elsecout<<"请重新输入与本节点不同的节点编号"<}
elsecout<<"请输入编号小于总结点数大于0的节点编号"<}
elsecout<<"请输入数字"<}
}
for(i=0;i{
intnumber=0;
for(intj=0;jif(v.List[j]==i)
number++;
indegree.push_back(number);
}
if(TopologicalSort(v,indegree))
{
cout<cout<<"正常完成!
"<}
elsecout<<"该有向图有回路!
"<system("pause");//结束前暂停
return0;
}
4.3.2常玉颖设计实现
拓扑排序函数
stacks;
boolTopologicalSort(Graphv,vectorindegree)
{
inti,k,m,n=0;
for(i=0;i{
if(!
indegree[i]){s.push(i);}
}
cout<<"结果为:
"<fopen("result.txt","+w");
while(!
s.empty())
{
i=s.top();
s.pop();
cout<
cout<<"||";
cout<if(n!
=v.Node.size()-1)
cout<<"-->";
n++;
if(i==indegree.size()-1)
for(m=v.H[i];m{
k=v.List[m];
indegree[k]--;
if(!
indegree[k])s.push(k);
}
elsefor(m=v.H[i];m{
k=v.List[m];
indegree[k]--;
if(!
indegree[k])s.push(k);
}
}
if(nreturntrue;
}
4.3.3于红爽设计实现
判断输入是否为数字
boolIsDigit(string&str)
{
boolflag=true;
for(unsignedinti=0;i{
if(!
isdigit(str[i]))
{
flag=false;
break;
}
}
returnflag;
}
5测试与调试
5.1个人测试(按组员分工)
5.1.1宋振个人测试
#include
#include
#include
#include
#include
usingnamespacestd;
structVnode
{
stringvernum;
};
structGraph
{
vectorNode;
vectorList;
vectorH;
intNodeNum;
};
intmain()
{
staticintm;
classGraphv;
Vnoden;
intnum;
inti,j,countN;
stringNode;
vectorindegree;
cout<<"请输入节点的总数"<cin>>v.NodeNum;
for(i=0;i{
stringtemp;
cout<<"~~~~~~~~~~~~~~~~请输入第"<
cin>>temp;
if(temp=="0")break;
n.vernum=temp;
v.Node.push_back(n);
}
num=v.Node.size();
for(i=0;i{
stringn;
cout<<"第"<
v.H.push_back(m);
for(j=0;;j++)
{
cin>>n;
intb=atoi(n.c_str());
if(b==0)
{
break;
}
b--;
v.List.push_back(b);
m++;
}
}
for(i=0;i{
intnumber=0;
for(j=0;jif(v.List[j]==i)
number++;
indegree.push_back(number);
}
intq;
for(q=0;q{
cout<}
for(q=0;q{
cout<}
for(q=0;q{
cout<}
for(q=0;q{
cout<}
return0;
}
建图过程:
5.1.2常玉颖个人测试
#include
#include
#include
#include
#include
usingnamespacestd;
structVnode
{
stringvernum;
};
classGraph
{
public:
boolTopologicalSort(Graphv,vectorindegree);
vectorNode;
vectorList;
vectorH;
intNodeNum;
};
boolGraph:
:
TopologicalSort(Graphv,vectorindegree)
{
stacks;
inti,k,m,n=0;
for(i=0;i{
if(!
indegree[i]){s.push(i);}
}
cout<<"结果为:
"<while(!
s.empty())
{
i=s.top();
s.pop();
cout<
cout<<"||";
cout<if(n!
=v.Node.size()-1)
cout<<"-->";
n++;
if(i==indegree.size()-1)
for(m=v.H[i];m{
k=v.List[m];
indegree[k]--;
if(!
indegree[k])s.push(k);
}
elsefor(m=v.H[i];m{
k=v.List[m];
indegree[k]--;
if(!
indegree[k])s.push(k);
}
}
if(nreturntrue;
}
intmain()
{
staticintm;
classGraphv;
Vnoden;
intnum;
inti,j,countN;
stringNode;
vectorindegree;
cout<<"节点的总数:
"<cin>>Node;
intb=atoi(Node.c_str());
v.NodeNum=b;
for(i=0;iv.Node.push_back(n);
num=v.Node.size();
for(i=0;i{
stringn;
cout<<"第"<
v.H.push_back(m);
for(j=0;;j++)
{
cin>>n;
intb=atoi(n.c_str());
if(b==0)
{
break;
}
b--;
v.List.push_back(b);
m++;
}
}
for(i=0;i{
intnumber=0;
for(j=0;jif(v.List[j]==i)
number++;
indegree.push_back(number);
}
if(v.TopologicalSort(v,indegree))
{
cout<<"正常完成!
"<}
elsecout<<"该有向图有回路!
"<return0;
}
通过入度进行拓扑排序,调试结果为:
5.1.3于红爽个人调试
输入
#include
#include
#include
#include
#include
usingnamespacestd;
boolIsDigit(string&str)
{
boolflag=true;
for(unsignedinti=0i{
if(!
isdigit(str[i]))
{
flag=false;
break;
}
}
returnflag;
}
intmain()
{
stringa="123w";
stringb="1";
stringc="applew";
if(IsDigit(a))
cout<<"yes"<else
cout<<"no"<if(IsDigit(b))
cout<<"yes"<else
cout<<"n