图是计算机经典算法的重要组成部分,从互联网结构到电力拓扑,从经济学的市场模型到医学对传染病的感染预测都具有非常广泛的应用。图的研究方面可以分为连通性、路径问题、可达性等多个方面。今天我们仅聚焦于有向图和无向图的环测定问题,先使用Java语言实现它们的基本算法,然后我将利用矩阵为大家展示如何通过数学模型来辅助算法。
由一系列相连的节点和所组成的数据结构,叫做图。无论作为社交网络还是地图,计算机在对这类问题进行处理的时候都可能会遇到各种数学问题。我们将学习两种重要的图模型:无向图(简单连接)和有向图(连接有方向性)。
一个图的结构可能非常复杂,但是为了简化我们的研究,我们只涉及以下两种最基本的结构,图1图2仅仅对调了2、3节点,图3表示有向图。
一、无向图与环测定
在我们首先要学习的这种图模型中,边(edge)仅仅是两个顶点(vertex)之间的连接。在无向图中,如果节点1和2之间存在连接表示0-1和1-0同时存在。首先我们需要定义表示无向图结构的对象:
import java.util.LinkedList;import java.util.List;public class Graph { private int v; // 顶点总数 private int e; // 边总数 private List[] adj; // 邻接表数组 public Graph(int v) { this.v = v; this.e = 0; adj = (List[]) new List[v]; for (int i = 0; i < v; i++) { adj[i] = new LinkedList<>(); } } /** * 由于图中允许存在平行边,因此不排除在邻接表中保存相同的键 * * @param v 定点 * @param w 定点 */ public void addEdge(int v, int w) { adj[v].add(w); adj[w].add(v); e++; } public void delEdge(int v, int w) { if (adj[v].contains(w)) { adj[v].remove(w); adj[w].remove(v); } } public boolean checkEdge(int v, int w) { return adj[v].contains(w); } public Iterable adj(int v) { return adj[v]; }