简介
图(Graph)是一种数据类型。主要包含顶点(Vertex)和边(Edge)。
图G(V, E)是由一个非空有限顶点集合V和有限边集合E组成。
本篇文章主要是对图的基础知识做一个学习总结。具体内容包括图的存储方式,图的连通性和无权图的遍历和寻路。
图的存储方式
图一般通过邻接矩阵或邻接表的方式存储。
邻接矩阵顾名思义是将顶点间的连通关系存放到矩阵中,无权图即可表示为1连通0不连通。
邻接表则是每个顶点后跟随着一个容器,容器中存放着与该顶点连通的点。
一般而言,稠密图用邻接矩阵存储,稀疏图用邻接表存储。(非常稠密的连接图才被叫做稠密图)
由于邻接矩阵和邻接表都可以表示图,因此我们可以抽象图的接口,分别用这两种方式来实现稠密图和稀疏图
Graph.java
/**
* @Author Nino 2019/11/7
*/
public interface Graph {
public int V();
public int E();
public void addEdge(int v, int w);
public boolean hasEdge(int v, int w);
public Iterator<Integer> adj(int v);
public void show();
}
DenseGraph.java
/**
* 稠密图 - 邻接矩阵
*
* @Author Nino 2019/11/7
*/
public class DenseGraph implements Graph {
// 点数
private int n;
// 边数
private int m;
// 是否有向
private boolean directed;
// 图的具体数据
private boolean[][] g;
public DenseGraph(int n, boolean directed) {
this.n = n;
this.m = 0;
this.directed = directed;
g = new boolean[n][n];
}
public DenseGraph() {
this(0, false);
}
public int V() {
return n;
}
public int E() {
return m;
}
public void addEdge(int v, int w) {
assert v >= 0 && v < n;
assert w >= 0 && w < n;
if (!hasEdge(v, w)) {
g[v][w] = true;
if (!directed) {
g[w][v] = true;
}
m++;
}
}
public boolean hasEdge(int v, int w) {
assert v >= 0 && v < n;
assert w >= 0 && w < n;
return g[v][w];
}
/**
* 返回一个顶点的所有邻边
* @param v
* @return
*/
public Iterator<Integer> adj(int v) {
assert v >= 0 && v < n;
Vector<Integer> vector = new Vector<>(n);
for (int i = 0; i < n; i++) {
if (g[v][i]) {
vector.add(i);
}
}
return vector.itera