1.思考
上一篇:数据结构与算法系列二十八(图广度优先搜索) ,我们利用广度优先搜索实现了求最短路径的问题。关于图的常见算法,还有图的深度优先搜索算法。
那么这一篇我们来实现图的深度优先搜索算法。关于图深度优先搜索算法实现,主要会用到递归、以及回溯算法思想。你可以想象一下你正在走迷宫,每个路口都可能有多个岔路:
- 你可以选择任意一个岔路走下去
- 如果找到了目标地点(顶点),那么达到目的,搜索过程结束
- 如果找不到目标地点(顶点),那么退回到上一个岔路口,选择另外一条岔路再走下去。
- 重复该过程,直到找到目标地点为止
- 以上就是图深度优先搜索以及回溯的思想,我们稍后通过递归代码实现
#考考你:
1.你知道图的深度优先搜索算法的核心思想吗
2.你能用java语言实现图的深度优先搜索吗
2.案例
2.1.图的定义
/**
* 无向图-->邻接表存储
*/
class DfsGraph{
/**
* 顶点个数
*/
private int v;
/**
* 邻接表:每个顶点对应一个链表
*/
private LinkedList<Integer> adj[];
/**
* 构造方法,根据顶点个数定义图
* @param v
*/
public DfsGraph(int v){
this.v = v;
this.adj = new LinkedList[v];
// 初始化顶点链表
for(int i = 0; i < v; i++){
adj[i] = new LinkedList<Integer>();
}
}
/**
* 建立顶点之间的关系
* @param s
* @param t
*/
public void addEdge(int s, int t){
// 无向图
// 每一条边需要存储两次
adj[s].add(t);
adj[t].add(s);
}
}
2.2.深度优先搜索
/**
* 标记是否找到了终止顶点(递归终止条件)
*/
public boolean found = false;
/**
* 广度优先搜索
* 1.搜索从起始顶点 s,到终止顶点t的最短路径
* @param s 起始顶点
* @param t 终止顶点
*/
public void dfs(int s, int t){
// 递归终止条件
found = false;
// 记录访问过顶点
boolean []visited = new boolean[v];
// 记录搜索路径
int []prev = new int[v];
for(int i = 0; i < v; i++){
prev[i] = -1;
}
// 深度优先搜索(递归实现)
recurDfs(s,t,visited,prev);
// 输出搜索结果路径
outSToTPath(prev,s,t);
}
/**
* 递归实现深度优先搜索
* @param s 开始顶点
* @param t 终止顶点
* @param visited 标记顶点是否访问过
* @param prev 搜索路径
*/
private void recurDfs(int s,int t,boolean []visited,int []prev){
// 递归终止条件成立(已经找到目标顶点)
if(found == true){return;}
// 将顶点标记为已经访问过了
visited[s] = true;
// 找到目标顶点
if(s == t){
found = true;
// 是目标终止顶点,深度优先搜索结束
System.out.println("顶点【" + 0 + "】到顶点【" + t + "】搜索结果:");
return;
}
// 循环遍历每个邻接表,在邻接表访问中,递归访问
for(int i = 0; i < adj[s].size(); i++){
// 如果已经发现目标顶点了,就不需要再循环递归
if(found == true){
return ;
}
int q = adj[s].get(i);
if(!visited[q]){
prev[q] = s;
// 记录搜索路径
System.out.println("正在从顶点【" + s + "】访问顶点【" + q + "】");
// 递归
recurDfs(q,t,visited,prev);
}
}
}
2.3.辅助打印输出
/**
* 递归打印输出搜索路径
* @param prev 搜索路径
* @param s 起始顶点
* @param t 终止顶点
*/
private void outSToTPath(int[] prev, int s, int t){
if(prev[t] != -1 && t != s){
outSToTPath(prev, s, prev[t]);
}
// 打印输出
System.out.print(t + "-->");
}
2.4.测试代码
/**
* 构建图,顶点:0 1 2 3 4 5 ,详情如下:
0 + + 1 + + 2
+ + +
+ + +
3 + + 4 + + 5
*/
public static void main(String[] args) {
// 1.创建6个顶点图
DfsGraph g = new DfsGraph(6);
// 2.建立顶点之间关系
// 2.1.顶点:0 1 ;0 3
g.addEdge(0,1);
g.addEdge(0,3);
// 2.2.顶点:1 2;1 4
g.addEdge(1,2);
g.addEdge(1,4);
// 2.3.顶点:2 5
g.addEdge(2,5);
// 2.4.顶点:3 4
g.addEdge(3,4);
// 2.5.顶点:4 5
g.addEdge(4,5);
// 3.开始深度优先搜索
int s = 0;
int t = 3;
System.out.println("顶点【" + s + "】到顶点【" + t + "】搜索过程:");
g.dfs(s, t);
}
}
2.5.测试结果
D:\02teach\01soft\jdk8\bin\java com.anan.struct.graph.DFS
顶点【0】到顶点【3】搜索过程:
正在从顶点【0】访问顶点【1】
正在从顶点【1】访问顶点【2】
正在从顶点【2】访问顶点【5】
正在从顶点【5】访问顶点【4】
正在从顶点【4】访问顶点【3】
顶点【0】到顶点【3】搜索结果:
0-->1-->2-->5-->4-->3-->
Process finished with exit code 0