深度优先遍历(Depth-First-Search, DFS)是图论中经常使用的一种算法,是一种针对图和树的遍历方法,算法一般采用递归或者栈来实现。在这篇文章中,我们将从算法流程、递归和非递归两种实现方式以及时间空间复杂度等多个角度来分析深度优先遍历的实现方法。
算法流程
深度优先遍历是一种递归的遍历算法,其主要思想是从某个顶点开始一直到最后一个顶点,然后再回到前一个顶点,一直这样递归遍历下去。具体流程如下:
1. 访问当前结点。
2. 依次按顺序访问当前结点的每个未被访问过的邻居结点,并递归访问邻居结点的邻居结点。
递归实现
在递归实现深度优先遍历时,我们采用树形递归的方式。即从某个起点开始,进行递归搜索,直到没有未访问的邻居节点时,返回上一级节点继续搜索。对于图和树来说,递归都可以实现深度优先遍历。该方法的实现代码如下:
```python
# 递归实现深度优先遍历
def dfs(v, visited, graph):
visited[v] = True # 标记为已访问
print(v, end="->") # 访问结点
# 遍历邻居节点
for w in graph[v]:
if not visited[w]:
dfs(w, visited, graph) # 递归遍历邻居的邻居节点
```
非递归实现
非递归方式的实现,需要使用栈来保存遍历的节点,每次取栈顶作为当前节点,然后遍历当前节点的邻居节点,将未访问过的邻居节点压入栈中。当所有邻居节点都访问过,就从栈中弹出当前节点,继续取出栈顶节点进行遍历。该方法的实现代码如下:
```python
# 非递归实现深度优先遍历
def dfs(v, visited, graph):
stack = [v] # 新建栈,将起点入栈
while stack:
cur = stack.pop() # 取栈顶元素
if not visited[cur]:
print(cur, end="->") # 访问结点
visited[cur] = True # 标记为已访问
# 遍历邻居节点,如果未访问则入栈
for w in graph[cur]:
if not visited[w]:
stack.append(w)
```
时间复杂度
深度优先遍历的时间复杂度为 $O(n+m)$,其中 $n$ 表示节点个数,$m$ 表示边的个数。因为从一个节点只会访问一次,而访问一条边也只会访问一次,因此时间复杂度为 $O(n+m)$。
空间复杂度
由于深度优先遍历使用递归或者栈来实现,因此其空间复杂度和栈的深度有关,在最坏情况下,所有节点均为联通的,则空间复杂度为 $O(n)$,其中 $n$ 表示节点个数。
微信扫一扫,领取最新备考资料