簡體   English   中英

非遞歸算法查找雙向連接的組件

[英]Non-Recursive algorithm to find biconnected components

是否可以使用非遞歸DFS在無向圖中找到雙向連接的組件,以便將其用於大型圖?

據我所知,它比通用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());       
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM