邻接矩阵
邻接矩阵表示
package Graph;
/* 邻接矩阵表示图 */
public class Graph {
class Edge { // 定义边
int v1, v2; // 有向边<v1, v2>
int weight; // 权值
public Edge(int v1, int v2, int weight) {
this.v1 = v1;
this.v2 = v2;
this.weight = weight;
}
}
private int vertexNum;
private int edgeNum;
private int G[][]; // 邻接矩阵
public Graph(int vertexNum) {// 初始化一个含vertexNum个顶点但没有边的图
this.vertexNum = vertexNum;
this.edgeNum = 0;
G = new int[100][100]; // 假设图最多含100个顶点
}
public void insertEdge(Edge edge) {
int v1 = edge.v1;
int v2 = edge.v2;
int weight = edge.weight;
G[v1][v2] = weight;
// 若是无向图,还要插入边<v2, v1>
G[v2][v1] = weight;
this.edgeNum++;
}
public void show() {// 打印邻接矩阵
for (int i = 0; i < vertexNum; i++) {
for (int j = 0; j < vertexNum; j++) {
System.out.print(G[i][j] + " ");
}
System.out.println();
}
}
}
邻接矩阵的缺点
- 假设当前的图是无向图,那么矩阵关于主对角线对称,我们可以只提取下三角或上三角的信息。
- 对于稀疏图,矩阵中存在大量的0,浪费空间。
对于无向图的存储,如何节省一半的存储空间
假设当前的图是无向图,那么矩阵关于主对角线对称,我们可以只提取下三角或上三角的信息。
使用邻接表,只存储邻接顶点
对于图来说,邻接矩阵是不错的一种图存储结构,但是我们也发现,对于边数相对顶点较少的图,这种结构是存在对存储空间的极大浪费的。因此我们考虑另外一种存储结构方式:邻接表(Adjacency List),即数组与链表相结合的存储方法。
package Graph;
/* 邻接表表示图 */
public class Graph2 {
class Node {// 链表中的节点
public int adjvertex;
public int weight;
public Node next;
public Node(int adjvertex, int weight, Node next) {
this.adjvertex = adjvertex;
this.weight = weight;
this.next = next;
}
}
class Vertex {// 顶点数组中的顶点
public Node first;
}
private int vertexNum;
private int edgeNum;
private Vertex vertexArr[]; // 顶点数组
public Graph2(int vertexNum) {// 初始化一个含vertexNum个顶点但没有边的图
this.vertexNum = vertexNum;
this.edgeNum = 0;
vertexArr = new Vertex[100]; // 假设图最多含100个顶点
for (int i = 0; i < this.vertexNum; i++) {// 初始化顶点数组
vertexArr[i].first = null;
}
}
// 插入有向边<v1, v2>
public void insertEdge(int v1, int v2, int weight) {
Node current = vertexArr[v1].first;
while (current != null) {
current = current.next;
}
current = new Node(v2, weight, null);// 在链表末尾插入新的节点
// 如果是无向图,还要再插入边<v2, v1>
current = vertexArr[v2].first;
while (current != null) {
current = current.next;
}
current = new Node(v1, weight, null);// 在链表末尾插入新的节点
}
}