【数据结构与算法】—— * 深度优先搜索入门 (二) *

简介: 【数据结构与算法】—— * 深度优先搜索入门 (二) *

问题引入

有一天,小玄一个人去玩迷宫,但是方向感很不好的他迷路了。小澈知道后便去解救无助的小玄。小澈是有备而来,已经弄清楚了迷宫的地图,现在小澈要以最快的速度去解救小玄。问题开始了......


迷宫由n行m列的单元格组成(n,m < 50),每个单元格要么是空地,要么是障碍物。


你的任务是帮小澈找到一条从迷宫的起点到小玄所在位置的最短路径。

注意障碍物是不能走的,也不能走到迷宫外哦。

问题解析

首先我们可以用一个二维数组来储存这个迷宫。刚开始时小澈位于迷宫的入口处(1,1),小玄在(p,q),最开始只能向右或者是向下走。1.png现在只有一个小澈,我们只能一个一个去尝试。我们可以先让小澈往右走,直到走不通时再回到这里。这里我们规定一个顺序,按照顺时针的方向来尝试(即按照右,下,左,上的顺序去尝试)。

第一次尝试后的结果如下:2.png

我们这样只是尝试了一条路,并不一定是最短的。在刚才的很多地方我们有很多选择方向都是可以有多重选择的,所以我们需要把所以的选择都尝试一遍,最后输出最短的一条路径。

代码实现

现在我们尝试用深度优先搜索的方式来解决这个问题。来看看dfs这个函数怎么写。

dfs函数

dfs函数的功能是用来解决当前应该怎么办。而小澈在某个点的时候需要处理的是:先检查小澈是否到达了小玄的位置,如果没有到达则找出下一步可以走的地方。

为了解决这个问题,dfs函数需要维护三个参数,分别是

  1. 当前这个点的x坐标
  2. 当前这个点的y坐标
  3. 当前已经走过的步数step
voiddfs(intx, inty, intstep)
{
return;
}

判断是否已经到达小玄的位置这一点很好实现,只需要判断当前的坐标是否和小玄的位置相等即可

voiddfs(intx, inty, intstep)
{
  //判断是否到达小玄的位置
if (x == p && y == q)
  {
    //更新最小值
if (step < min)
min = step;
return;   //请注意这里的返回很重要
  }
return;
}

如果我们没有到达小玄的位置,则找出下一步可以走的地方。因为有四个方向可以走,根据我们之前的约定,按照顺时针的方向来尝试(即按照右,下,左,上的顺序去尝试)。为了编程方便,我们定义了一个方向数组next,如下:

intnext[4][2] = {{0,1},  //向右走
        {1,0},    //向下走
        {0,-1 },  //向左走
          {-1,0}    //向上走
};

通过这个方向数组,使用循环我们就能很容易的获得下一步的坐标。这里将下一步的横坐标用tx存储,纵坐标用ty来存储。

for (k = 0; k <= 3; k++)
{
  //计算下一个点的坐标
tx = x + next[k][0];
ty = y + next[k][1];
}

接下来我们要对下一个点的(tx,ty)进行一些判断。包括是否越界,是否为障碍物,以及这个点是否在路径中(避免重复访问一个点)。需要用一个book[tx][ty]来记录格子(tx,ty)是否已经在路径中。


如果这个点符合要求,就对这个点进行下一步的扩展,即dfs(tx,ty,step+1),注意这里是step+1,因为你一旦从这个点开始往下继续尝试,就意味着你的步数已经增加了1.


代码实现如下:

for (k = 0; k <= 3; k++)
{
  //计算下一个点的坐标
tx = x + next[k][0];
ty = y + next[k][1];
  //判断是否越界
if (tx < 1 || tx > n || ty < 1 || ty > m)
continue;
  //判断该点是否为障碍物或者已经在路径中
if (a[tx][ty] == 0 && book[tx][ty] == 0)
  {
book[tx][ty] = 1;   //标记这个点已经走过
dfs(tx, ty, step + 1);  //开始尝试下一个点
book[tx][ty] = 0;   //尝试结束,取消这个点的标记
  }
}

完整代码

#include <stdio.h>
intn, m, p, q, min = 99999999;
inta[51][51], book[51][51];
voiddfs(intx, inty, intstep)
{
intnext[4][2] = { {0,1}, //向右走
        {1,0},    //向下走
        {0,-1 },  //向左走
        {-1,0}    //向上走
  };
inttx, ty, k;
  //判断是否到达小玄的位置
if (x == p && y == q)
  {
    //更新最小值
if (step < min)
min = step;
return;   //请注意这里的返回很重要
  }
  //枚举四种走法
for (k = 0; k <= 3; k++)
  {
    //计算下一个点的坐标
tx = x + next[k][0];
ty = y + next[k][1];
    //判断是否越界
if (tx < 1 || tx > n || ty < 1 || ty > m)
continue;
    //判断该点是否为障碍物或者已经在路径中
if (a[tx][ty] == 0 && book[tx][ty] == 0)
    {
book[tx][ty] = 1;   //标记这个点已经走过
dfs(tx, ty, step + 1);  //开始尝试下一个点
book[tx][ty] = 0;   //尝试结束,取消这个点的标记
    }
  }
return;
}
intmain()
{
inti, j, startx, starty;
  //读入nmn为行,m为列
scanf("%d %d", &n, &m);
  //读入迷宫
for (i = 1; i <= n; i++)
  {
for (j = 1; j <= m; j++)
scanf("%d", &a[i][j]);
  }
  //读入起点和终点的坐标
scanf("%d %d %d %d", &startx, &starty, &p, &q);
  //从起点开始搜索
book[startx][starty] = 1;  //标记起点已经在路径中,防止后面重复走
  //第一个参数是起点的x坐标,第二个参数是起点的y坐标,第三个参数是初始步数为0dfs(startx, starty, 0);
  //输出最短步数
printf("%d", min);
getchar(); getchar();
return0;
}

