动画 | 1分钟看懂深度优先遍历

Posted 小白算法苦旅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动画 | 1分钟看懂深度优先遍历相关的知识,希望对你有一定的参考价值。

动画 | 1分钟看懂深度优先遍历

Depth First Search

深度优先遍历

动画 | 1分钟看懂深度优先遍历

动画 | 1分钟看懂深度优先遍历

/什么是DFS/

深度优先遍历(DFS)和宽度优先遍历(BFS)一样,属于图论算法的一种,但不同于BFS, DFS每次搜索的结果必然是图的一个连通分量。


先来看上期文章最后一道题目:


给定一个M×N (M, N <= 100)的迷宫。

    其中’S’代表起点, ‘E’代表终点, ‘.’表示路, ‘#’表示墙;

    你的任务是输出走出迷宫的最短路径, 若没有通路, 则输出-1。


    如果将迷宫问题中,”求最短路径“的问题修改为”第n步刚好到达“且走过的路不能再次走过。


这道题又该如何去写呢?BFS对于求最短路的问题是很方便,但是对于恰好到达的问题,就显得力不从心。由于BFS在搜索终点的过程中,为了避免结点的多次访问,设置了一个vis数组来判断当前结点是否访问过。


这时候我们可以换一种思路,我们可以求出迷宫的起点到终点的所有路径,然后判断他的步数是否和输入的步数一致。先看这段视频,来了解工作过程。

(视屏中遍历的顺序是:上、右、下、左)

(ps:开头有错误,n=5而不是n=4)


一分钟演示动画


 Stack 

/栈/

我们可以发现,DFS算法使用了”栈“的数据结构,和队列不同,栈是一种先进后出的数据结构。DFS使用这种方法,来实现向深处搜索。视频里面就是这样的过程。


同样的,我们首先要定义一下方向数组以及vis标记数组:


int dir[4][2] = { {-1, 0}, {0, 1}, {1, 0}, {0, -1}};
int vis[maxn][maxn];


以及主要功能实现:


void dfs(){  if (flag) return; p cur, next; cur = s.top(); for (int i = 0; i < 4; i++) { next.x = cur.x + dir[i][0]; next.y = cur.y + dir[i][1]; next.step = cur.step + 1; if (next.x >= 0 && next.x <= n && next.y <= m && next.y >= 0 && !vis[next.x][next.y]) { vis[next.x][next.y] = 1; if (map[next.x][next.y] == '.' || map[next.x][next.y] == 'E') { s.push(next); dfs(); vis[next.x][next.y] = 0; if (map[next.x][next.y] == 'E' && next.step == k)          flag = 1; } } } s.pop(); //出栈}


大体的框架没有发生什么改变,但是可以发现出栈的操作放到了循环的外面,,以及采用了递归的调用方式,这就是不同之处。至于大致的解析在第一篇文章中已经提到过,大家可以浏览一下:)


传送门:



END
动画 | 1分钟看懂深度优先遍历


动画 | 1分钟看懂深度优先遍历
这是一个有温度的公众号


以上是关于动画 | 1分钟看懂深度优先遍历的主要内容,如果未能解决你的问题,请参考以下文章

阿里高频题动画讲解二叉树深度优先遍历

10分钟教你用python动画演示深度优先算法搜寻逃出迷宫的路径

一文搞明白java遍历循环递归深度优先广度优先的区别

动画:如何用广度和深度优先搜索找到女朋友?

(王道408考研数据结构)第六章图-第三节:图的遍历(DFS和BFS)

数据结构—深度优先遍历广度优先遍历图遍历算法的应用