# 图算法系列之深度优先搜索（一）

·  阅读 681

## 搜索API的定义

``````public class Search {
Search(Graph graph, int s);

boolean marked(int v);

int count();
}

1. 构造方法提供了一个图对象，以及一个起点s，需要找到与s连通的所有顶点
2. marked判断顶点s与v是否相邻
3. count返回与顶点s相连的总顶点数

## 深度优先搜索

1. 先选择一条通道走，在走的路上放上一根绳子
2. 每遇到一个路口就用笔标记一下，继续选择一条未走过的通道
3. 当遇到一个已经被标记的路口时就退回到上一个路口继续选择一个未走过的通道
4. 当回退的路口已经没有路可以走的时候就在继续往后回退

``````public class DepthFirstSearch {
private boolean marked[];
private int count;

public DepthFirstSearch(Graph graph, int s) {
this.marked = new boolean[graph.V()];
this.dfs(graph, s);
}

private void dfs(Graph graph, int v) {
marked[v] = true;
count++;
for (int w : graph.adj(v)) {
if (!marked[w]) {
dfs(graph, w);
}
}
}

@Override
public boolean marked(int v) {
return marked[v];
}

@Override
public int count() {
return count;
}
}

1. 标记它被已经访问
2. 递归的访问与之相连的所有邻接点

``````@Test
public void test() {
Graph graph = new Graph(8); //构建一张图

SeDepthFirstSearcharch search = new DepthFirstSearch(graph, 0);
System.out.println(search.count());
System.out.println(search.marked(6));
System.out.println(search.marked(7));
System.out.println(search.marked(2));
System.out.println(search.marked(5));
}

## 寻找路径的API

``````public class Paths {
Paths(Graph graph, int s);

boolean hasPathTo(int v); //判断出从s->v是否存在路径

Iterable<Integer> pathTo(int v); //如果存在路径，返回路径
}

## 基于深度优先搜索查找图中的可达路径

``````public class DepthFirstPaths {
private boolean marked[];
private int[] edgeTo;
private int s;

DepthFirstPaths(Graph graph, int s) {
this.s = s;
this.marked = new boolean[graph.V()];
this.edgeTo = new int[graph.V()];
this.dfs(graph, s);
}

private void dfs(Graph graph, int v) {
this.marked[v] = true;
for (int w : graph.adj(v)) {
if (!marked[w]) {
this.edgeTo[w] = v;
this.dfs(graph, w);
}
}
}

public boolean hasPathTo(int v) {
return marked[v];
}

public Iterable<Integer> pathTo(int v) {
if (!hasPathTo(v)) {
throw new IllegalStateException("s不能到达v");
}
stack.push(v);
while (edgeTo[v] != s) {
stack.push(edgeTo[v]);
v = edgeTo[v];
}
stack.push(s);
return stack;
}
}

``````@Test
public void test() {
Graph graph = new Graph(8);

DepthFirstPaths paths = new DepthFirstPaths(graph, 0);
System.out.println(paths.hasPathTo(5));
System.out.println(paths.hasPathTo(2));
System.out.println(paths.hasPathTo(6));

paths.pathTo(5).forEach(System.out::print);
System.out.println();
paths.pathTo(4).forEach(System.out::print);
System.out.println();
paths.pathTo(2).forEach(System.out::print);

}