使用邻接矩阵表示图详解

说明

  1. 图是一种可以实现多对多的数据结构,不像链表和树,他们只能建立一对一的关系,每个节点只有前驱或者后继节点,不能实现多对多
  2. 对于图的描述可以使用邻接矩阵或者邻接表
  3. 使用邻接矩阵描述图:
  • 创建集合保存图的顶点
  • 创建二维数组即矩阵描述顶点与顶点之间的关系,顶点与顶点之间用权值来描述,若权值为1,表明两个顶点是相连的,若权值为0,表明两个顶点不相连
  • 考虑如何用二维数组描述???
  • 使用有序集合存储顶点,那么存储的顶点在集合中是有序的,使用他们在集合中的下标表示它们在数组中的索引
  • 二维数组的行和列分别用集合的下标来表示,则能完整的表示各个顶点之间的关系
  • 若两个顶点相连,则他们对应二维数组相应位置的元素为1,否则为0
  • 即可实现邻接矩阵表示图
  1. 但是邻接矩阵有一个问题,就是会浪费大量的空间,比如如果两个顶点之间没有连接,也需要用0来表示
  2. 因此另一种表示图的方法,可以解决这个问题
  3. 使用邻接表描述图
  • 使用邻接表描述图,即使用数组+链表的方法来表示
  • 总共有几个顶点,则创建几条链表,每条链表表示一个顶点和其他顶点的连接关系
  • 将每个顶点相关联的其他顶点使用链表连接起来,
  • 即可实现邻接表描述图
  1. 本文主要说明使用邻接矩阵描述图
  2. 源码见下

源码及分析

package algorithm.datastructor.graph;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * @author AIMX_INFO
 * @version 1.0
 */
public class Graph {
    //使用邻接矩阵表示图

    //使用集合存储图的顶点
    private ArrayList<String> vertexList;
    //使用二维数组即矩阵描述顶点之间的关系
    private int[][] edges;
    //边的个数
    private int numOfEdges;

    //测试
    public static void main(String[] args) {
        int n = 5;
        String[] vertexs = {"A", "B", "C", "D", "E"};
        //创建图
        Graph graph = new Graph(n);
        //添加顶点
        for (String vertex : vertexs) {
            graph.insertVertex(vertex);
        }
        //连接顶点
        graph.insertEdge(0, 1, 1);
        graph.insertEdge(0, 2, 1);
        graph.insertEdge(1, 2, 1);
        graph.insertEdge(1, 3, 1);
        graph.insertEdge(1, 4, 1);
        //显示图
        graph.showGraph();

    }

    //n为顶点的个数
    public Graph(int n) {
        edges = new int[n][n];
        vertexList = new ArrayList<>(n);
        numOfEdges = 0;
    }

    //插入顶点
    public void insertVertex(String vertex) {
        vertexList.add(vertex);
    }

    /**
     * 添加边
     *
     * @param v1     顶点在集合中存储的下标
     * @param v2     顶点在集合中的下标
     * @param weight 两个顶点之间的权值,0或者1,表示是否相连
     */
    public void insertEdge(int v1, int v2, int weight) {
        edges[v1][v2] = weight;
        edges[v2][v1] = weight;
        numOfEdges++;
    }

    //返回节点的个数
    public int getNumOfVertex() {
        return vertexList.size();
    }

    //返回边的个数
    public int getNumOfEdges() {
        return numOfEdges;
    }

    //返回下标 i 对应的数
    public String getValueByIndex(int i) {
        return vertexList.get(i);
    }

    //返回v1和v2的权值
    public int getWeigh(int v1, int v2) {
        return edges[v1][v2];
    }

    //显示矩阵
    public void showGraph() {
        for (int[] link : edges) {
            System.out.println(Arrays.toString(link));
        }
    }
}