深度优先搜索属于图论中的入门算法,类似于于穷举的优化。当数据量过大时,深搜广搜的效率会降低很多。
算法思路
以迷宫举例,你有上下左右四个方向可以行动,走过的路都会被打上标记,相当于变成了墙。
根据→↑←↓的规则走上面6*4的迷宫,从6A走到4A,路线如下:
6A->6B->6C->6D->5D->4D->3D->2D->1D->1C->1B->2B->2C->2A->3A->4A;
如果把4A变成一堵墙,5C变成出口,则上面的路线会变成死路,会一直回退到4D重新寻路。
从4D开始新的寻路:4C->4B->5B->5C;
黄格子为已经搜过的路,在这种情况下明明走三步就能到达出口却要搜整张图。
算法应用场景
1.走迷宫找出路:相当于一个劲的闷着头往前找路,碰到了死胡同退出来换下一条路继续找。运气不好得把整个迷宫搜遍了才能找到路。因此如果题目需求在最短的时间找到出路的话,就需要用bfs了。
2.与环相关的问题:这是dfs常见的应用,如果闷着头冲发现冲回了原点,就说明存在环。
算法实现(Java)
/*判断树是否有环
*mp表示有向图的连接情况,n表示图的节点数*/
boolean isPass[] = new boolean[n];
Map<Integer, Vector<Integer>> mp = new HashMap<>();
int n = SIZE;
boolean flag = false;
void dfs(int u, int start) {
if (flag == true) return;
Vector<Integer> vec = mp.get(u);
for (int i=0; i<vec.size(); i++){
int v = vec.elementAt(i);
if (isPass[v]==false) {
isPass[v] = true;
dfs(v, start);
}
else {
System.out.println("有环");
flag = true;
break;
}
}
}
boolean judge(){
for(int i=0, i<n, i++) {
if(isPass[i] == false) dfs(i, i);
}
}