拓扑排序算法
来源:互联网 发布:java简单金字塔代码 编辑:程序博客网 时间:2024/06/15 07:04
拓扑排序算法
@(算法学习)
AOV网
说到拓扑排序首先需要看的一个概念是Activity On Vertex 网。关于AOE前面做过具体的探究。
http://blog.csdn.net/u011240016/article/details/53171808?locationNum=1&fps=1
关于如何寻找最大路径文中有具体的思考。
而既然活动可以在边上,就必然意味着,活动可以在结点上。
这样做有什么含义吗?
有。在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图就可以用于研究哪些活动必须先完成了。
比如常见的选课,有些课是需要先导课程的,如果没有学过,就没法选。课程量少时,当然可以一眼看穿,如果全校范围内,课程数很多,就需要借助计算机来帮忙了。
AOV中不允许出现回路。这个很容易理解,即,你选的课程先导课程不能是更难的课吧。只有学完了简单的先导课才能去学难一点的课程。能直接学更难的,再反过来修先导课吗?如果硬是说可以,我也不说啥了。。总而言之,我们认定了,AOV不许有回路。反之,拓扑排序也可以用于检测图中是否有环。
拓扑排序的思想
设G=(V,E),是一个具有n个顶点的有向图,V中的顶点序列
- 从顶点
Vi 到Vj 有一条路径,则在顶点序列中顶点Vi 必须在顶点Vj 之前。
这种讲法是为了更加容易编码,实际自己理解时,可以这样想,找到一个没有箭头指向自己的结点,去掉它以及与它相连的边;再找这样的没有箭头指向自己的结点,依次继续。如果最终所有的结点都能被去掉,则这个AOV可以用拓扑排序构造拓扑序列。这个有向图就没有环。
此外,拓扑排序不一定就是一个。
输出拓扑序列的量化为步骤就是:
- 从AOV网中选择一个没有前驱的顶点并输出;
- 从AOV网中删除该结点,并删除所有以该结点出发的的弧。有时候说是弧尾,在有向图中,弧尾是出发点,弧头是结尾。这是根据箭头所在的地方称之为头得来的。
结果分析:
- AOV中全部顶点被输出,则AOV网中不存在回路。
- AOV网中顶点未被全部输出,则AOV网中存在回路。
拓扑排序算法基于的数据结构
一般来说,拓扑排序中的图的存储结构用的是邻接表。
为什么?
因为拓扑排序时需要查找以某个顶点出发的弧,此外,还需要查找入度为0的结点。即,找没有箭头指向自己的结点。
为此,在顶点表中加入一个入度域即可满足全部要求。
如何查找没有前驱的顶点呢?
查找入度为0的顶点。这还不够优化,即,为了加快查找,可以用栈来存放。把度为0的顶点存放在栈中。
先写伪代码,具体实现很简单:
- 初始化栈S,计数变量cnt;
- 扫描顶点表,将入度为0的顶点压栈
- 当栈非空时循环:
- 栈顶结点
Vi 出栈,输出Vj ,并且cnt++; - 将顶点
Vj 的各个邻接点入度减1; - 将新的入度为0的顶点入栈
- 栈顶结点
具体代码:
void TopSort(){ int top = -1, cnt = 0; // 顺序栈S并初始化,计数初始化,top指向栈顶元素 for(int i = 0; i <vertexNum; i++) // 扫描顶点表,找入度为0的点 { if(adjList[i].in == 0) { S[++top] = i; // 先更新top指针 } while(top != -1) // 栈非空 { int j = S[top--]; // 取出栈顶并更新top cout << adjList[j].vertex; cnt++; p = adjList[j].firstEdge; while(p != NULL)// 找出顶点j的所有出边 { k = p->adjvex; adjList[k].in--; //所有与j相邻的结点入度减1 if(adjList[k].in == 0) { S[++top] = k; //加入栈 } p = p->next; // 邻接表下的next指向的是另一个兄弟 } } } if(cnt < vertexNum) cout<< "有回路" << endl;}
所以可见时间复杂度是
- 贪婪算法--- 拓扑排序
- 贪婪算法--- 拓扑排序
- 拓扑排序算法
- 拓扑排序算法
- 拓扑排序算法
- 【算法导论】拓扑排序
- 【算法导论】拓扑排序
- 拓扑排序算法
- 拓扑排序算法
- 拓扑排序算法
- 拓扑排序算法
- 算法 拓扑排序
- 算法 拓扑排序
- 拓扑排序算法
- 算法摘记 拓扑排序
- 拓扑排序算法
- 【数据结构】拓扑排序算法
- 拓扑排序算法模板
- JavaScript面向对象之-----封装
- Android中得到SharedPreference全面总结
- setRequestedOrientation
- 测试图片
- 自定义Activity标题栏(Title bar)和窗体显示状态操作(requestWindowFeature()的应用)
- 拓扑排序算法
- 关于Android中listView的复用及优化问题详解,应用开发者应多多使用,是app更顺畅,让用户更好体验!
- android自定义标题栏
- 解决ScrollView下嵌套ListView、GridView显示不全的问题
- [unreal4入门系列之十二] 在UE4中创建非玩家角色(NPC)
- android:scaleType属性
- C#泛型161122
- 解决Error:Execution failed for task ':app:transformClassesWithJarMergingForDebug'问题
- How to Install JAVA on Ubuntu