图论算法(6)(更新版) --- Tarjan算法求强连通分量
来源:互联网 发布:oimo.js 编辑:程序博客网 时间:2024/06/04 22:53
在之前的Tarjan算法求连通分量博文中(点此查看),代码实现用到了固定大小数组,扩展起来似乎并不是很方便,在java里这样来实现本身就是不太妥当的,所以下面给出一个更新版本的代码实现:
package test;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.Set;import java.util.Stack;public class TarjanSCC<NodeType> {int index;Map<NodeType, LinkedList<NodeType>> graph;Map<NodeType, Integer> indexMap;Map<NodeType, Integer> lowLinkMap;Stack<NodeType> stack;List<List<NodeType>> result;public TarjanSCC(Map<NodeType, LinkedList<NodeType>> graph) {this.index = 0;this.graph = graph;this.indexMap = new HashMap<NodeType, Integer>();this.lowLinkMap = new HashMap<NodeType, Integer>();this.result = new ArrayList<List<NodeType>>();}public List<List<NodeType>> tarjan() {this.index = 0;stack = new Stack<NodeType>();List<List<NodeType>> result = new ArrayList<List<NodeType>>();for (NodeType v : this.graph.keySet()) {if (indexMap.get(v) == null) {result.addAll(this.strongConnect(v));}}return result;}public List<NodeType> getSuccessors(NodeType v,Map<NodeType, LinkedList<NodeType>> graph) {List<NodeType> successors = new ArrayList<NodeType>();Set<NodeType> set = graph.keySet();Iterator<NodeType> it = set.iterator();while (it.hasNext()) {NodeType node = it.next();if (node.equals(v)) {successors.addAll(graph.get(node));break;}}return successors;}public List<List<NodeType>> strongConnect(NodeType v) {indexMap.put(v, index);lowLinkMap.put(v, index);index++;stack.push(v);for (NodeType w : getSuccessors(v, graph)) {if (indexMap.get(w) == null) {strongConnect(w);lowLinkMap.put(v, Math.min(lowLinkMap.get(v), lowLinkMap.get(w)));} else if (stack.contains(w)) {lowLinkMap.put(v, Math.min(lowLinkMap.get(v), indexMap.get(w)));}}if (lowLinkMap.get(v).equals(indexMap.get(v))) {List<NodeType> sccList = new ArrayList<NodeType>();while (true) {NodeType w = stack.pop();sccList.add(w);if (w.equals(v)) {break;}}if (sccList.size() > 1) {result.add(sccList);}}return result;}}
下面是主函数调用代码:
package test;import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;import java.util.HashMap;import java.util.LinkedList;import java.util.List;import java.util.Map;public class TestTarjan {Map<Integer, LinkedList<Integer>> graph = new HashMap<Integer, LinkedList<Integer>>();public TestTarjan(String path) {try {BufferedReader br = new BufferedReader(new FileReader(path));String[] strArray;String str;while ((str = br.readLine()) != null) {strArray = str.split("\\s");int a = Integer.parseInt(strArray[0]);int b = Integer.parseInt(strArray[1]);if (graph.containsKey(a)) {graph.get(a).add(b);} else {LinkedList<Integer> linkedlist = new LinkedList<Integer>();linkedlist.add(b);graph.put(a, linkedlist);}}br.close();} catch (IOException e) {e.printStackTrace();}}public List<List<Integer>> getResult(){TarjanSCC<Integer> tarjanScc = new TarjanSCC<Integer>(graph);return tarjanScc.tarjan();}public static void main(String[] args) {TestTarjan testTarjan = new TestTarjan("c:/tarjan.txt");System.out.println(testTarjan.getResult());}}
这里赋上一组简单的测试数据:
1 2
2 3
3 1
4 2
3 4
3 5
5 6
6 7
7 5
7 8
8 9
9 10
10 8
1 0
- 图论算法(6)(更新版) --- Tarjan算法求强连通分量
- Tarjan算法(求强连通分量)
- tarjan 算法(求强连通分量)
- 图论算法(6) --- Tarjan算法求强连通分量
- 刻录光盘(Tarjan算法求强连通分量)
- Tarjan求有向图的强连通分量(Tarjan算法描述)
- Tarjan求有向图的强连通分量(Tarjan算法描述)
- Tarjan求有向图的强连通分量(Tarjan算法描述)
- 强连通分量(tarjan算法)
- tarjan算法求图中环(强连通分量)
- tarjan算法模板(强连通分量)
- Tarjan算法求强连通分量
- 求强连通分量的Tarjan算法
- Tarjan算法-求强连通分量
- tarjan算法求强连通分量
- tarjan算法求强连通分量
- 求强连通分量之tarjan算法
- tarjan算法求强连通分量
- [JIRA] 最新Linux版本 jira6.3.6安装汉化破解以及数据迁移
- Django中的lambda函数
- The substring() Method in JDK 6 and JDK 7 (jdk6中的substring()会造成内存泄漏)
- java 自动装箱与拆箱
- MATLAB GUI对话框设计
- 图论算法(6)(更新版) --- Tarjan算法求强连通分量
- Word Search [leetcode]
- 怎么上谷歌E9加速器分享安卓平板怎么上Google注册gmail
- windows server 2012 活动目录部署系列(七)域控制器的常规卸载
- PDU编码(非常经典)
- 内存泄露简述
- QRadioButton分组且无边框的简单实现
- 列书闲读
- hdu 5038 Grade(水题)