基于入度的拓扑排序(Kahn's Algorithm)
2016-05-11 20:25
375 查看
本文中的图用邻接链表来表示
拓扑排序只针对于有向无环图(DAG)才能完成,所以可以利用拓扑排序来判断一个有向图是否有环。
某一点的入度:图中指向该顶点的边的个数
图1 :DAG
以上图简单说明,点0的入度即为2。下面介绍拓扑排序的算法流程:
Step 1:计算出所有顶点的入度。
Step2 :将所有入度为0的点加入到一个队列。
Step3 :将队头元素取出,然后pop()。
1.count变量表示访问过的顶点个数,将count加1.
2.用top数组将每一次出队的元素保存起来。
3.将这个点的所有相邻点的入度减一,如果某个相邻点的入度减小为0,则将这个相邻点加入到队列中。
Step4 :重复Step3直到队列为空
Step5 :如果count和顶点个数相同,则将top数组中的元素按序输出就是排序后的结果;如果count不等于顶点个数
(在不相等的情况下,一般是count大于顶点个数),说明图中存在环,拓扑排序无法完成。
入度的计算方法:
遍历所有的顶点,每一次遍历,将该点所有相邻的点的入度都加1。所有的点遍历完后,入度就计算完成了。
具体拓扑排序代码如下:
结果是:4 5 2 0 3 1
拓扑排序只针对于有向无环图(DAG)才能完成,所以可以利用拓扑排序来判断一个有向图是否有环。
某一点的入度:图中指向该顶点的边的个数
图1 :DAG
以上图简单说明,点0的入度即为2。下面介绍拓扑排序的算法流程:
Step 1:计算出所有顶点的入度。
Step2 :将所有入度为0的点加入到一个队列。
Step3 :将队头元素取出,然后pop()。
1.count变量表示访问过的顶点个数,将count加1.
2.用top数组将每一次出队的元素保存起来。
3.将这个点的所有相邻点的入度减一,如果某个相邻点的入度减小为0,则将这个相邻点加入到队列中。
Step4 :重复Step3直到队列为空
Step5 :如果count和顶点个数相同,则将top数组中的元素按序输出就是排序后的结果;如果count不等于顶点个数
(在不相等的情况下,一般是count大于顶点个数),说明图中存在环,拓扑排序无法完成。
入度的计算方法:
遍历所有的顶点,每一次遍历,将该点所有相邻的点的入度都加1。所有的点遍历完后,入度就计算完成了。
具体拓扑排序代码如下:
#include #include #include #include using namespace std; class Graph{ private: int V; list *adj; public: Graph(int V){ this->V =V; adj = new list[V]; } //有向图 void addEdge(int src, int dest){ adj[src].push_back(dest); } void toplogicSortInd(){ vector indegree(V,0); queue q; vectortop; //用来存储拓扑排序的结果 int count = 0; //记录访问过的顶点个数 //step1:计算入度 for(int v = 0; v < V; v++){ list::iterator itr; for(itr = adj[v].begin(); itr != adj[v].end(); itr++){ indegree[*itr]++; } } //step2:将入度为0的点入队 for(int u = 0; u < V; u++){ if(indegree[u] == 0) q.push(u); } //step3 && step4 while(!q.empty()){ int v = q.front(); top.push_back(v); q.pop(); count++; list::iterator itr; for(itr = adj[v].begin(); itr!=adj[v].end(); itr++){ if(--indegree[*itr] == 0) q.push(*itr); } } if(count != V){ cout << "\n图中存在环,拓扑排序无法完成。\n"; return; } else{ for(int i = 0; i < V; i++){ cout << top[i] << " "; } cout << endl; } } }; // Driver program to test above functions int main() { // Create a graph given in the above diagram Graph g(6); g.addEdge(5, 2); g.addEdge(5, 0); g.addEdge(4, 0); g.addEdge(4, 1); g.addEdge(2, 3); g.addEdge(3, 1); cout << "拓扑排序的一种结果是 \n"; g.toplogicSortInd(); return 0; }
结果是:4 5 2 0 3 1
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- 渗透技术一瞥(图)
- 图片引发的溢出危机(图)
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C++联合体转换成C#结构的实现方法
- C#实现的算24点游戏算法实例分析