总结

发明深度优先算法的John E.Hopcroft 和 Robert E .Tarjan.1971~1972年,他们在斯坦福大学研究图的连通性(任意两点是否可以互相到达)和平面性(图中所有的边不交叉。在电路板上设计布线的时候,要求线和线不能交叉。这就是平面性的一种应用)


今天的内容就分享到这啦!!

如果觉得有帮助,请:

目录
相关文章
|
2月前
|
算法 测试技术 定位技术
数据结构与算法——DFS(深度优先搜索)
数据结构与算法——DFS(深度优先搜索)
|
1月前
|
算法 安全 网络安全
数据结构之网络攻击路径(深度优先搜索)
本文介绍了如何使用深度优先搜索(DFS)算法分析网络攻击路径。在网络安全领域,DFS用于检测网络中潜在的攻击路径,帮助安全人员及时发现并阻止威胁。文中详细描述了网络图的构建、节点间的连接关系以及DFS的实现过程。通过一个具体的例子,展示了如何检测从一个普通节点到关键节点的攻击路径,并讨论了DFS算法的优缺点。提供的C++代码实现了网络图的构建和攻击路径的检测功能。
67 24
|
1月前
|
算法
数据结构之博弈树搜索(深度优先搜索)
本文介绍了使用深度优先搜索(DFS)算法在二叉树中执行遍历及构建链表的过程。首先定义了二叉树节点`TreeNode`和链表节点`ListNode`的结构体。通过递归函数`dfs`实现了二叉树的深度优先遍历,按预序(根、左、右)输出节点值。接着,通过`buildLinkedList`函数根据DFS遍历的顺序构建了一个单链表,展示了如何将树结构转换为线性结构。最后,讨论了此算法的优点,如实现简单和内存效率高,同时也指出了潜在的内存管理问题,并分析了算法的时间复杂度。
52 0
|
1月前
|
算法
数据结构之路由表查找算法(深度优先搜索和宽度优先搜索)
在网络通信中,路由表用于指导数据包的传输路径。本文介绍了两种常用的路由表查找算法——深度优先算法(DFS)和宽度优先算法(BFS)。DFS使用栈实现,适合路径问题;BFS使用队列,保证找到最短路径。两者均能有效查找路由信息,但适用场景不同,需根据具体需求选择。文中还提供了这两种算法的核心代码及测试结果,验证了算法的有效性。
102 23
|
1月前
|
传感器 算法
数据结构之环境监测系统(深度优先搜索)
环境监测系统采用深度优先搜索(DFS)算法,实现实时监测和分析环境参数,如温度、湿度等。系统通过构建传感器网络图结构,利用DFS遍历网络,检测异常数据。当温度超过预设阈值时,系统将发出警告。此系统适用于工业生产、室内空调控制、农业温室管理等多种场景,提供高效的环境监测解决方案。
49 12
|
1月前
|
算法
数据结构之旅行商问题(深度优先搜索)
旅行商问题(TSP)是寻找访问多个城市并返回起点的最短路径的经典问题。本文介绍了TSP的背景、应用、复杂性和解决方法,重点讲解了使用深度优先搜索(DFS)算法求解TSP的过程。通过邻接矩阵表示城市间的距离,利用访问数组和栈结构辅助DFS遍历,最终找到最优路径。此方法虽然能保证找到最优解,但时间复杂度高,适用于城市数量较少的情况。示例代码展示了算法的具体实现及结果分析。
49 2
|
1月前
|
算法
数据结构之农业作物管理(深度优先搜索)
本文探讨了农业作物管理系统的背景、发展动因及其在现代农业中的重要性,特别是在应对气候变化、资源减少等挑战时的作用。文中介绍了作物关系建模与深度优先搜索(DFS)的应用,展示了如何通过邻接矩阵和DFS算法实现作物的智能管理和优化。通过具体的数据结构设计和核心代码实现,说明了DFS在农业作物管理中的应用效果及优缺点。
37 1
|
1月前
|
机器学习/深度学习 算法 Python
机器学习入门:理解并实现K-近邻算法
机器学习入门:理解并实现K-近邻算法
36 0
|
2月前
|
机器学习/深度学习 算法
机器学习入门(三):K近邻算法原理 | KNN算法原理
机器学习入门(三):K近邻算法原理 | KNN算法原理
|
2月前
|
机器学习/深度学习 算法 大数据
机器学习入门:梯度下降算法(下)
机器学习入门:梯度下降算法(下)

热门文章

最新文章

  • 1
    2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
  • 2
    2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
  • 3
    2024重生之回溯数据结构与算法系列学习(8)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
  • 4
    2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
  • 5
    2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
  • 6
    2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
  • 7
    2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
  • 8
    2024重生之回溯数据结构与算法系列学习之王道第2.3章节之线性表精题汇总二(5)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
  • 9
    2024重生之回溯数据结构与算法系列学习【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
  • 10
    基于OHCI的USB主机 —— OHCI(自定义数据结构)