DFS 深度优先搜索 —— 一种探险的算法

一、引言

深度优先搜索是什么?

深度优先搜索(DFS, Depth First Search)是一个针对图和树的遍历算法。

DFS与其他搜索算法的区别。

  1. 深度优先搜索(DFS)是一种利用递归实现的搜索算法。在搜索过程中,DFS从根节点开始,探索尽可能深的分支,如果当前节点没有未访问的邻接点,则回溯到上一个节点,继续探索下一个未访问的邻接点。DFS使用的数据结构是栈,其特点是一旦放入栈中,就不会被移除,直到栈顶被压入新的元素或者栈被清空。因此,DFS是沿着树或图的深度遍历,直到找到目标或达到无法继续搜索为止。
  2. 广度优先搜索(BFS)则是一种利用队列实现的搜索算法。其搜索过程和“湖面丢进一块石头激起层层涟漪”类似,先搜索邻居,搜完邻居再搜邻居的邻居。具体来说,BFS将当前节点的所有未访问的邻接点放入队列中,然后从队列的前端取出节点进行访问,同时将该节点标记为已访问。这个过程会一直进行,直到队列为空,即没有未访问的邻接点。由于BFS按照广度进行搜索,因此它更适用于广度较大的图或树。

DFS在各种计算问题中的应用。

DFS和BFS都是用于遍历或搜索树或图的算法,但它们适用于不同的场景。

  1. DFS(深度优先搜索)的主要应用场景包括:
  • 迷宫搜索:如果要在给定的迷宫中找到从起点到终点的路径,DFS是一个合适的选择,因为它可以深入地搜索路径,直到找到出口或无法继续前进。
  • 回溯算法:对于解决某些需要回溯的问题,如求解数独或解决逻辑推理问题,DFS是一种常用的算法,因为它可以深入地搜索问题的解空间,直到找到解决方案或确定无解。
  • 图的遍历:如果需要遍历一个图的所有节点,DFS可以高效地实现这个目标,因为它可以深入地搜索图的分支,直到找到所有未访问的节点。
  1. BFS(广度优先搜索)的主要应用场景包括:
  • 最短路径问题:BFS可以用于寻找从一个节点到另一个节点的最短路径,因为它会先遍历离起点近的节点,再逐步向外扩展,直到找到目标节点。例如,在解决图中的最短路径问题时,BFS通常是一个合适的选择。
  • 图的遍历:如果需要按层次遍历一个图,BFS是一个很好的选择。它会先访问离起点最近的节点,然后逐层向外扩展,直到访问完所有的节点。
  • 宽度优先搜索:在一些需要将信息分批处理的场景中,如网络爬虫的页面抓取,BFS按广度进行搜索和处理,能够高效地处理大量信息。

需要注意的是,DFS和BFS在具体应用中可能受到一些限制。例如,DFS不适合用于循环图或存在多个起点的图,因为它可能会陷入无限循环;而BFS也不适合用于稀疏图或非常大的图,因为它需要存储大量的节点和边信息。因此,在实际应用中需要根据具体的问题和数据结构选择合适的搜索算法。

二、深度优先搜索的基本概念

定义和术语

  1. 搜索树:在深度优先搜索中,每个节点的搜索顺序都会被记录下来,这些顺序形成一个树形结构,被称为搜索树。
  2. 根节点:搜索树的第一个节点被称为根节点,它是搜索的起点。
  3. 叶节点:搜索树的最后一个节点被称为叶节点,它是搜索的终点。
  4. 节点扩展:在深度优先搜索中,从一个节点开始,通过扩展该节点的所有未访问过的邻接节点,来寻找新的解。
  5. 回溯:当深度优先搜索无法通过当前节点的邻接节点找到新的解时,会回溯到上一个节点,并尝试其他未访问过的邻接节点。
  6. 剪枝:在深度优先搜索中,可以通过对搜索树进行剪枝来减少搜索的空间,从而提高搜索效率。剪枝是通过判断当前分支不可能存在解而将其删除。
  7. 记忆化搜索:在深度优先搜索中,可以使用记忆化搜索来避免重复搜索已经访问过的节点。记忆化搜索是一种将已访问过的节点存储起来,以便在后续搜索中可以快速查找的方法。

 

DFS的搜索过程

深度优先搜索(DFS)(C++) - 知乎

