【alg4-無向圖】使用DFS找出所有連通分量
阿新 • • 發佈:2020-12-09
問題描述
深度優先搜尋的下一個直接應用就是找出一幅圖的所有連通分量。“與…連通”是一種等價關係,它能夠將所有頂點切分為等價類(連通分量)。
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();
}
}
}