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

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

问题引入

输入一个数n,输出1~n的全排列


问题解析

假设有编号为1,2,3的3张扑克牌和编号为1,2,3的3个盒子。需要将这3张扑克牌分别放到3个盒子里面,并且每个盒子有且只能放一张扑克牌。问一共有多少种放法?

1.png

首先,我们按照正常的顺序来进行放置,顺序为——“1-2-3”

2.png然后我们走到了第四个盒子前,这时候已经没有扑克牌可以放置了,现在我们要重新回到3号盒子前,需要取回之前放在3号盒子里的扑克牌,再去尝试看看能不能放别的扑克牌,从而产生一个新的排列。于是我们取回3号扑克牌。

但这时候我们发现手中仍然只有3号扑克牌,没有别的选择,我们不得不回到2号盒子前收回2号扑克。现在我们手里有2张扑克牌,分别是2,3.按照之前约定的顺序(每次到一个盒子前,先放1号,再放2号,最后放3号)我们需要往2号盒子里面放3号扑克牌(上一次放的是2号扑克牌)。放好后来到三号盒子前,将手中仅剩的2号扑克牌放入3号盒子中,又来到了4号盒子面前(不存在),这时候产生了新的排列——“1.3.2”

3.png

按照这样的步骤去模拟,我们便会产生所有的排列

4.png


问题解决

最基本的问题:放入扑克牌

for(i = 1;i <= n;i++)
{
if(book[i] == 0)
    {
a[step] = i;    //book[i] 等于0表示第i号扑克还在手上
book[i] = 1;    //表明book[i]已经不在手上
    }
}

使用book数组来标记哪些数组已经使用了

将这串代码封装成一个函数,用同样的方式去处理step+1个盒子

voiddfs(intstep)   //step表示现在站在第几个盒子前面
{
  //处理第step个小盒子
for (i = 1; i <= n; i++)
  {
if (book[i] == 0)  //book[i] 等于0表示第i号扑克还在手上
    {
a[step] = i;  //将第i号扑克放入第step个盒子中
book[i] = 1;  //表明book[i]已经不在手上
    }
  }
return;
}

处理第step+1个小盒子的方法就是dfs(step+1)

voiddfs(intstep)   //step表示现在站在第几个盒子前面
{
  //处理第step个小盒子
for (i = 1; i <= n; i++)
  {
if (book[i] == 0)  //book[i] 等于0表示第i号扑克还在手上
    {
a[step] = i;  //将第i号扑克放入第step个盒子中
book[i] = 1;  //表明book[i]已经不在手上
dfs(step + 1);  //这里用函数递归的调用来实现(自己调用自己)
book[i] = 0;  //这是非常重要的一步,一定要将刚才尝试的扑克牌收回,才能进行下一步尝试
      //如果不把刚才放入小盒子的扑克牌收回,那将无法再进行下一步的摆放
      //当step = n + 1时,表明前n个盒子都已经放好扑克了
    }
  }
return;
}

上面代码中的 book[i] = 0 这条语句非常重要,这句话的作用是将小盒子中的扑克牌收回,因为在一次摆放尝试结束返回的时候,如果不把刚才放入小盒子中的扑克牌收回,那将无法进行下一次摆放。

当我们处理到第n+1个盒子的时候,证明我们前n个已经排序完毕,将他们打印出来即可。

打印完毕一定要return,否则会无休止地运行下去。

完整代码

//深度优先搜索
inta[10], book[10], n;
//C语言的全局变量在没有赋值以前默认为0//因此这里的book数组无需再全部赋值初始值0//将放牌封装成一个函数
voiddfs(intstep)   //step表示现在站在第几个盒子前面
{
inti;
if (step == n + 1)    //如果站在第n+1个盒子前,表明前n个盒子都已经完成了放置
  {
    //输出一种排列
for (i = 1; i <= n; i++)
printf("%d", a[i]); 
printf("\n");
return;   //返回之前最近的一步(最近一次调用dfs的地方)
    //打印完要立即return,否则会无限循环下去
  }
  //处理第step个小盒子
for (i = 1; i <= n; i++)
  {
if (book[i] == 0)  //book[i] 等于0表示第i号扑克还在手上
    {
a[step] = i;  //将第i号扑克放入第step个盒子中
book[i] = 1;  //表明book[i]已经不在手上
dfs(step + 1);  //这里用函数递归的调用来实现(自己调用自己)
book[i] = 0;  //这是非常重要的一步,一定要将刚才尝试的扑克牌收回,才能进行下一步尝试
      //如果不把刚才放入小盒子的扑克牌收回,那将无法再进行下一步的摆放
      //当step = n + 1时,表明前n个盒子都已经放好扑克了
    }
  }
return;
}
intmain()
{
scanf("%d", &n);  //输入时要注意为1-9之间的整数
dfs(1); //首先站在1号小盒面前
return0;
}

总结

深度优先搜索(Depth First Search,DFS)

理解深度优先搜索的关键在于解决“当下该如何做”。至于“下一步该如何做”,则与“当下该如何做”是一样的。

基本模型

voiddfs(intstep)
{
    判断边界
    尝试每一种可能
for(i = 1;i <= n;i++)
    {
    继续下一步的尝试 dfsstep+1    }
    返回
}

每一种尝试就是一种“扩展”。每次站在一个盒子前面的时候,都有n种扩展方法,但不是每一种方法都能够成功扩展。


