【Java】边集转化为邻接矩阵

图的边集是可以转化为邻接矩阵的。

邻接矩阵的定义如下:

邻接矩阵(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)}的运行结果:

就微笑着同清风合力染绿大地,这样才算善待生命,不负年华。

【Java】边集转化为邻接矩阵

相关文章:

你感兴趣的文章:

标签云: