1. 程式人生 > 其它 >【alg4-無向圖】使用DFS找出所有連通分量

【alg4-無向圖】使用DFS找出所有連通分量

技術標籤:演算法演算法

問題描述

深度優先搜尋的下一個直接應用就是找出一幅圖的所有連通分量。“與…連通”是一種等價關係,它能夠將所有頂點切分為等價類(連通分量)。

API

連通分量的API:

API功能
CC(Graph G)預處理建構函式
boolean connected(int v, int w)v和w連通嗎
int count()連通分量數
int id(int v)v所在的連通分量的識別符號(0~count()-1)

實現

CC的實現使用了marked[]陣列來尋找一個頂點作為每個連通分量中深度優先搜尋的起點。遞迴的深度優先搜尋第一次呼叫的引數是頂點0——它會標記所有與0連通的頂點。然後建構函式中的for迴圈會查詢每個沒有被標記的頂點並遞迴呼叫dfs()來標記和它相鄰的所有頂點。另外它還使用了一個以頂點作為索引的陣列id[],將同一個連通分量中的頂點和連通分量的識別符號關聯起來(int值)。

程式碼

其中圖用到了Graph
Bag.java:

package section1_3;

import java.util.Iterator;
import java.util.NoSuchElementException;

public class Bag<Item> implements Iterable<Item> {
    private Node<Item> first;
    private int n;

    private class Node<Item> {
        Item item;
        Node<
Item>
next; } public Bag() { first = null; n = 0; } public boolean isEmpty() { return first == null; } public int size() { return n; } public void add(Item item) { Node oldfirst = first; first = new Node<>();
first.item = item; first.next = oldfirst; n++; } @Override public Iterator<Item> iterator() { return new LinkedIterator(first); } private class LinkedIterator implements Iterator<Item> { private Node<Item> current; public LinkedIterator(Node<Item> first) { current = first; } public boolean hasNext() { return current != null; } public void remove() { throw new UnsupportedOperationException(); } public Item next() { if (!hasNext()) throw new NoSuchElementException(); Item item = current.item; current = current.next; return item; } } }

CC.java:

package section4_1;

import section1_3.Bag;

public class CC {

    private boolean[] marked;
    private int[] id;
    private int count;

    public CC(Graph G) {
        marked = new boolean[G.V()];
        id = new int[G.V()];
        for (int v = 0;v < G.V();v++) {
            if (!marked[v]) {
                dfs(G,v);
                count++;
            }
        }
    }

    public void dfs(Graph G, int v) {
        marked[v] = true;
        id[v] = count;
        for (int w : G.adj(v)) {
            if (!marked[w]) {
                dfs(G,w);
            }
        }
    }

    public boolean connected(int v, int w) {
        return id[v] == id[w];
    }

    public int id(int v) {
        return id[v];
    }

    public int count() {
        return count;
    }

    public static void main(String[] args) {
        int[][] data = {
                {0,5},
                {4,3},
                {0,1},
                {9,12},
                {6,4},
                {5,4},
                {0,2},
                {11,12},
                {9,10},
                {0,6},
                {7,8},
                {9,11},
                {5,3}
        };
        int vn = 13;
        int e = 13;
        Graph graph = new Graph(vn,e,data);
        CC cc = new CC(graph);

        int M = cc.count();
        System.out.println(M + " components");

        Bag<Integer>[] components;
        components = (Bag<Integer>[]) new Bag[M];

        for (int i = 0;i < M;i++) {
            components[i] = new Bag<>();
        }

        for (int v = 0;v < graph.V();v++) {
            components[cc.id(v)].add(v);
        }

        for (int i = 0;i < M;i++) {
            for (int v : components[i]) {
                System.out.print(v + " ");
            }
            System.out.println();
        }
    }
}

在這裡插入圖片描述