深度优先搜索

深度优先搜索的介绍

深度优先搜索(Depth First Search,缩写为DFS)是一种用于遍历或搜索树或图的算法。它从一个开始顶点(或根顶点)开始遍历图或树,沿着一条路径直到没有更多的未访问节点为止,然后回溯到之前的顶点,继续寻找下一个可以访问的顶点。

DFS算法可以用递归或堆栈等方式实现。它的基本思想是深度优先遍历每个结点,访问未访问过的子结点。在遍历过程中,标记已经访问过的结点,以避免重复访问。

DFS的伪代码:

DFS(start):
    visited[start] = true
    for each neighbor of start:
        if neighbor is not visited:
            DFS(neighbor)

其中,start为起始节点,visited为已访问的节点集合。我们先将起始节点标记为已访问,然后遍历该节点的所有邻居,如果邻居节点未被访问过,则递归访问该节点,标记为已访问。

具体实现方式可以有多种,比如可以使用递归方式实现,也可以使用堆栈等数据结构实现。无论哪种方式,算法都具有类似的基本思想:深度优先搜索遍历每个结点,尽可能深入地搜索每个结点的所有子结点,只有在到达末端后才回溯到上一个结点。

DFS算法在Python中的具体实现:

from typing import List

def dfs(graph: List[List[int]], start: int, visited: List[bool]):
    # 标记当前节点为已访问
    visited[start] = True
    print(start, end=' ')
    # 遍历当前节点的邻居节点
    for neighbor in graph[start]:
        # 如果邻居节点未被访问过,则递归访问它
        if not visited[neighbor]:
            dfs(graph, neighbor, visited)

# 例子:使用邻接表实现的无向图
n = 6
graph = [[] for _ in range(n)]
graph[0] = [1, 2]
graph[1] = [0, 3, 4]
graph[2] = [0, 4]
graph[3] = [1, 5]
graph[4] = [1, 2, 5]
graph[5] = [3, 4]

# 从节点0开始进行DFS
visited = [False] * n
dfs(graph=graph, start=0, visited=visited)

在实现中,我们使用邻接表(graph)来表示无向图的数据结构。其中,graph[i]表示节点i的所有邻居节点,即跟节点i直接相连的其他节点。

dfs函数中,我们先将起始节点标记为已访问,并输出当前节点的编号。接着,遍历当前节点的所有邻居节点,如果邻居节点没有被访问过,则递归访问它。这样,我们就可以按照深度优先的方式遍历整张图。最后,我们输出遍历过程中经过的所有节点编号。

以上的实现方式是递归方法,DFS也可以用迭代方法中的堆栈实现。

通过使用堆栈来实现

在迭代方式下,DFS可以通过使用堆栈来实现,主要思路是:

  1. 将起始节点加入到堆栈

  2. 如果堆栈非空,那么弹出栈顶元素

  3. 如果当前弹出的节点没有被访问过,那么把该节点加入到已访问节点中,并将其邻接节点压入堆栈中(这是为了接下来继续访问)

  4. 重复步骤2

用堆栈实现DFS的Python代码:

def dfs_iterative(graph, start):
    visited = set()
    stack = [start]
    while stack:
        node = stack.pop()
        if node not in visited:
            visited.add(node)
            for neighbor in graph[node]:
                stack.append(neighbor)
    return visited

在上述代码中,我们使用一个集合来存储已访问的节点,使用一个堆栈保存当前待访问的节点。若堆栈非空,那么弹出栈顶元素,判断该节点是否已经被访问。若未被访问,则将该节点标记为已访问,并把它的邻接节点压入堆栈中,等待后续访问。重复进行上述步骤,直到堆栈为空,此时遍历完成。最后,我们返回已经访问的节点集合。

二叉树上的深度优先搜索

对于二叉树上的深度优先搜索(DFS),通常有三种不同的遍历方式:

  1. 前序遍历(Preorder Traversal)
  2. 中序遍历(Inorder Traversal)
  3. 后序遍历(Postorder Traversal)

下面分别介绍这三种遍历方式的具体实现方式:

1. 前序遍历

在前序遍历中,首先访问根节点,然后递归地遍历左子树和右子树。下面是前序遍历的Python代码:

def preorder(root):
    if not root:
        return
    print(root.val)
    preorder(root.left)
    preorder(root.right)

2. 中序遍历

在中序遍历中,首先递归地遍历左子树,然后访问根节点,最后递归遍历右子树。下面是中序遍历的Python代码:

def inorder(root):
    if not root:
        return
    inorder(root.left)
    print(root.val)
    inorder(root.right)

3. 后序遍历

在后序遍历中,首先递归地遍历左子树和右子树,然后访问根节点。下面是后序遍历的Python代码:

def postorder(root):
    if not root:
        return
    postorder(root.left)
    postorder(root.right)
    print(root.val)

需要注意的是,在实现二叉树的深度优先搜索算法时,我们需要考虑如何处理空节点,以及如何标记已经被访问的节点。另外,我们还需要在代码中考虑如何传递参数和处理返回值,以便正确地实现二叉树的深度优先搜索算法。

总结

深度优先搜索(DFS)是一种用于遍历图和树的常用算法,其核心思想是从某个起始节点开始,尽可能深地遍历图或树,直到无法继续往下遍历为止,然后再回溯到上一个结点继续遍历。

DFS算法的实现可以采用递归和非递归(使用堆栈)两种方式。对于图的DFS,我们需要使用一个辅助集合来记录已经访问过的节点,在遍历时,可以采用递归方式实现,也可以使用非递归方式,使用栈来保存当前待访问的节点。

对于二叉树的DFS遍历,有三种不同的遍历方式,分别是前序遍历,中序遍历和后序遍历。在二叉树DFS遍历中,需要注意处理空节点和已访问节点的情况,还需要考虑参数传递和返回值的问题。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值