终止条件和回溯

        终止条件

  1. 遍历完所有的顶点:DFS是一种深度优先的搜索算法,它会遍历图中的所有顶点。当所有的顶点都被访问过,也就是没有未遍历的节点时,搜索过程就会终止。

  2. 找到目标:如果DFS的目标是找到特定的顶点或路径,当找到这个目标时,搜索过程就会终止。

  3. 达到终止状态:在某些情况下,图中的顶点可能满足某种终止状态。例如,对于一个排程问题,如果所有的任务都已经完成或者无法再被调度,搜索过程就会终止。

  4. 没有更多的未访问顶点:如果DFS中没有更多的未访问顶点,也就是说所有的顶点都已被访问过,此时搜索过程就会终止。

        回溯与DFS的关系

        DFS 是一个劲的往某一个方向搜索,而回溯算法是建立在 DFS 基础之上的,但不同的是在搜索过程中,达到结束条件后,恢复状态,回溯上一层,再次搜索。因此回溯算法与 DFS 的区别就是有无状态重置

 

三、深度优先搜索的实现

  • 递归实现。
    ​​​​​​​

    <?php
    
    function dfs($graph, $start, $visited = [])  
    {  
        // 标记当前节点为已访问  
        $visited[$start] = true;  
        echo $start . " ";  
      
        // 遍历当前节点的所有邻居节点  
        foreach ($graph[$start] as $neighbor) {  
            // 如果邻居节点未被访问,则递归调用 dfs 函数  
            if (empty($visited[$neighbor])) {  
                dfs($graph, $neighbor, $visited);  
            }  
        }  
    }  
      
    // 示例图的邻接表表示  
    $graph = [  
        0 => [1, 2],  
        1 => [2],  
        2 => [0, 3],  
        3 => [3]  
    ];  
      
    // 从节点 2 开始进行深度优先搜索  
    dfs($graph, 2);

  • 非递归实现。

    • 用栈实现

<?php  
  
function dfs($graph, $start)  
{  
    $visited = [];  
    $stack = [];  
    $stack[] = $start;  
  
    while (!empty($stack)) {  
        $node = array_pop($stack);  
  
        // 标记当前节点为已访问  
        $visited[$node] = true;  
        echo $node . " ";  
  
        // 将当前节点的未访问邻居节点入栈  
        foreach ($graph[$node] as $neighbor) {  
            if (empty($visited[$neighbor])) {  
                $stack[] = $neighbor;  
            }  
        }  
    }  
}  
  
// 示例图的邻接表表示  
$graph = [  
    0 => [1, 2],  
    1 => [2],  
    2 => [0, 3],  
    3 => [3]  
];  
  
// 从节点 2 开始进行深度优先搜索  
dfs($graph, 2);

 

四、深度优先搜索的优化

  1. 记忆化搜索。

  2. 使用启发式信息。

  3. 处理重复节点。

五、深度优先搜索的应用实例

  1. 图的遍历。

  2. 树的遍历。

  3. 八皇后问题。

  4. 数独。

六、总结与展望
​​​​​​​

深度优先搜索(DFS)是一种常用的图遍历算法,它具有以下优点:

  1. DFS能够遍历整张图,包括所有分支和节点,不会出现遗漏或未访问的节点。
  2. 在一些情况下,DFS的算法复杂度比其他遍历算法更低,因此在某些情况下更适合大规模的图。
  3. 在某些情况下,DFS需要使用递归或栈来实现,这可能会导致大量的内存开销和递归调用开销。
  4. 如果图中存在大量的节点和边,可能会导致搜索效率低下,需要更复杂的优化策略来提高效率。
  5. DFS对于图的某些特性(例如连通性、无环性等)没有很好的处理方式,需要额外的算法来处理。
  6. 在分布式系统中,DFS的局限性更加明显。例如,DFS在分布式环境中需要实现节点间的通信和同步,这可能会增加系统的开销和复杂性。

场景总结

  1. 搜索引擎:DFS被广泛应用于网页信息的抓取和索引,是搜索引擎的重要组成部分。通过DFS遍历整个网页,可以获得网页之间的链接关系,以及网页的内容和元数据等信息,为搜索引擎提供索引和搜索结果。

  2. 图数据库:图数据库是一种以图形结构为基础的数据库,可以存储、管理和查询实体之间的复杂关系。DFS是图数据库中一种非常有用的查询算法,可以高效地遍历和查询图中的节点和边。

  3. 网络安全:DFS在网络安全领域也有很多应用,例如攻击面扫描、漏洞扫描、入侵检测等。通过DFS遍历整个网络,可以发现网络中的漏洞和弱点,及时进行修补和防范。

  4. 数据挖掘:DFS在数据挖掘领域中也有很多应用,例如关联规则挖掘、聚类分析、序列模式挖掘等。通过DFS遍历数据集中的所有元素,可以发现数据之间的关联和规律,为决策提供有力的支持。

  5. 人工智能:DFS在人工智能领域中也有很多应用,例如知识图谱、自然语言处理、机器学习等。通过DFS遍历知识图谱中的节点和边,可以进行知识的表示、推理和学习。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值