【发布时间】:2016-04-24 19:07:49
【问题描述】:
我目前正在尝试编写一个程序来检查有向图是否是循环的。我不确定我做错了什么(很可能我做错了一切,所以请 StackOverflow,让我看看我的愚蠢!)。我会感谢任何形式的帮助,因为我已经到了不知道可能是什么问题的地步。
输入是邻接表,如:
0: 2 4
1: 2 4
2: 3 4
3: 4
4: 0 1 2 3
(0 指向 2 和 4;1 指向 2 和 4,依此类推...)
我的想法是检查我正在检查的节点是否为“灰色”(部分探索)。如果是,它必须是一个后边,因此是一个循环图。黑边总是被探索或交叉,所以这不应该触发循环消息。我的目标是进行深度优先搜索
如果 A-->B 和 B-->A,这不应触发有关循环的消息(但 A--> B、B-->C、C-->A 应该)。
hasCycle 调用 hasCycleInSubgraph,它通过图形的 Adjency List 递归调用自身。
class qs {
private ArrayList<Integer>[] adjList;
private Stack<Integer> stack;
private ArrayList<Integer> whiteHat;
private ArrayList<Integer> greyHat;
private ArrayList<Integer> blackHat;
public qs(ArrayList<Integer>[] graph) {
this.adjList = graph;
this.stack = new Stack();
this.whiteHat = new ArrayList<Integer>();
this.greyHat = new ArrayList<Integer>();
this.blackHat = new ArrayList<Integer>();
for (Integer h = 0; h < adjList.length; h++) {
whiteHat.add(h);
}
}
public boolean hasCycle() {
for (Integer i = 0; i < adjList.length; i++) {
// System.out.print("Local root is: ");
// System.out.println(i);
whiteHat.remove(i);
greyHat.add(i);
if (hasCycleInSubgraph(i) == true) {
return true;
}
greyHat.remove(i);
blackHat.add(i);
}
return false;
}
public boolean hasCycleInSubgraph(Integer inp) {
if (blackHat.contains(inp)) {
return false;
}
for (Integer branch : adjList[inp]) {
// System.out.print("Adj is: ");
// System.out.println(branch);
if ( greyHat.contains(branch) && !inp.equals(branch) ) {
return true;
}
whiteHat.remove(branch);
greyHat.add(branch);
if ( hasCycleInSubgraph(branch) == true ) {
return true;
}
greyHat.remove(branch);
blackHat.add(branch);
}
return false;
}
}
【问题讨论】:
标签: java recursion graph graph-algorithm depth-first-search