经典算法之深度优先搜索(DFS)

简介: 经典算法之深度优先搜索(DFS)

一、前言

本文介绍了经典搜索算法: 深度优先搜索(DFS)

两个小故事:

岳云鹏的相声:孙越的爸爸带他参观家里面的聚宝盆,走到了一个密室门前,密室的门上上了一把锁,孙越的爸爸身上带了一万多把钥匙,他还忘了哪一把钥匙能打开个门了,于是就一把把试,试到了最后一把,门开了。

你叫DFS,在一次校园活动中你认识了三个非常漂亮的女孩,你想和她们进一步发展。于是,你选择了其中一个人,并对她展开了追求,你采用了 聊天->约会->表白 的恋爱三部曲。但是很不幸,她拒绝了你,于是你添加了第二个女生的微信,同样采取了你常用的三部曲。很不幸,第二个女生也拒绝你了。但是,你没有被困难打倒,于是你添加了第三个女生的微信,依旧是这三部曲,终于,第三个女生答应了你。你的朋友询问你,是如何找到女朋友的?,你答:我采用了DFS对象法🙈


二、基本概念

1.简单介绍

前言中的两个小故事,孙越的爸爸找钥匙开门的过程和DFS小朋友找女朋友都是一个搜索过程。
简而言之,搜索就是尝试问题中所有的可能性,在所有的可能性中找到正确的结果。而深度优先搜索用一句话概括就是:“ 一直往下走,走到最后还是走不通,那就换条路再走,直到无路可走。”用一个成语来形容,那就是 :“ 不撞南墙不回头。”
在这里插入图片描述

2. 官方概念

以下是维基百科上的解释:

深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。这个算法会尽可能深地搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。这种算法不会根据图的结构等信息调整执行策略

三、动图分析

DFS会从初始节点出发,按预定的顺序扩展到下一个节点,然后从下一节点出发继续扩展新的节点,不断递归执行这个过程,直到某个节点不能再扩展下一个节点为止。此时,则返回上一个节点重新寻找一个新的扩展节点。如此搜索下去,直到找到目标节点,或者搜索完所有节点为止。

动图:

在这里插入图片描述

四、模板框架

💞以下模板来自于大佬Carl:

void DFS(参数){
    if (终止条件){
        做要做的事
        return ;//退出 
    }
    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小))
        {
            处理节点;
            DFS(路径,选择列表);
            回溯:回到没用过
        }
    return ;//退出 
}

五、例题分析

组合问题

题干描述:

力扣77题:组合
给定两个整数 nk,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
输入:n = 4, k = 2
输出:

