上面的图G包含了"A,B,C,D,E,F,G,H,I"共9个顶点,而且包含了"(A,C),(A,D),(A,F),(B,C),(C,D),(E,G),(F,G),(H.I)"共8条边。G是无向图,因此边(A,C)和边(C,A)是同一条边;这里列举边时,是按照字母先后顺序列举的。
上图右边的矩阵是G在内存中的邻接矩阵示意图。A[i][j]=1表示第i个顶点与第j个顶点是邻接点,A[i][j]=0则表示它们不是邻接点;而A[i][j]表示的是第i行第j列的值;例如,A[1,2]=1,表示第1个顶点(即顶点B)和第2个顶点(C)是邻接点。
首先创建MatrixUDG,它是邻接矩阵对应的类。其中变量mVexs用于保存顶点,变量mMatrix则是用于保存矩阵信息的二维数组。例如,mMatrix[i][j]=1,则表示”顶点i(即mVexs[i])”和”顶点j(即mVexs[j])”是邻接点;mMatrix[i][j]=0,则表示它们不是邻接点。
创建图后,通过BFS求连同分量的个数,附代码:
public class MatrixUDG {
public char[] mVexs; // 顶点集合
public int[][] mMatrix; // 邻接矩阵
/*
* 创建图
* vexs -- 顶点节点
* edges -- 边节点
*/
public MatrixUDG(char[] vexs, char[][] edges) {
// 初始化"顶点数"和"边数"
int vlen = vexs.length;
int elen = edges.length;
// 初始化"顶点"
mVexs = new char[vlen];
for (int i = 0; i < mVexs.length; i++)
mVexs[i] = vexs[i];
// 初始化"边"
mMatrix = new int[vlen][vlen];
for (int i = 0; i < elen; i++) {
// 读取边的起始顶点和结束顶点
int p1 = getPosition(edges[i][0]);
int p2 = getPosition(edges[i][1]);
mMatrix[p1][p2] = 1;
mMatrix[p2][p1] = 1;
}
}
private int getPosition(char ch) {
for(int i=0; i<mVexs.length; i++)
if(mVexs[i]==ch)
return i;
return -1;
}
/*
* 打印图
*/
public void print() {
System.out.printf("Martix Graph:\n");
for (int i = 0; i < mVexs.length; i++) {
for (int j = 0; j < mVexs.length; j++)
System.out.printf("%d ", mMatrix[i][j]);
System.out.printf("\n");
}
}
public static void main(String[] args) {
char[] vexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G','H','I'};
char[][] edges = new char[][]{
{'A', 'C'},
{'A', 'D'},
{'A', 'F'},
{'B', 'C'},
{'C', 'D'},
{'E', 'G'},
{'F', 'G'},
{'H', 'I'}};
MatrixUDG pG;
pG = new MatrixUDG(vexs, edges);
pG.print(); // 打印图
System.out.println(pG.GetCount(pG.mMatrix));
}
public int GetCount(int[][] grid){
int count = 0;
int verNum = grid.length;
boolean[] visited = new boolean[verNum];
for (int i = 0; i < verNum; i++) {
if (!visited[i])
{
BFS(grid,verNum,i,visited);
count++;
}
}
return count;
}
public static void BFS(int[][] G, int edgeNum, int begin, boolean[] visited)
{
Queue<Integer> Q=new LinkedList<Integer>();
Q.add(begin);
visited[begin] = true;
while (!Q.isEmpty())
{
int tmp = Q.peek();
Q.poll();
for (int i = 0; i < edgeNum; i++)
{
if (!visited[i] && G[tmp][i]==1)
{
Q.add(i);
visited[i] = true;
}
}
}
}
}