好好学数据结构-图的邻接链表法、邻接矩阵法

326 阅读2分钟

这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战

树实际上是图的一种,但并不是所有的图都是树。简单地说,树是没有环路的连通图。

简单说来,图是节点与节点之间边的集合。

  • 图可以分为有向图(如下图)或无向图。有向图的边可以类比为单行道,而无向图的边可以类比为双向车道。
  • 图可以包括多个相互隔离的子图。如果任意一对节点都存在一条路径,那么该图被称为连通图。
  • 图也可以包括(或不包括)环路。无环图(acyclic graph)是指没有环路的图。

你可以将图直观地画成如下样子。

在编程的过程中,有两种常见方法表示图。

邻接链表法

这是表示图的最常见的方法。每个顶点(或节点)存储一列相邻的顶点。在无向图中,边(a,b)会被存储两遍:在a的邻接顶点中存储一遍,在b的邻接顶点中存储一遍。

图的节点类的实现方法和树的节点类基本一致。

class Graph {
2.     public Node[] nodes;
3.   }
4.
5.   class Node {
6.     public String name;
7.     public Node[] children;
8.   }

不同于树,我们需要使用图类Graph,这是因为我们不一定能够从某一单一节点到达图中所有节点。

使用其他的类来表示图并非必需。由链表(或数组,动态数组)组成的数组(或散列表)也可以存储邻接链表。上图可以表示为:

0: 1
1: 2
2: 0, 3
3: 2
4: 6
5: 4
6: 5

这样的表示方式要更紧凑,但是不够整洁。除非别无他法,我们更倾向于使用节点类。

邻接矩阵法

邻接矩阵是N\times N的布尔型矩阵(N是节点的数量),其中matrix[i][j]的值为true,表示从节点i到节点j存在一条边。(你同样可以使用整数矩阵,同时使用0和1表示边是否存在。)

在无向图中,邻接矩阵是对称的。在有向图中,邻接矩阵并不一定对称。

可以使用于邻接链表的算法(广度搜索等)同样可以应用于邻接矩阵,但是其效率会有所降低。在邻接链表表示法中,你可以方便地迭代一个节点的相邻节点。在邻接矩阵表示法中,你需要迭代所有节点以便于找出某个节点的所有相邻节点。