图的边集是可以转化为邻接矩阵的。
邻接矩阵的定义如下:
邻接矩阵(Adjacency Matrix):是表示顶点之间相邻关系的矩阵。设G=(V,E)是一个图,其中V={v1,v2,…,vn}。G的邻接矩阵是一个具有下列性质的n阶方阵:
①对无向图而言,邻接矩阵一定是对称的,而且对角线一定为零(在此仅讨论无向简单图),有向图则不一定如此。
②在无向图中,任一顶点i的度为第i列所有元素的和,在有向图中顶点i的出度为第i行所有元素的和,而入度为第i列所有元素的和。
③用邻接矩阵法表示图共需要n^2个空间,由于无向图的邻接矩阵一定具有对称关系,所以扣除对角线为零外,仅需要存储上三角形或下三角形的数据即可,因此仅需要n(n-1)/2个空间。
边集就是一个图所有边的集合。
这里使用ArrayList edgeSet一个动态的一维数组表示一个无向图的边集。定义:edgeSet中的顺序为奇数与顺序为偶数的共同表示一条边。如下的测试用例:
ArrayList<Integer> edgeSet = new ArrayList<Integer>();
edgeSet.add(1);
edgeSet.add(2);
edgeSet.add(1);
edgeSet.add(3);
edgeSet.add(2);
edgeSet.add(3);
edgeSet.add(2);
edgeSet.add(4);
就是定义存在边集{(1,2),(1,3),(2,3),(2,4)},现在的任务就是把它转化为这个图的邻接矩阵,当然a[0][0]可以忽略,只是用来占位置的:
这里 横轴1-4与数组组成1-4的矩阵元素坐标,如果得到的结果是1,则表示,图中存在此边。比如矩阵元素中a[1][2]=1,则边集一定存在边(1,2),如果是0,则图中必定不存在这条边。比如a[1][4]=0,那么在边集中一定找不到(1,4)这条边。
邻接矩阵虽然看起来是二维数组,但是这里还是一维数组表示,只是输出的话以如下的方法输出,那么输出的结果就是矩阵了。
//输出以一维数组的表示的矩阵
public static void printAdjacencyMatrix(int adjacencyMatrix[]) {
//遍历这个一维数据
for (int i = 0; i < adjacencyMatrix.length; i++) {
//每输出一个元素则同时输出一个制表符
System.out.print(adjacencyMatrix[i] + "\t");
//如果遍历的计数器i+1,刚好是矩阵长度的平方,的倍数,则输出一个换行
if (((i + 1) % Math.sqrt(adjacencyMatrix.length)) == 0) {
System.out.println();
}
}
System.out.println();
}
此方法的关键是换行的输出。比如这个的输出矩阵,i从0开始遇到4,8,12,16则输出一个换行,这个矩阵的长度是25,因此便有了如上的“如果遍历的计数器i+1,刚好是矩阵长度的平方,的倍数,则输出一个换行”:
要把边集转化成邻接矩阵,首先要以如下的情况初始化邻接矩阵,布置好横轴、纵轴,当然,那个0只是为了占领那个邻接矩阵a[0][0]这个没有意义的位置。
此时应该先根据边集求出点集。根据边集求出点集在《【Java】为ArrayList去重》(点击打开链接)已经介绍过了,这里不再赘述,就是一个边集元素去重的过程。
由于邻接矩阵式由一维数组表示的。因此纵轴的位置是 计数器i x 点集长度+1,比如上面的数组,点集就是{1,2,3,4},长度为4,纵轴1,2,3,4分别在一维数组的5,11,16,21这个位置,因此便有了如下的代码:
System.out.println("初始化邻接矩阵:");
ArrayList<Integer> nodeSet = new ArrayList(new HashSet(edgeSet));
int adjacencyMatrix[] = new int[(nodeSet.size() + 1)
* (nodeSet.size() + 1)];
for (int i = 0; i <= nodeSet.size(); i++) {
if (i == 0) {
adjacencyMatrix[i] = 0;
} else {
adjacencyMatrix[i] = nodeSet.get(i - 1);
adjacencyMatrix[i * (nodeSet.size() + 1)] = nodeSet.get(i - 1);
}
}
接着,是最核心的一步,首先要遍历点集,求出这个点的邻接节点。点的邻接节点根据这个点与边集,如下方法求出:
//求点的邻接节点
public static ArrayList<Integer> neighbourNode(ArrayList<Integer> edgeSet,
int node) {
//设置一个动态数组ArrayList保存此点的邻接节点
ArrayList<Integer> neighbourNode = new ArrayList<Integer>();
//遍历边集,看那条边拥有此点,那么这条边的另一点,就是此点的邻接节点
for (int i = 0; i < edgeSet.size(); i = i + 2) {
if (node == edgeSet.get(i)) {
neighbourNode.add(edgeSet.get(i + 1));
}
}
for (int i = 1; i < edgeSet.size(); i = i + 2) {
if (node == edgeSet.get(i)) {
neighbourNode.add(edgeSet.get(i - 1));
}
}
return neighbourNode;
}
求出点的邻接节点集之后,就开始遍历这个点的邻接节点集,更新邻接矩阵中的元素。找出这点与其邻接节点,组成的一个矩阵元素坐标,把这个这个矩阵元素坐标所对应的值从0改成1,对所有点求出其邻接节点,之后再该上面的方法,更新邻接矩阵,因此便有了如下的代码:
System.out.println("最终的邻接矩阵:");
for (int i =1; i <= nodeSet.size(); i++) {
ArrayList<Integer> neighbourNode=neighbourNode(edgeSet,adjacencyMatrix[i]);
for(int j=0;j<neighbourNode.size(); j++){
for(int k=0;k<=nodeSet.size();k++){
if(neighbourNode.get(j)==adjacencyMatrix[k * (nodeSet.size()+1)]){
adjacencyMatrix[(nodeSet.size()+1)*k+i]=1;
}
}
}
}
printAdjacencyMatrix(adjacencyMatrix);
至此,边集就最终转化成邻接矩阵了。全代码如下:
import java.util.*;
public class edgeSet_AdjacencyMatrix {
//求点的邻接节点
public static ArrayList<Integer> neighbourNode(ArrayList<Integer> edgeSet,
int node) {
//设置一个动态数组ArrayList保存此点的邻接节点
ArrayList<Integer> neighbourNode = new ArrayList<Integer>();
//遍历边集,看那条边拥有此点,那么这条边的另一点,就是此点的邻接节点
for (int i = 0; i < edgeSet.size(); i = i + 2) {
if (node == edgeSet.get(i)) {
neighbourNode.add(edgeSet.get(i + 1));
}
}
for (int i = 1; i < edgeSet.size(); i = i + 2) {
if (node == edgeSet.get(i)) {
neighbourNode.add(edgeSet.get(i - 1));
}
}
return neighbourNode;
}
//输出以一维数组的表示的矩阵
public static void printAdjacencyMatrix(int adjacencyMatrix[]) {
//遍历这个一维数据
for (int i = 0; i < adjacencyMatrix.length; i++) {
//每输出一个元素则同时输出一个制表符
System.out.print(adjacencyMatrix[i] + "\t");
//如果遍历的计数器i+1,刚好是矩阵长度的平方,的倍数,则输出一个换行
if (((i + 1) % Math.sqrt(adjacencyMatrix.length)) == 0) {
System.out.println();
}
}
System.out.println();
}
public static void edgeSet_AdjacencyMatrix(ArrayList<Integer> edgeSet) {
System.out.println("初始化邻接矩阵:");
ArrayList<Integer> nodeSet = new ArrayList(new HashSet(edgeSet));
int adjacencyMatrix[] = new int[(nodeSet.size() + 1)
* (nodeSet.size() + 1)];
for (int i = 0; i <= nodeSet.size(); i++) {
if (i == 0) {
adjacencyMatrix[i] = 0;
} else {
adjacencyMatrix[i] = nodeSet.get(i - 1);
adjacencyMatrix[i * (nodeSet.size() + 1)] = nodeSet.get(i - 1);
}
}
printAdjacencyMatrix(adjacencyMatrix);
System.out.println("最终的邻接矩阵:");
for (int i =1; i <= nodeSet.size(); i++) {
ArrayList<Integer> neighbourNode=neighbourNode(edgeSet,adjacencyMatrix[i]);
for(int j=0;j<neighbourNode.size(); j++){
for(int k=0;k<=nodeSet.size();k++){
if(neighbourNode.get(j)==adjacencyMatrix[k * (nodeSet.size()+1)]){
adjacencyMatrix[(nodeSet.size()+1)*k+i]=1;
}
}
}
}
printAdjacencyMatrix(adjacencyMatrix);
}
public static void main(String[] args) {
ArrayList<Integer> edgeSet = new ArrayList<Integer>();
edgeSet.add(1);
edgeSet.add(2);
edgeSet.add(1);
edgeSet.add(3);
edgeSet.add(2);
edgeSet.add(3);
edgeSet.add(2);
edgeSet.add(4);
edgeSet_AdjacencyMatrix(edgeSet);
}
}
边集{(1,2),(1,3),(2,3),(2,4)}的运行结果: