有向图—拓扑排序,Kosaraju算法
2016-09-21 17:29
197 查看
有向图基本算法
对于有向图的结构,和无向图类似,甚至更简单,有疑问请留言。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]; } }
算法第四版
相关文章推荐
- 【Python排序搜索基本算法】之深度优先搜索、广度优先搜索、拓扑排序、强联通&Kosaraju算法
- 【Python排序搜索基本算法】之深度优先搜索、广度优先搜索、拓扑排序、强联通&Kosaraju算法
- 拓扑排序
- 拓扑排序
- C#有向图拓扑排序
- 有向图强连通分量Kosaraju算法
- 图邻接表C语言实现 拓扑排序
- 拓扑排序 toposort
- HDU-2647 Reward 拓扑排序
- POJ 1094 Sorting It All Out 拓扑排序
- 拓扑排序与关键路径
- 实用算法实现-第 16 篇 拓扑排序
- 【算法导论】拓扑排序
- 拓扑排序
- 杭电hdu 3231 box relations 拓扑排序
- 拓扑排序的STL实现
- 有向图的强连通分量之Kosaraju算法
- poj1094Sorting It All Out(拓扑排序)
- HDU-4324 Triangle LOVE 拓扑排序
- 图的遍历、拓扑排序、最短路径算法