深度优先遍历 & 计算图的连通分量

连通分量

  • 相当于森林中的有几棵树对应到图中的概念;
  • 连通分量是“树的个数”,是一个整数

用深度优先遍历计算图的连通分量代码实现

  • 数组 id 就像是并查集中用来存储元素所属集合的数组,存储的是每个节点所属的群体
  • id 数组的值做 “GROUP BY” 操作,就得到了这张图的连通分量
  • 连通分量由 ccount 保存;
package bobo.algo;

// 求无权图的联通分量
public class Components {

    Graph G;                    // 图的引用
    private boolean[] visited;  // 记录dfs的过程中节点是否被访问
    private int ccount;         // 记录联通分量个数
    private int[] id;           // 每个节点所对应的联通分量标记

    // 图的深度优先遍历
    void dfs( int v ){

        visited[v] = true;
        id[v] = ccount;

        for( int i: G.adj(v) ){
            if( !visited[i] )
                dfs(i);
        }
    }

    // 构造函数, 求出无权图的联通分量
    public Components(Graph graph){

        // 算法初始化
        G = graph;
        visited = new boolean[G.V()];
        id = new int[G.V()];
        ccount = 0;
        for( int i = 0 ; i < G.V() ; i ++ ){
            visited[i] = false;
            id[i] = -1;
        }

        // 求图的联通分量
        for( int i = 0 ; i < G.V() ; i ++ )
            if( !visited[i] ){
                dfs(i);
                ccount ++;
            }
    }

    // 返回图的联通分量个数
    int count(){
        return ccount;
    }

    // 查询点v和点w是否联通
    boolean isConnected( int v , int w ){
        assert v >= 0 && v < G.V();
        assert w >= 0 && w < G.V();
        return id[v] == id[w];
    }
}

你可能感兴趣的:(深度优先遍历 & 计算图的连通分量)