邻接矩阵和邻接表

766 阅读2分钟

邻接矩阵

邻接矩阵是图数据结构的一种表示方法,它是一个二维数组,其中数组的每个元素表示一个节点之间的关系,如是否存在边,边的权值等信息。邻接矩阵的行和列都是节点,若节点i和节点j之间有边,则邻接矩阵中第i行第j列的元素为1或边的权值。若不存在边,则该元素为0或者一个特定的值。

优缺点

邻接矩阵的优点是查询两个节点之间是否存在边非常方便,只需要访问一次二维数组即可,时间复杂度为O(1)。缺点是对于稀疏图来说,邻接矩阵会浪费很多空间,因为大部分元素都是0。

演示

public class AdjacencyMatrix {

    private int[][] matrix; // 存储邻接矩阵
    private int vertexCount; // 顶点数量

    // 构造函数
    public AdjacencyMatrix(int vertexCount) {
        this.vertexCount = vertexCount;
        this.matrix = new int[vertexCount][vertexCount];
    }

    // 添加边
    public void addEdge(int start, int end, int weight) {
        matrix[start][end] = weight;
        matrix[end][start] = weight;
    }

    // 获取边的权重
    public int getWeight(int start, int end) {
        return matrix[start][end];
    }

    // 获取顶点的度
    public int getDegree(int vertex) {
        int degree = 0;
        for (int i = 0; i < vertexCount; i++) {
            degree += matrix[vertex][i];
        }
        return degree;
    }
}

邻接矩阵是一个二维数组,其中第i行第j列的元素表示节点i和节点j之间的边的权重。如果节点i和节点j之间没有边,则该元素的值为0。在这个示例中,定义了一个Graph类,其中包含一个二维数组matrix,表示邻接矩阵,还包含一个addEdge方法,用于在节点之间添加边。

邻接表

邻接表是图数据结构的另一种表示方法,它使用链表来表示每个节点的邻居节点,即每个节点与它相邻的节点的列表。通俗来说,邻接表就是由一些链表构成的集合,每个节点对应一条链表,该链表中包含了与该节点相邻的所有节点。

优缺点

邻接表的优点是对于稀疏图来说非常节省空间,因为它只需要存储存在边的节点对应的链表。此外,邻接表对于遍历节点的邻居非常方便,因为邻居节点都被保存在链表中,时间复杂度为O(k),其中k是节点的平均度数。缺点是查询两个节点之间是否存在边需要遍历链表,时间复杂度为O(k),其中k是节点的度数。

演示

import java.util.ArrayList;
import java.util.List;

public class AdjacencyList {

    private List<List<Integer>> adjList; // 存储邻接表
    private int vertexCount; // 顶点数量

    // 构造函数
    public AdjacencyList(int vertexCount) {
        this.vertexCount = vertexCount;
        this.adjList = new ArrayList<>(vertexCount);
        for (int i = 0; i < vertexCount; i++) {
            adjList.add(new ArrayList<>());
        }
    }

    // 添加边
    public void addEdge(int start, int end) {
        adjList.get(start).add(end);
        adjList.get(end).add(start);
    }

    // 获取邻居节点列表
    public List<Integer> getNeighbors(int vertex) {
        return adjList.get(vertex);
    }

    // 获取顶点的度
    public int getDegree(int vertex) {
        return adjList.get(vertex).size();
    }
}

邻接表是一个由链表组成的数组,其中每个节点的链表表示与该节点相邻的节点。在这个示例中,定义了一个Graph类,其中包含一个数组adjList,表示邻接表,还包含一个addEdge方法,用于在节点之间添加边。每个链表节点表示一个边,其中包含两个属性,一个表示该边连接的目标节点的编号,另一个表示该边的权重。

区别

  1. 存储空间:邻接矩阵需要一个大小为n*n的数组来存储,其中n是节点数;而邻接表只需要存储每个节点和它的相邻节点,因此存储空间要小得多。
  2. 遍历:在邻接矩阵中,检查两个节点之间是否有边只需要访问矩阵中的一个元素;而在邻接表中,需要访问两个节点的邻接表,并搜索邻接表以查找相邻节点。
  3. 性能:邻接矩阵支持O(1)时间内查找两个节点之间是否有边,而邻接表需要O(k)时间,其中k是节点的平均度数。然而,在稀疏图中,邻接表的性能通常优于邻接矩阵,因为邻接矩阵中有大量的0元素,这些元素不需要存储或搜索。