这就是今天的全部内容啦,如果觉得有帮助,请

目录
相关文章
|
12天前
|
机器学习/深度学习 算法 机器人
【机器人路径规划】基于深度优先搜索(Depth-First-Search,DFS)算法的机器人路径规划(Python代码实现)
【机器人路径规划】基于深度优先搜索(Depth-First-Search,DFS)算法的机器人路径规划(Python代码实现)
|
5月前
|
人工智能 运维 算法
基于 C# 深度优先搜索算法的局域网集中管理软件技术剖析
现代化办公环境中,局域网集中管理软件是保障企业网络高效运行、实现资源合理分配以及强化信息安全管控的核心工具。此类软件需应对复杂的网络拓扑结构、海量的设备信息及多样化的用户操作,而数据结构与算法正是支撑其强大功能的基石。本文将深入剖析深度优先搜索(Depth-First Search,DFS)算法,并结合 C# 语言特性,详细阐述其在局域网集中管理软件中的应用与实现。
127 3
|
6月前
|
监控 算法 安全
基于 PHP 语言深度优先搜索算法的局域网网络监控软件研究
在当下数字化时代,局域网作为企业与机构内部信息交互的核心载体,其稳定性与安全性备受关注。局域网网络监控软件随之兴起,成为保障网络正常运转的关键工具。此类软件的高效运行依托于多种数据结构与算法,本文将聚焦深度优先搜索(DFS)算法,探究其在局域网网络监控软件中的应用,并借助 PHP 语言代码示例予以详细阐释。
117 1
|
7月前
|
运维 监控 JavaScript
内网网管软件中基于 Node.js 的深度优先搜索算法剖析
内网网管软件在企业网络中不可或缺,涵盖设备管理、流量监控和安全防护。本文基于Node.js实现深度优先搜索(DFS)算法,解析其在网络拓扑遍历中的应用。通过DFS,可高效获取内网设备连接关系,助力故障排查与网络规划。代码示例展示了图结构的构建及DFS的具体实现,为内网管理提供技术支持。
125 11
|
10月前
|
算法 安全 网络安全
数据结构之网络攻击路径(深度优先搜索)
本文介绍了如何使用深度优先搜索(DFS)算法分析网络攻击路径。在网络安全领域,DFS用于检测网络中潜在的攻击路径,帮助安全人员及时发现并阻止威胁。文中详细描述了网络图的构建、节点间的连接关系以及DFS的实现过程。通过一个具体的例子,展示了如何检测从一个普通节点到关键节点的攻击路径,并讨论了DFS算法的优缺点。提供的C++代码实现了网络图的构建和攻击路径的检测功能。
223 24
|
7月前
|
机器学习/深度学习 算法
算法系列之搜索算法-深度优先搜索DFS
深度优先搜索和广度优先搜索一样,都是对图进行搜索的算法,目的也都是从起点开始搜索,直到到达顶点。深度优先搜索会沿着一条路径不断的往下搜索,直到不能够在继续为止,然后在折返,开始搜索下一条候补路径。
415 62
算法系列之搜索算法-深度优先搜索DFS
|
6月前
|
算法 安全 Java
算法系列之深度优先搜索寻找妖怪和尚过河问题的所有方式
在算法学习中,深度优先搜索(DFS)是一种常用的图搜索算法,通过递归或栈实现,适合路径搜索、连通性、拓扑排序、回溯、生成、环路检测、强连通分量和可达性等问题。本文将介绍如何利用深度优先搜索解决“妖怪和尚过河问题”的所有方式。
138 26
算法系列之深度优先搜索寻找妖怪和尚过河问题的所有方式
|
10月前
|
算法
数据结构之博弈树搜索(深度优先搜索)
本文介绍了使用深度优先搜索(DFS)算法在二叉树中执行遍历及构建链表的过程。首先定义了二叉树节点`TreeNode`和链表节点`ListNode`的结构体。通过递归函数`dfs`实现了二叉树的深度优先遍历,按预序(根、左、右)输出节点值。接着,通过`buildLinkedList`函数根据DFS遍历的顺序构建了一个单链表,展示了如何将树结构转换为线性结构。最后,讨论了此算法的优点,如实现简单和内存效率高,同时也指出了潜在的内存管理问题,并分析了算法的时间复杂度。
267 0
|
6月前
|
监控 算法 JavaScript
企业用网络监控软件中的 Node.js 深度优先搜索算法剖析
在数字化办公盛行的当下,企业对网络监控的需求呈显著增长态势。企业级网络监控软件作为维护网络安全、提高办公效率的关键工具,其重要性不言而喻。此类软件需要高效处理复杂的网络拓扑结构与海量网络数据,而算法与数据结构则构成了其核心支撑。本文将深入剖析深度优先搜索(DFS)算法在企业级网络监控软件中的应用,并通过 Node.js 代码示例进行详细阐释。
115 2
|
6月前
|
存储 算法 JavaScript
基于 Node.js 深度优先搜索算法的上网监管软件研究
在数字化时代,网络环境呈现出高度的复杂性与动态性,上网监管软件在维护网络秩序与安全方面的重要性与日俱增。此类软件依托各类数据结构与算法,实现对网络活动的精准监测与高效管理。本文将深度聚焦于深度优先搜索(DFS)算法,并结合 Node.js 编程语言,深入剖析其在上网监管软件中的应用机制与效能。
94 6

热门文章

最新文章