一、图的表示
1.图的两种表示
1.1 邻接表
对于图 G = ( V , E ) G=(V,E) G=(V,E)来说,邻接表表示由一个包含 ∣ V ∣ |V| ∣V∣条链表的数组 A A A构成,对于每一个结点 u ∈ V u\in V u∈V,邻接链表 A [ u ] A[u] A[u]包含所有与结点 u u u之间有边相连的结点。
如下图所示:
如上图,图 G G G是一个无向图,则对于边 ( u , v ) (u,v) (u,v)来说,结点 v v v将出现在链表 A [ u ] A[u] A[u]中,结点 u u u也会出现在链表 A [ v ] A[v] A[v]中,因此邻接链表长度之和为 2 ∣ E ∣ 2|E| 2∣E∣。而有向图则会减少一半,长度之和为 ∣ E ∣ |E| ∣E∣。
显然,邻接表存储空间为 Θ ( V + E ) \Theta(V+E) Θ(V+E)。
可在链表中的数据域中添加权重使得邻接表可表示一个权重图。
1.2 邻接矩阵
对于邻接矩阵来说,将图 G G G编码为 0 , 1 , 2 , ⋯ , ∣ V − 1 ∣ 0,1,2,\cdots,|V-1| 0,1,2,⋯,∣V−1∣。则,图G的邻接矩阵表示由一个 ∣ V ∣ × ∣ V ∣ |V|\times|V| ∣V∣×∣V∣的矩阵 A = ( a i j ) A=(a_{ij}) A=(aij)表示。矩阵满足
a i j = { 1 ( i , j ) ∈ E 0 ( i , j ) ∉ E a_{ij} =\begin{cases} 1 (i,j)\in E\\ 0 (i,j)\notin E \end{cases} aij={
1 (i,j)∈E0 (i,j)∈/E
若需要修改为权重图,则:
a i j = { w i j ( i , j ) ∈ E ∞ ( i , j ) ∉ E a_{ij} =\begin{cases} w_{ij} (i,j)\in E\\ \infty (i,j)\notin E \end{cases} aij={
wij (i,j)∈E∞ (i,j)∈/E
如下图所示:
2.各自优势与缺陷
2.1 邻接表优势与缺陷
优点在于表示稀疏图 ( ∣ E ∣ < < ∣ V 2 ∣ ) (|E|<<|V^2|) (∣E∣<<∣V2∣)的图时非常紧凑,相比于邻接矩阵花费的空间少得多。
能够随意地对链表的结点进行修改来添加一些附加信息,鲁棒性高。
缺点在于无法快速判断一条边 ( u , v ) (u,v) (u,v)是否是图中的一条边。
2.2 邻接矩阵优势与缺陷
优点在于能够快速判断一条边 ( u , v ) (u,v) (u,v)是否是图中的一条边,只需要找到对应下标元素相关信息即可。
缺点在于消耗的空间大。
3.具体程序表示
3.1 邻接矩阵表示
private static final int maxWeight = 1000; //无法到达的权重表示
private static final int maxVertices = 10; //最大结点数
private ArrayList<E> Vertices; //结点数组
private int[][] edge; //边数组
private int numOfEdges;
3.2 邻接表表示
private static final int maxVertices = 10; //最大结点数
private ArrayList<ListNode> Vertices; //结点列表
private int numOfEdges;
private int numOfVexs;
private class EdgeNode{
//边类
int nodeIndex; //边指向的结点索引
int weight; //边权重
EdgeNode next; //同一结点的下一条边
EdgeNode(int nodeIndex,int weight,EdgeNode next){
this.nodeIndex = nodeIndex;
this.weight = weight;
this.next = next;
}
}
private class ListNode{
//结点类
E data; //结点数据域
int headNodeIndex; //结点索引位置
EdgeNode headNode; //第一条边
ListNode(E data, int headNodeIndex, EdgeNode headNode){
this.data = data;
this.headNodeIndex = headNodeIndex;
this.headNode = headNode;
}
}
二、搜索算法实现
1.搜索算法图解
以下图为例子,从 B B B点出发
1.1 广度优先搜索算法图解
广度优先搜索类似于数的层