与线性表和树不同,图可以表示多对多的关系。
图的常用概念有:
- 顶点(vertex)
- 边(edge)
- 路径
- 无向图
- 有向图
- 带权图
无向图:
有向图和带权图:
图的表示方式:
图的表示方式有两种:二维数组表示(邻接矩阵);链表表示(邻接表)
邻接矩阵:
邻接矩阵是表示图中顶点之间相邻关系的矩阵,n个顶点的图可以用n x n二维数组来表示。
下图有6个顶点,用6 x 6二维数组表示,其中1表示直接相连,0表示不直接相连:
邻接表:
邻接矩阵需要为每个顶点都分配n个边的空间,不管边是否存在,这样会浪费一定的空间。而邻接表的实现只关心存在的边,不关心不存在的边,避免了空间浪费。邻接表由数组+链表组成:
下面使用邻接数组来实现以下图:
package DataStructure;
import java.util.ArrayList;
import java.util.Arrays;
public class GraphDemo {
public static void main(String[] args) {
Graph graph = new Graph(5);
String[] vertexS = {"A", "B", "C", "D", "'E"};
for (String vertex : vertexS) {
graph.insertVertex(vertex);
}
// A-B A-C B-C B-D B-E
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();
}
}
class Graph {
private ArrayList<String> vertexList; // 储存顶点
private int[][] edges; // 储存邻接矩阵
private int edgesNum; // 储存边的个数
public Graph(int n) {
vertexList = new ArrayList<>(n);
edges = new int[n][n];
}
// 常用方法:
// 插入顶点
public void insertVertex(String vertex) {
vertexList.add(vertex);
}
/**
* 添加边
* @param v1 顶点的下标
* @param v2 另一个顶点的下标
* @param flag 1或0 表示直接连接或不直接连接
*/
public void insertEdge(int v1, int v2, int flag) {
edges[v1][v2] = flag;
edges[v2][v1] = flag;
edgesNum++;
}
// 返回顶点个数
public int getVertexNum() {
return vertexList.size();
}
// 返回边的数目
public int getEdgesNum() {
return edgesNum;
}
// 返回下标i对应的顶点数据
public String getVertex(int i) {
return vertexList.get(i);
}
// 返回两个顶点的连接关系
public int getFlag(int v1, int v2) {
return edges[v1][v2];
}
// 显示图对应的矩阵
public void showGraph() {
for (int[] edge : edges) {
System.out.println(Arrays.toString(edge));
}
}
}