原文: https://www.programiz.com/dsa/graph-adjacency-matrix

在本教程中,您将学习什么是邻接矩阵。 此外,您还将在 C,C++ ,Java 和 Python 中找到邻接矩阵的工作示例。

邻接矩阵是将图形G = {V, E}表示为布尔矩阵的一种方式。


邻接矩阵表示

矩阵的大小为VxV,其中V是图形中的顶点数,而条目Aij的值取决于顶点i至顶点j的边为 1 或 0。


邻接矩阵示例

下图显示了一个图形及其等效的邻接矩阵。

邻接矩阵 - 图1

图的邻接矩阵

在无向图的情况下,由于每个边(i,j),矩阵关于对角线对称,也有边(j,i)


邻接矩阵的优点

基本操作(如添加边线,移除边线和检查从顶点i到顶点j的边线)是非常节省时间的恒定时间操作。

如果图是密集的并且边的数量很大,则邻接矩阵应该是首选。 即使图和邻接矩阵是稀疏的,我们也可以使用稀疏矩阵的数据结构来表示它。

但是,最大的优势来自矩阵的使用。 硬件的最新进展使我们能够在 GPU 上执行甚至昂贵的矩阵运算。

通过对相邻矩阵执行运算,我们可以深入了解图形的性质及其顶点之间的关系。


邻接矩阵的缺点

邻接矩阵的VxV空间要求使其成为存储猪。 野外绘制的图形通常没有太多的联系,这就是邻接表是大多数任务的更好选择的主要原因。

虽然基本操作很容易,但是当使用邻接矩阵表示法时,inEdgesoutEdges之类的操作很昂贵。


Python,Java 和 C/C++ 示例

如果您知道如何创建二维数组,那么您还将知道如何创建邻接矩阵。

  1. # Adjacency Matrix representation in Python
  2. class Graph(object):
  3. # Initialize the matrix
  4. def __init__(self, size):
  5. self.adjMatrix = []
  6. for i in range(size):
  7. self.adjMatrix.append([0 for i in range(size)])
  8. self.size = size
  9. # Add edges
  10. def add_edge(self, v1, v2):
  11. if v1 == v2:
  12. print("Same vertex %d and %d" % (v1, v2))
  13. self.adjMatrix[v1][v2] = 1
  14. self.adjMatrix[v2][v1] = 1
  15. # Remove edges
  16. def remove_edge(self, v1, v2):
  17. if self.adjMatrix[v1][v2] == 0:
  18. print("No edge between %d and %d" % (v1, v2))
  19. return
  20. self.adjMatrix[v1][v2] = 0
  21. self.adjMatrix[v2][v1] = 0
  22. def __len__(self):
  23. return self.size
  24. # Print the matrix
  25. def print_matrix(self):
  26. for row in self.adjMatrix:
  27. for val in row:
  28. print('{:4}'.format(val)),
  29. print
  30. def main():
  31. g = Graph(5)
  32. g.add_edge(0, 1)
  33. g.add_edge(0, 2)
  34. g.add_edge(1, 2)
  35. g.add_edge(2, 0)
  36. g.add_edge(2, 3)
  37. g.print_matrix()
  38. if __name__ == '__main__':
  39. main()
  1. // Adjacency Matrix representation in Java
  2. public class Graph {
  3. private boolean adjMatrix[][];
  4. private int numVertices;
  5. // Initialize the matrix
  6. public Graph(int numVertices) {
  7. this.numVertices = numVertices;
  8. adjMatrix = new boolean[numVertices][numVertices];
  9. }
  10. // Add edges
  11. public void addEdge(int i, int j) {
  12. adjMatrix[i][j] = true;
  13. adjMatrix[j][i] = true;
  14. }
  15. // Remove edges
  16. public void removeEdge(int i, int j) {
  17. adjMatrix[i][j] = false;
  18. adjMatrix[j][i] = false;
  19. }
  20. // Print the matrix
  21. public String toString() {
  22. StringBuilder s = new StringBuilder();
  23. for (int i = 0; i < numVertices; i++) {
  24. s.append(i + ": ");
  25. for (boolean j : adjMatrix[i]) {
  26. s.append((j ? 1 : 0) + " ");
  27. }
  28. s.append("\n");
  29. }
  30. return s.toString();
  31. }
  32. public static void main(String args[]) {
  33. Graph g = new Graph(4);
  34. g.addEdge(0, 1);
  35. g.addEdge(0, 2);
  36. g.addEdge(1, 2);
  37. g.addEdge(2, 0);
  38. g.addEdge(2, 3);
  39. System.out.print(g.toString());
  40. }
  41. }
  1. // Adjacency Matrix representation in C
  2. #include <stdio.h>
  3. #define V 4
  4. // Initialize the matrix to zero
  5. void init(int arr[][V]) {
  6. int i, j;
  7. for (i = 0; i < V; i++)
  8. for (j = 0; j < V; j++)
  9. arr[i][j] = 0;
  10. }
  11. // Add edges
  12. void addEdge(int arr[][V], int i, int j) {
  13. arr[i][j] = 1;
  14. arr[j][i] = 1;
  15. }
  16. // Print the matrix
  17. void printAdjMatrix(int arr[][V]) {
  18. int i, j;
  19. for (i = 0; i < V; i++) {
  20. printf("%d: ", i);
  21. for (j = 0; j < V; j++) {
  22. printf("%d ", arr[i][j]);
  23. }
  24. printf("\n");
  25. }
  26. }
  27. int main() {
  28. int adjMatrix[V][V];
  29. init(adjMatrix);
  30. addEdge(adjMatrix, 0, 1);
  31. addEdge(adjMatrix, 0, 2);
  32. addEdge(adjMatrix, 1, 2);
  33. addEdge(adjMatrix, 2, 0);
  34. addEdge(adjMatrix, 2, 3);
  35. printAdjMatrix(adjMatrix);
  36. return 0;
  37. }
// Adjacency Matrix representation in C++

#include <iostream>
using namespace std;

class Graph {
   private:
  bool** adjMatrix;
  int numVertices;

   public:
  // Initialize the matrix to zero
  Graph(int numVertices) {
    this->numVertices = numVertices;
    adjMatrix = new bool*[numVertices];
    for (int i = 0; i < numVertices; i++) {
      adjMatrix[i] = new bool[numVertices];
      for (int j = 0; j < numVertices; j++)
        adjMatrix[i][j] = false;
    }
  }

  // Add edges
  void addEdge(int i, int j) {
    adjMatrix[i][j] = true;
    adjMatrix[j][i] = true;
  }

  // Remove edges
  void removeEdge(int i, int j) {
    adjMatrix[i][j] = false;
    adjMatrix[j][i] = false;
  }

  // Print the martix
  void toString() {
    for (int i = 0; i < numVertices; i++) {
      cout << i << " : ";
      for (int j = 0; j < numVertices; j++)
        cout << adjMatrix[i][j] << " ";
      cout << "\n";
    }
  }

  ~Graph() {
    for (int i = 0; i < numVertices; i++)
      delete[] adjMatrix[i];
    delete[] adjMatrix;
  }
};

int main() {
  Graph g(4);

  g.addEdge(0, 1);
  g.addEdge(0, 2);
  g.addEdge(1, 2);
  g.addEdge(2, 0);
  g.addEdge(2, 3);

  g.toString();
}

邻接矩阵应用

  1. 在网络中创建路由表
  2. 导航任务