深度优先搜索用来搜索从图上一个顶点到另一个顶点的路径,或者图上的特定节点。
深度优先,形象一点说,不撞南墙不回头。人类在走迷宫时通常会采用这种算法:先试着走一条路,试试能不能走通,不能走通再回来重新走另一条。
下面我们用计算机语言来实现这种算法。
一、图的深度优先搜索的递归定义是:
假设有一个图,从顶点V开始,进行深度优先搜索:
① 访问顶点V, 并标记V已访问.
② 从顶点V的每个未访问的邻接点开始,进行深度优先搜索.
以上定义中,标记V已访问
的意义在于防止形成环。
而对于无环的二叉树来说,先序遍历,中序遍历,后序遍历都是深度优先搜索。
比如先序遍历的递归定义:
① 访问根节点
② 先序遍历左子节点,先序遍历右子节点。
可以发现先序遍历的定义和深度优先搜索的定义很相似,只是后者少了标记的步骤。
为了方便编程,介绍表示图的数据结构:
var graph = [[1,2], [3], [3], []]
二维数组graph
的下标表示节点,graph[i]
表示以节点i
为起点的边的终点集合(从节点i
可以直接到达的点的集合)。
例如:graph[0] = [1,2]
代表两条边0,1
和0,2
。graph
如下:
0--->1
| |
v v
2--->3
下面用JavaScript
实现图的深度优先遍历:
var graph = [[1,2], [3], [3], []]
var visited = new Array(graph.length) //visited[i] = true 代表节点i已被访问
visited.fill(false) //初始化数组元素全为false
var dfs = function(start){
console.log(starts) //visited
visited[start] = true
for(let vertical of graph[start]){
if(!visited[vertical]){
dfs(vertical)
}
}
}
dfs(0)
控制台输出:
0
1
3
2
在下一篇文章中,我们用深度优先搜索算法,查找图上从一个顶点到另一个顶点的所有路径。
欢迎关注,欢迎点赞~