上次写了篇图的基本构造方法,运用图这种强大的数据结构结构,还能解决实际应用中的许多问题,今天这篇就主要整理一些常见的应用
一、路径问题
路径问题在图的处理领域是非常重要的。如我们最常见的走迷宫,就是典型的寻路问题。这里主要运用深度优先和广度优先算法两种方式来进行路径寻找,这2种搜索算法在很多数据结构中都有重要的运用,之前写的一篇二叉查找树中的层序遍历就用到了广度优先算法,这里就详细的介绍一下。
1.深度优先寻找路径
首先是深度优先,为了更加形象,直接看下图
这里以顶点1为出发点,4为终点。假设一个人要走到终点,从1出发有三条路径,首先沿着往5的路径进行遍历,依次1 -> 5 -> 9 -> 8,然后发现没路了,就返回上一顶点,到顶点5这里发现还有一条路就继续沿着这条路走,5->3->6,结果又没路了,就继续返回到起点,沿着另一条路行走……1->2->4,一看,这下就直接到终点了,转了几条路终于找到了终点,那心里真是无比的兴奋啊!回到正题,看看这个具体实现,可以用一个boolean类型的变量来标记是否遍历过该顶点,用一个int型的变量表示从起点到一个顶点的已知路径上的最后一个顶点。至于图的基本构造可以参考我之前写的图论基础篇
/**
* 图的深度优先查找路径
* @author Legend
*/
public class DepthFirstPaths {
private boolean[] marked; // 该顶点是否调用过dfs
private int[] edgeTo; // 从起点到一个顶点的已知路径上的最后一个顶点
private final int s; // 起点
// 图的初始化
public DepthFirstPaths(Graph G,int s) {
marked = new boolean[G.V()];
edgeTo = new int[G.V()];
this.s = s;
dfs(G,s);
}
// 深度优先主方法
private void dfs(Graph G,int v) {
marked[v] = true;
// 遍历与顶点v相连的边
for (int w : G.adj(v)) {
if (!marked[w]) {
edgeTo[w]