[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

输入:n = 1, k = 1
输出:

[[1]]

思路分析

图片来自于力扣
C语言代码:

int* path;
int pathTop;
int** ans;
int ansTop;

void DFS(int n, int k,int startIndex) {
    //当path中元素个数为k个时,我们需要将path数组放入ans二维数组中
    if(pathTop == k) {
        //path数组为我们动态申请,若直接将其地址放入二维数组,path数组中的值会随着我们回溯而逐渐变化
        //因此创建新的数组存储path中的值
        int* temp = (int*)malloc(sizeof(int) * k);
        int i;
        for(i = 0; i < k; i++) {
            temp[i] = path[i];
        }
        ans[ansTop++] = temp;
        return ;
    }

    int j;
    for(j = startIndex; j <=n ;j++) {
        //将当前结点放入path数组
        path[pathTop++] = j;
        //进行递归
        DFS(n, k, j + 1);
        //进行回溯,将数组最上层结点弹出
        pathTop--;
    }
}

int** combine(int n, int k, int* returnSize, int** returnColumnSizes){
    //path数组存储符合条件的结果
    path = (int*)malloc(sizeof(int) * k);
    //ans二维数组存储符合条件的结果数组的集合。(数组足够大,避免极端情况)
    ans = (int**)malloc(sizeof(int*) * 10000);
    pathTop = ansTop = 0;
    DFS(n, k, 1);
    //最后的返回大小为ans数组大小
    *returnSize = ansTop;
    //returnColumnSizes数组存储ans二维数组对应下标中一维数组的长度(都为k)
    *returnColumnSizes = (int*)malloc(sizeof(int) *(*returnSize));
    int i;
    for(i = 0; i < *returnSize; i++) {
        (*returnColumnSizes)[i] = k;
    }
    //返回ans二维数组
    return ans;
}
相关文章
|
6月前
|
算法 测试技术 定位技术
数据结构与算法——DFS(深度优先搜索)
数据结构与算法——DFS(深度优先搜索)
|
12天前
|
监控 算法 安全
基于 PHP 语言深度优先搜索算法的局域网网络监控软件研究
在当下数字化时代,局域网作为企业与机构内部信息交互的核心载体,其稳定性与安全性备受关注。局域网网络监控软件随之兴起,成为保障网络正常运转的关键工具。此类软件的高效运行依托于多种数据结构与算法,本文将聚焦深度优先搜索(DFS)算法,探究其在局域网网络监控软件中的应用,并借助 PHP 语言代码示例予以详细阐释。
27 1
|
2月前
|
运维 监控 JavaScript
内网网管软件中基于 Node.js 的深度优先搜索算法剖析
内网网管软件在企业网络中不可或缺,涵盖设备管理、流量监控和安全防护。本文基于Node.js实现深度优先搜索(DFS)算法,解析其在网络拓扑遍历中的应用。通过DFS,可高效获取内网设备连接关系,助力故障排查与网络规划。代码示例展示了图结构的构建及DFS的具体实现,为内网管理提供技术支持。
49 11
|
2月前
|
机器学习/深度学习 算法
算法系列之搜索算法-深度优先搜索DFS
深度优先搜索和广度优先搜索一样,都是对图进行搜索的算法,目的也都是从起点开始搜索,直到到达顶点。深度优先搜索会沿着一条路径不断的往下搜索,直到不能够在继续为止,然后在折返,开始搜索下一条候补路径。
107 62
算法系列之搜索算法-深度优先搜索DFS
|
22天前
|
算法 安全 Java
算法系列之深度优先搜索寻找妖怪和尚过河问题的所有方式
在算法学习中,深度优先搜索(DFS)是一种常用的图搜索算法,通过递归或栈实现,适合路径搜索、连通性、拓扑排序、回溯、生成、环路检测、强连通分量和可达性等问题。本文将介绍如何利用深度优先搜索解决“妖怪和尚过河问题”的所有方式。
68 26
算法系列之深度优先搜索寻找妖怪和尚过河问题的所有方式
|
5天前
|
监控 算法 JavaScript
企业用网络监控软件中的 Node.js 深度优先搜索算法剖析
在数字化办公盛行的当下,企业对网络监控的需求呈显著增长态势。企业级网络监控软件作为维护网络安全、提高办公效率的关键工具,其重要性不言而喻。此类软件需要高效处理复杂的网络拓扑结构与海量网络数据,而算法与数据结构则构成了其核心支撑。本文将深入剖析深度优先搜索(DFS)算法在企业级网络监控软件中的应用,并通过 Node.js 代码示例进行详细阐释。
23 2
|
11天前
|
存储 算法 JavaScript
基于 Node.js 深度优先搜索算法的上网监管软件研究
在数字化时代,网络环境呈现出高度的复杂性与动态性,上网监管软件在维护网络秩序与安全方面的重要性与日俱增。此类软件依托各类数据结构与算法,实现对网络活动的精准监测与高效管理。本文将深度聚焦于深度优先搜索(DFS)算法,并结合 Node.js 编程语言,深入剖析其在上网监管软件中的应用机制与效能。
28 6
|
2月前
|
存储 人工智能 算法
【深度优先搜索篇】走迷宫的魔法:算法如何破解迷宫的神秘密码
【深度优先搜索篇】走迷宫的魔法:算法如何破解迷宫的神秘密码
|
8月前
|
算法
DFS算法的实现
DFS算法的实现
114 3
|
5月前
|
算法
数据结构之路由表查找算法(深度优先搜索和宽度优先搜索)
在网络通信中,路由表用于指导数据包的传输路径。本文介绍了两种常用的路由表查找算法——深度优先算法(DFS)和宽度优先算法(BFS)。DFS使用栈实现,适合路径问题;BFS使用队列,保证找到最短路径。两者均能有效查找路由信息,但适用场景不同,需根据具体需求选择。文中还提供了这两种算法的核心代码及测试结果,验证了算法的有效性。
189 23

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等