使用邻接矩阵表示图详解
说明
- 图是一种可以实现多对多的数据结构,不像链表和树,他们只能建立一对一的关系,每个节点只有前驱或者后继节点,不能实现多对多
- 对于图的描述可以使用邻接矩阵或者邻接表
- 使用邻接矩阵描述图:
- 创建集合保存图的顶点
- 创建二维数组即矩阵描述顶点与顶点之间的关系,顶点与顶点之间用权值来描述,若权值为1,表明两个顶点是相连的,若权值为0,表明两个顶点不相连
- 考虑如何用二维数组描述???
- 使用有序集合存储顶点,那么存储的顶点在集合中是有序的,使用他们在集合中的下标表示它们在数组中的索引
- 二维数组的行和列分别用集合的下标来表示,则能完整的表示各个顶点之间的关系
- 若两个顶点相连,则他们对应二维数组相应位置的元素为1,否则为0
- 即可实现邻接矩阵表示图
- 但是邻接矩阵有一个问题,就是会浪费大量的空间,比如如果两个顶点之间没有连接,也需要用0来表示
- 因此另一种表示图的方法,可以解决这个问题
- 使用邻接表描述图
- 使用邻接表描述图,即使用数组+链表的方法来表示
- 总共有几个顶点,则创建几条链表,每条链表表示一个顶点和其他顶点的连接关系
- 将每个顶点相关联的其他顶点使用链表连接起来,
- 即可实现邻接表描述图
- 本文主要说明使用邻接矩阵描述图
- 源码见下
源码及分析
package algorithm.datastructor.graph;
import java.util.ArrayList;
import java.util.Arrays;
/**
* @author AIMX_INFO
* @version 1.0
*/
public class Graph {
//使用邻接矩阵表示图
//使用集合存储图的顶点
private ArrayList<String> vertexList;
//使用二维数组即矩阵描述顶点之间的关系
private int[][] edges;
//边的个数
private int numOfEdges;
//测试
public static void main(String[] args) {
int n = 5;
String[] vertexs = {"A", "B", "C", "D", "E"};
//创建图
Graph graph = new Graph(n);
//添加顶点
for (String vertex : vertexs) {
graph.insertVertex(vertex);
}
//连接顶点
graph.insertEdge(0, 1, 1);
graph.insertEdge(0, 2, 1);
graph.insertEdge(1, 2, 1);
graph.insertEdge(1, 3, 1);
graph.insertEdge(1, 4, 1);
//显示图
graph.showGraph();
}
//n为顶点的个数
public Graph(int n) {
edges = new int[n][n];
vertexList = new ArrayList<>(n);
numOfEdges = 0;
}
//插入顶点
public void insertVertex(String vertex) {
vertexList.add(vertex);
}
/**
* 添加边
*
* @param v1 顶点在集合中存储的下标
* @param v2 顶点在集合中的下标
* @param weight 两个顶点之间的权值,0或者1,表示是否相连
*/
public void insertEdge(int v1, int v2, int weight) {
edges[v1][v2] = weight;
edges[v2][v1] = weight;
numOfEdges++;
}
//返回节点的个数
public int getNumOfVertex() {
return vertexList.size();
}
//返回边的个数
public int getNumOfEdges() {
return numOfEdges;
}
//返回下标 i 对应的数
public String getValueByIndex(int i) {
return vertexList.get(i);
}
//返回v1和v2的权值
public int getWeigh(int v1, int v2) {
return edges[v1][v2];
}
//显示矩阵
public void showGraph() {
for (int[] link : edges) {
System.out.println(Arrays.toString(link));
}
}
}