有没有办法使用非递归DFS在无向图中找到双连通组件,以便它可以用于大型图形?
答案 0 :(得分:0)
据我所知,它比一般的dfs复杂一点。 一般的尾递归打开循环相当不错。如果您有多个调用,但不使用子例程结果,那么它的解包也足够好。但是如果你使用结果,那么goto / break或代码重复会有点难看。
我必须像这样做一些丑陋的修改。说实话,我没有机会调试它,把它作为一般想法来制作你自己的代码。
import java.util.Stack;
private void dfs2(Graph G, int u, int v) {
Stack<MyStackFrame> stack = new Stack<>();
int children;
int wi = -1;
int w;
do {
if (wi < 0) { //start dfs
children = 0;
pre[v] = cnt++;
low[v] = pre[v];
for (wi = 0; wi < G.adj(v).length; wi++) {
w = G.adj(v)[wi];
if (pre[w] == -1) {
children++;
stack.push(new MyStackFrame(children, wi, u, v));
//dfs(G, v, w);
wi = -1;
u = v;
v = w;
break;
}
// update low number - ignore reverse of edge leading to v
else if (w != u)
low[v] = Math.min(low[v], pre[w]);
}
if (wi < 0)
break;
// root of DFS is an articulation point if it has more than 1 child
if (u == v && children > 1)
articulation[v] = true;
}
else { // continue dfs
MyStackFrame stackFrame = stack.pop();
u = stackFrame.u;
v = stackFrame.v;
children = stackFrame.children;
wi = stackFrame.wi;
w = G.adj(v)[wi];
// update low number
low[v] = Math.min(low[v], low[w]);
// non-root of DFS is an articulation point if low[w] >= pre[v]
if (low[w] >= pre[v] && u != v)
articulation[v] = true;
wi++;
for (; wi < G.adj(v).length; wi++) {
w = G.adj(v)[wi];
if (pre[w] == -1) {
children++;
stack.push(new MyStackFrame(children, wi, u, v));
//dfs(G, v, w);
wi = -1;
u = v;
v = w;
break;
}
// update low number - ignore reverse of edge leading to v
else if (w != u)
low[v] = Math.min(low[v], pre[w]);
}
if (wi < 0)
break;
// root of DFS is an articulation point if it has more than 1 child
if (u == v && children > 1)
articulation[v] = true;
}
} while (!stack.empty());
}