有向图—拓扑排序,Kosaraju算法
来源:互联网 发布:经济型酒店数据分析 编辑:程序博客网 时间:2024/04/25 11:49
有向图基本算法
- 对于有向图的结构,和无向图类似,甚至更简单,有疑问请留言。
1>有向图的数据结构
package graphTheory;/** * @author luoz * @date 2016年9月19日 下午9:26:21 **/public class Digraph { private final int V; private int E; private Bag<Integer>[] adj; public Digraph(int V) { this.V = V; this.E = 0; adj = (Bag<Integer>[])new Bag[V]; for(int i = 0;i<V;i++) adj[i] = new Bag<>(); } public int V() { return V; } public int E() { return E; } public void addEdge(int v,int w) { adj[v].add(w); E++; } public Iterable<Integer> adj(int v) { return adj[v]; } public Digraph reverse() { Digraph g = new Digraph(V); for(int j = 0; j<V;j++) for(int w : adj[j]) g.addEdge(w,j); return g; }}
- 基于深度优先遍历的顶点排序
1>前序:在递归调用之前将顶点加入队列;
2>后序:在递归调用之后将顶点加入队列;
3>逆后序:在递归调用之后将顶点压入栈;
package graphTheory;import java.util.*;import javax.management.Query;/** * @author luoz * @date 2016年9月19日 下午10:11:48 **/public class DepthFirstOrder { private boolean[] marked; //pre order private Queue<Integer> pre; //postorder private Queue<Integer> post; //reverse postorder private Stack<Integer> repost; public DepthFirstOrder(Digraph g) { marked = new boolean[g.V()]; pre = new LinkedList<>(); post = new LinkedList<>(); repost = new Stack<>(); for(int i = 0;i<g.V();i++) if(!marked[i]) dfs(g,i); } private void dfs(Digraph g,int v) { pre.add(v); marked[v] = true; for(int w : g.adj(v)) if(!marked[w]) dfs(g,w); post.add(v); repost.add(v); } public Iterable<Integer> pre() { return pre; } public Iterable<Integer> post() { return post; } public Iterable<Integer> reversepost() { return repost; }}
- 检测有无环
package graphTheory;import java.io.File;import java.util.Stack;/** * @author luoz * @date 2016年9月19日 下午9:48:41 **/public class DirectedCycle { private boolean[] marked; private int[] edgeTo; //All vertices of a directed loop private Stack<Integer> cycle; //resursion all vertices of the cycle private boolean[] onStack; private boolean marked(int v) { return marked[v]; } public boolean hasCycle() { return cycle != null; } public DirectedCycle(Digraph g) { marked = new boolean[g.V()]; edgeTo = new int[g.V()]; onStack = new boolean[g.V()]; for(int i = 0;i<g.V();i++) if(!marked[i]) dfs(g,i); } private void dfs(Digraph g,int v) { marked[v] = true; onStack[v] = true; for(int w : g.adj(v)) { if(this.hasCycle()) return; else if(!marked[w]) { edgeTo[w] = v; dfs(g,w); } else if(onStack[w]) { cycle = new Stack<Integer>(); for(int i = v; i != w; i = edgeTo[i]) cycle.push(i); cycle.push(w); cycle.push(v); } onStack[v] = false; } } public Iterable<Integer> cycle() { return cycle; } /*测试代码,从文件中读取的,可以自己写测试代码*/ public static void main(String[] args) { FileIo fileio = new FileIo(); String s = fileio.characterReader(new File("cycle.txt")); String[] st = s.split(","); Digraph g = new Digraph(13); int E = st.length; for(int i = 0;i<E;i++) { String[] str = st[i].split(" "); g.addEdge(Integer.parseInt(str[0]),Integer.parseInt(str[1])); } DirectedCycle cc = new DirectedCycle(g); System.out.println(cc.hasCycle()); System.out.println(cc.cycle); }}
拓扑排序
拓扑排序只针对有向无环图。
一幅有向无环图的拓扑排序,也就是所有顶点的逆后序排列。
package graphTheory;/** * @author luoz * @date 2016年9月20日 上午8:30:05 **/public class Topological { private Iterable<Integer> order; public Topological(Digraph g) { DirectedCycle hascycle = new DirectedCycle(g); if(!hascycle.hasCycle()) { DepthFirstOrder df = new DepthFirstOrder(g); order = df.reversepost(); } } public Iterable<Integer> order() { return order; }}
Kosaraju算法
计算强连通分量的算法。
主要运用了图G的反转和顶点排序的逆后序。
package graphTheory;/** * @author luoz * @date 2016年9月20日 上午9:08:53 **/public class KosarajuSCC { private boolean[] marked; private int[] id; private int count; public KosarajuSCC(Digraph g) { marked = new boolean[g.V()]; id = new int[g.V()]; // DepthFirstOrder df = new DepthFirstOrder(g.reverse()); for(int i : df.reversepost()) if(!marked[i]) { dfs(g,i); count++; } } private void dfs(Digraph g,int v) { marked[v] = true; id[v] = count; for(int w :g.adj(v)) if(!marked[w]) dfs(g,w); } public int count() { return count; } public boolean connected(int v,int w) { return id[v] == id[w]; }}
算法第四版
0 0
- 有向图—拓扑排序,Kosaraju算法
- 有向图中寻找强连通分量(环)和拓扑排序——Kosaraju、Trajan、Gabow算法
- 数据结构——有向图(拓扑排序算法)
- kosaraju算法-求解有向图SCC
- 有向图--拓扑排序
- 《算法4》有向图与DAG与Kosaraju算法
- 数据结构与算法之有向图的拓扑排序
- java数据结构与算法-有向图的拓扑排序
- 有向图的拓扑排序算法JAVA实现
- 算法 有向无环图 拓扑排序
- Kosaraju算法求有向强连通分量,缩点后是DAG的拓扑序列(从小到大)
- 有向图强连通分量Kosaraju算法
- hdu1269 有向图 强连通分量 kosaraju 算法
- hdu2767 Proving Equivalences,有向图强联通,Kosaraju算法
- Kosaraju算法查找有向图的强连通分支
- Kosaraju算法 有向图的强连通分量
- 有向图Kosaraju算法的正确性证明
- 有向图的强连通分解--Kosaraju算法
- 不登录CSDN就获取需要登陆的JSON数据 (已解决)
- 数据与统计
- NHibernate之映射文件配置说明
- RecyclerView实现Listview-1
- 自动化运维工具SaltStack详细部署
- 有向图—拓扑排序,Kosaraju算法
- 冒泡排序
- 也学习Java/JVM/GC (二)
- 从源码入手理解Window和WindowManager
- JavaScript排序之归并排序
- App瘦身最佳实践(分析了微信、淘宝、微博图片文件的放法)
- RPC概念和应用
- RecyclerView的使用教程2
- 第三周 项目3-求集合并集