- 1、本文档共4页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
图的逆拓扑排序 (回路识别)
⽬录
背景
在学习拓扑排序的时候,⽼师提出了⼀个问 :在逆拓扑排序算法中如何识别出回路?
总所周知,拓扑排序必须在DAG (有向⽆环图)中实现,也就是说如果给定的图带有回路,就⽆法进⾏拓扑排序。
我经过思考,想出了⼀个识别⽅法,在此做出记录。
实现思路
何为回路,我的理解就是访问回头路,从系统栈的⾓度说,就是指向了还在栈中的节点。只要节点还在栈中节点就还在访问路径上,此时指
向就是⾛回头路。若节点不在栈中,出栈了,访问路径⾃然也就把改点剔除,就不存在经过该的回路。
我们是基于DFS算法进⾏拓扑排序。DFS是基于递归实现的算法,从初始点开始,依次遍历第⼀个邻居节点,直到没有邻居为⽌,递归结束
时输出节点,输出的顺序就是拓扑排序。
以上图为例,就是从0开始依次遍历1、3、4;因为4没有指向其他节点。递归结束。然后搜索剩余未遍历的点,再次进⾏递归遍历。
从系统栈的⾓度就是,依次将0、1、3、4压⼊栈。递归结束,输出4、3、1、0;第⼆轮递归把2压⼊,输出2。
DFS算法,每轮递归访问⼀次最深的路径,⼀共两轮,最终的排序次序为:4、3、1、0、2
如果没有回路,那么每⼀轮递归只会沿着路径做最深访问,不会出现重复(从系统栈的⾓度,指向了还在栈中的节点)。
⽐如第⼀张图的0、1、3、4没有出现重复访问,但第⼆张图中,0、1、3、4、2、3,在同⼀轮递归中访问了重复的节点3。说明出现了
回路 (⾛了回头路)
因此我们可以添加⼀个数组nowVisited[],记录每⼀轮递归节点被访问的情况。这样就有两个数组记录节点访问情况,visited[]记录全局访
问情况,nowVisited[]只记录本轮递归的访问情况。
如果⼀个节点在本轮递归中没有访问,说明没有出现回路,继续执⾏代码。
如果⼀个节点在本轮递归被访问过了,说明出现了回路,代码⽴即中⽌执⾏。
代码
#include iostream
using namespace std ;
//定义邻接矩阵
#define MAXVERT EXNUM 1
typedef struct {
int vex[MAXVERT EXNUM] ;
int edge[MAXVERT EXNUM][MAXVERT EXNUM] ;
int vexnum, arcnum;
}Graph;
//寻找第⼀个邻接点
int FirstNeighbor(Graph G, int v)
{
for (int i = ; i G.vexnum; ++i)
{
if (G.edge[v][i] != )
{
return i;
}
}
return -1;
}
//寻找下⼀个邻接点
int NextNeighor(Graph G, int v, int w)
{
for (int i = w+1; i G.vexnum; ++i)
{
if (G.edge[v][i] != )
{
return i;
}
}
return -1;
}
//DFS遍历找到排序次序
bool visited[MAXVERT EXNUM] ;
bool nowVisited[MAXVERT EXNUM] ;
bool warry = false;
void DFS(Graph G, int v) {
visited[v] = true;//记录全局访问情况
nowVisited[v] = true;//记录本轮访问情况
for (int w = FirstNeighbor(G, v) ; w = ; w = NextNeighor(G, v, w)) {//依次递归访问v的邻居节点
if (nowVisited[w] == true) {//如果本轮已经访问过了v的邻居节点w,出现回路,⽴即中⽌代码
cout\n出现回路: G.vex[v] = G.vex[w] ;
exit( ) ;
}
if (visited[w] == false) {//没被访问就继续递归,沿着该点路径继续延长
DFS(G, w) ;
}
}//for
cout G.vex[v] -;
nowVisited[v] = false;//本轮结束,消去本轮对应的访问记录。
}
//防⽌遗漏
void DFSTraverse(Graph G) {
for (int v = ; v G.vexn
您可能关注的文档
最近下载
- 六年级数学上册期末复习计划.docx VIP
- 测量测绘重点难点分析.docx
- 2024年中考道德与法治复习:解题方法 课件53张.pptx
- 全国国家版图知识竞赛题库及答案(中小学组).doc VIP
- 《电子政务外网安全监测平台技术规范》.docx VIP
- 中小学必背飞花令诗词-(春、月、风、花、山、江、人、日、动物、颜色、数字).doc VIP
- DELTA台达-UPS不间断电源系统HPH 系列 20-30-40 kW UPS用户使用手册-操作说明书.pdf
- 2024年商丘永城市污水处理运营有限公司招才引智引进专业技术人员12名笔试模拟试题及答案解析.docx
- 国家开放大学22228《物业信息管理》期末考试复习资料汇编.docx
- DCS系统巡检与维护和故障处理及应急预案.docx VIP
文档评论(0)