DFS搜索算法详解

2023-05-16

                                                                             深度优先搜索

                                                                                                ---一条道走到黑

DFS其实叫深度优先搜索算法,起始它只是一种搜索的方法思路,并没有固定的算法格式。让我们通过一个社交图的例子来看。

我们拿到一个社交关系无向图:

通过无向图可以得到邻接矩阵 

用1表示他们有社交关系,0表示没有社交关系。

 我们提出一个问题,怎样通过无向图能够找出一个人所有的朋友呢,答案可以是深度优先搜索。

借助邻接矩阵可以得到各个人物之间的社会关系,通过一个人去找他的朋友(它朋友的朋友也是他的朋友),比如zzx的朋友有lxh、lrz、cy。

首先能够找到lxh,通过lxh找到了lrz,再通过lxh找到了cy。可以看出搜索的过程中,有时候需要前一个已经访问到的朋友,自然而然的可以想起递归的方式。

使用递归,首先循环体是得到朋友的下标,遍历朋友那一行,访问朋友的朋友。这个过程中我们要知到哪些朋友已经访问过了,所以在访问之后应该标记为以访问状态。代码如下:

递归循环体,用true表示已访问状态,顺便打印出朋友名称,遍历朋友那一行找出新朋友,当得到新朋友的时候,重复上一次的操作。(写递归,首先简化问题,找出循环体,找出出递归条件)

        cout << i << m_v[i].c_str() << "->";
		arr[i] = true;

		for (int j = 0; j < m_v.size(); ++j)
		{
			if (m_edges[i][j]!=0 && arr[j]==false)
			{
				  _DFS(j, arr);//此处没有return 因为函数没有返回值,有return会产生意想不到的错误

			}
		}

完整代码

    void _DFS(int i, vector<bool> & arr)
	{
		//&  使用递归的时候应该注意的是,当递归参数要在整个程序中保持最新值的时候,
		//参数应该传引用,或者指针,因为局部变量的话,在函数体出栈的时候,会更新成
		//本次栈中的局部变量,产生与预期不符的结果

		cout << i << m_v[i].c_str() << "->";
		arr[i] = true;

		for (int j = 0; j < m_v.size(); ++j)
		{
			if (m_edges[i][j]!=0 && arr[j]==false)
			{
			   _DFS(j, arr);//此处没有return 因为函数没有返回值,有return会产生意想不到的错误
			}//for循环的终止条件作为递归的终止条件。
		}
	}
	void DFS(const V & val)
	{
		int ret = GetVertexIndex(val);
		vector<bool> flag(m_v.size(), false);

		_DFS(ret, flag);
	}

工程:https://github.com/lixuhui123/Graph

再看一个放扑克牌的例子。有三个桶,三张扑克牌,要求每个桶发一张扑克牌,输出牌的所有排列组合。

使用DFS,约定扑克牌按从小到大的方式放,有三个桶,依次在桶里放一张,循环体是,在所有的未使用的牌当中,放一张到当前桶中去。(这里需要一个数组标记这个牌有没有被使用)

        for (int i = 1; i <= pai; ++i)
	{
		if (flags[i]==false)
		{
			books[steps] = i;
			flags[i] = true;
		}
	}

什么时候输出一种排列组合呢,当到达的桶的序号大于给定桶的个数的时候,意味着所有的桶已经被装填。

        if (steps == pai + 1)
	{
		for(int i=1;i<=pai;++i)
		{
			cout << books[i] << ' ';
		}
		cout << endl;
		return;
	}

当当前桶被放满的时候,就需要进入下一个桶,也就是

        for (int i = 1; i <= pai; ++i)
	{
		if (flags[i]==false)
		{
			books[steps] = i;
			flags[i] = true;
            dfs(steps + 1);
		}
	}

要输出所有的排列组合,一张牌要被使用好多次,涉及到牌的回收重新标记未使用。这个过程应该在每次递归出栈之后做,而且标记数组必须传引用或者是全局变量。

        for (int i = 1; i <= pai; ++i)
	{
		if (flags[i]==false)
		{
			books[steps] = i;
			flags[i] = true;
                dfs(steps + 1);
			flags[i] = false;
		}
	}

 完整代码:

//输出的是给定所有牌的全排列
#include <iostream>
#include<vector>
using namespace std;
//首先是每次都要重复干的事情,每次就是在盒子前面将手里的牌按从小到大的顺序放一张放到
//盒子里面
bool flags[4] = { false };
int  books[4];
int pai = 3;
void dfs(int steps)
{
	//先做三个盒子三张扑克牌
	if (steps == pai + 1)
	{
		for(int i=1;i<=pai;++i)
		{
			cout << books[i] << ' ';
		}
		cout << endl;
		return;
	}
	for (int i = 1; i <= pai; ++i)
	{
		if (flags[i]==false)
		{
			books[steps] = i;
			flags[i] = true;
            dfs(steps + 1);
			flags[i] = false;
		}
	}
		

}
int main()
{
	dfs(1);
	system("pause"); 
	return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DFS搜索算法详解 的相关文章

  • 数字三角形(java)

    问题描述 在数字三角形中寻找一条从顶部到底边的路径 使得路径上所经过的数字之和最大 路径上的每一步都只能往左下或 右下走 只需要求出这个最大和即可 不必给出具体路径 三角形的行数大于1小于等于100 数字为 0 99输入格式 输入格式 5
  • D - 整数变换问题

    整数变换问题 题意 问我们最少经过多少次变换可以将n转化为m 题解 这个题我们很容易想到就是用dfs 但是数据范围也很明显不能用直接的暴力 所以我们需要剪枝 我们假设用最原始的暴力 就是每次循环两种情况一直到最后 这样的暴力很机械 很盲目
  • 寻找 有向图/无向图 所有环路的DFS暴力求解法(ps:C++代码,复杂度爆炸警告,生产环境慎用)

    思路 1 DFS算法可以求解图中从一点到另一点的全部路径 2 通过枚举所有顶点的邻接点 然后通过DFS寻找枚举点到的所有路径来寻找环路 3 思路很简单 但是算法复杂度确实是太高了 下面上代码 include
  • 2023最新一文学会fastdfs单节点部署(含安装包镜像包)

    1 实验环境 镜像版本 麒麟服务器镜像V10SP2 镜像下载地址 链接 https pan baidu com s 11BopM7FsmvUFud D68J7Rg pwd 1234 提取码 1234 安装包下载地址 链接 https pan
  • [POI2008]CLO-Toll

    题目链接 本题有个小点需要注意 如果说它是多个相互不连通的图 也有可能形成一个可行解 多个环嘛 然后剩下的 就是dfs去跑 如果跑出了返祖边 那么这个返祖边抵达的点 将改变原来的方向 剩下的就都是正方向 dfs直接跑就是了 include
  • 200. Number of Islands

    求岛屿的数量 求岛屿的数目情况 主要有两种情况 解析 这道题目的本质问题其实是想就求 不相连的1 的块数目情况 在查找的过程当中 相邻的1是当做只有一块的基本情况 要去何必周边的1 情况 就是标记为是岛屿就行了这种情况下 就是利用一个一直回
  • Tempter of the Bone【DFS+奇偶剪枝】scanf会WA!!!

    题目链接HDU1010 多好的一道题 交scanf会WA cin一发过 我WA了30 次 惊是这样的BUG 我就说我推的公式怎会错呢 如果有字体缩小的方式 我要把上面那行缩小些 先看大家WA 可真是一道有趣的题目 首先 有这样的图推出奇偶剪
  • 数据结构——深度优先遍历(DFS)无向连通图

    以下是数据结构中关于深度优先遍历无向连通图的操作 编程风格参考严蔚敏版数据结构 其实深度优先遍历就是二叉树的先序遍历的推广 头文件以及宏定义 include
  • 算法---LeetCode 200. 岛屿数量

    1 题目 原题链接 给你一个由 1 陆地 和 0 水 组成的的二维网格 请你计算网格中岛屿的数量 岛屿总是被水包围 并且每座岛屿只能由水平方向和 或竖直方向上相邻的陆地连接形成 此外 你可以假设该网格的四条边均被水包围 示例 1 输入 gr
  • 洛谷题单 算法1-7 搜索

    USACO08FEB Meteor Shower S 题目描述 Bessie hears that an extraordinary meteor shower is coming reports say that these meteor
  • LeetCode-679.24 点游戏、深度优先搜索算法DFS

    来源 力扣 LeetCode 题目分析 括号运算符仅仅表达了一个运算顺序 可以不用考虑 实际的运算类型就 4 种 一共只有 4 个数 因此所有组合的可能性是有限的 DFS 算法就是对当前的所有可能的操作进行枚举 当前的操作即从可选的数字中挑
  • 7-33 地下迷宫探索 (30 分)(思路加详解)

    一 题目 7 33 地下迷宫探索 30 分 地道战是在抗日战争时期 在华北平原上抗日军民利用地道打击日本侵略者的作战方式 地道网是房连房 街连街 村连村的地下工事 如下图所示 我们在回顾前辈们艰苦卓绝的战争生活的同时 真心钦佩他们的聪明才智
  • 02 二叉树的DFS(前序、中序或后序遍历实现)【Binary Tree 二叉树】

    二叉树的深度优先遍历主要有三种 前序 根左右 中序 左根右 后序 左右根 下面是完整的实现和讲解 include
  • CMake:递归检查并拷贝所有需要的DLL文件

    文章目录 1 目的 2 设计 整体思路 多层依赖的处理 获取 DLL 所在目录 探测剩余的 DLL 文件 3 代码实现 判断 stack 是否为空 判断 stack 是否为空 获取所有 target 检测并拷贝 DLL 4 使用 1 目的
  • poj 3074 Sudoku

    Time Limit 1000MS Memory Limit 65536K Total Submissions 7613 Accepted 2696 Description In the game of Sudoku you are giv
  • 【算法学习笔记】17:DFS与BFS

    1 DFS 深度优先搜索常用于解决需要给出所有方案的问题 因为它的搜索顺序就是能够得到一个完整的搜索路径 方案 后回退再去搜索其它的方案 1 1 例题 排列数字 由于要求所有排列的方案 可以每次从 1 n 1 n 1 n里拿一个数字 然后记
  • 剑指offer.13.机器人的运动范围之DFS、BFS搜索

    机器人的运动范围 前言 一 DFS 1 思想 2 源码 二 BFS 1 源码 2 改进源码BFS 总结 前言 对于矩阵搜索问题 就像图的搜索一样 熟练掌握DFS BFS是关键 一 DFS 1 思想 通过DFS去寻找满足条件的格子 而已经访问
  • Codeforces-1454E Number of Simple Paths(基环树-思维)

    题目大意 给你n个点 n条边 求图中简单路径的个数 题目思路 n个点n条边 那么图中一定有一个环 拿这个图来讲 我们将两点间的关系分为4种 1 两点都在环上 简单路径的个数为2 例如2与5 2 一个点在环上一个点不在环上 简单路径个数为2
  • 【算法】深度优先搜索DFS 入门:基本知识+经典例题

    DFS最重要的是理清搜索顺序 ps 这是我入门dfs时写的博客 后来dfs渐渐熟练了 也补充了一些题目上去 带原题和代码 个人感觉整篇博文从上到下确实由易到难 代码也由开始的冗长变得渐渐精简 自学DFS看的视频 小甲鱼 讲原理 青岛大学 王
  • 数据结构--树存储结构 & 深度优先遍历 & 广度优先遍历 通俗易懂

    树的概念 首先 树是一种常用的非线性数据结构 是以边 Edge 相连的节点 Node 的集合 每个节点存储对应的值 当存在子节点时与之相连 根节点 是树的首个节点 边 所有节点都由边相连 用于标识节点间的关系 叶子结点 树的末端节点 它们没

随机推荐

  • SSL和TLS-TLS 介绍

    SSL和TLS TLS 介绍 TLS PRFGeneration of Keying Material TLS协议在结构上与SSL协议相同 是一个客户端 服务器协议 xff0c 运行在可靠的传输层协议之上 xff0c 比如TCP 和SSL一
  • less

    less语法 xff1a 目标 xff1a 使用less运算写法完成px单位到rem单位的转换 css不支持计算写法 xff0c 可以通过less实现 less是一个css 39 预处理器 xff0c less文件后缀是 less 扩充了c
  • [刷题之旅no24]P1185 绘制二叉树

    这道题更像一道数学题 xff0c 说实话 xff0c 数学规律找得越好 xff0c 解题越快 xff0c 其他思路倒是对解题没有什么太大的帮助吧 只要给出确定层数 那么层与层之间的高度差可以被直接计算出来 也就是每一层所在二维字符数组中的纵
  • WSL无法打开或者卡死

    WSL无法打开或者卡死后 xff0c 使用管理员权限打开终端 比如cmd xff0c 然后输入 xff1a netsh winsock reset 最后 xff0c 重启windows即可
  • VirtualBox上安装arch linux

    大部分是根据wiki arch linux官网搬过来的 废话少说 直接上步骤 1 到清华大学镜像网站上下载arch linux 2 选择最新的版本 找到 iso文件下载 3 下载完成后用virtualbox打开 新建一个arch linux
  • 远程连接出现拒绝访问

    排除防火墙的情况下有以上错误提示解决办法如下 xff1a 服务器 开始 运行 输入 services msc xff0c 打开计算机的服务 xff0c 找到 Remote Desktop Services xff0c 登陆 xff0c 选择
  • webpack---优化_第三方库单独打包

    概括 xff1a 需要同时写两个或者多个webpack的配置文件 webpack dll js只需要执行一次 xff0c 以后多次执行webpack config js就行 webpack dll js的作用是 xff1a 1 对某些库进行
  • Photos 有问题。请从其原始安装位置重新安装应用程序,或与管理员联系的解决方法

    Photos 有问题 请从其原始安装位置重新安装应用程序 xff0c 或与管理员联系 解决方法 看到大神的解决方法有被吓到 xff0c 但是因为怕麻烦 xff0c 又怕自己作死 xff0c 找到了另一种解决方法 xff08 每个人情况可能不
  • Qt 下结合SARibbon、Dock 开发Opencascade应用的基础框架

    一 下载编译Qt Ribbon组件SARibbon SARibbon 下载地址 xff1a github https github com czyt1988 SARibbon 下载后Qt Creator加载SARibbon pro xff0
  • python 爬虫,获取携程网站机票数据

    爬取携程机票数据 from prettytable import PrettyTable import requests import json def xiecheng dcity acity date date 61 date 0 4
  • WSL(Windows Subsystem for Linux)安装、迁移D盘、设置默认登录账户、更改root密码和授予普通用户sudo权限

    WSL Windows Subsystem for Linux 安装 迁移D盘 设置默认登录账户 更改root密码和授予普通用户sudo权限 博客目录 WSL Windows Subsystem for Linux 安装 迁移D盘 设置默认
  • UBUNTU下编译OPENCV4.5.2提示找不到CUDA SDK

    在终端键入 xff1a sudo ln s usr local cuda 5 5 usr local cuda
  • Selenium常用API详解,从入门到进阶(上)

    目录 1 打开页面 2 查找页面元素 3 输入文本 4 点击操作 5 提交操作 6 清除文本 7 获取文本 属性 8 获取页面的标题和URL 9 窗口 9 1 设置窗口大小 9 2 窗口切换 9 2 1 为什么需要窗口切换 xff1f 9
  • Tensorflow-gpu保姆级安装教程(Win11, Anaconda3,Python3.9)

    Tensorflow gpu 保姆级安装教程 xff08 Win11 Anaconda3 xff0c Python3 9 xff09 前言Tensorflow gpu版本安装的准备工作 一 查看电脑的显卡 xff1a 二 Anaconda的
  • 程序设计思维与实践 Week15 实验(1/2/智能班)

    A Q 老师的记录册 Problem Statement Q 老师有 N 个学生 xff0c 每个学生都有各自独立的编号 xff0c 且编号范围在 1 N 之间 这一天 xff0c 所有学生都在不同的时间进入教室 Q 老师记录了当编号为 i
  • 环境部署(物理手工部署):

    环境搭建的思路 1 找开发了解下项目使用的一些组件 xff0c 比如说jdk 数据库 缓存 中间件 2 搭建这些依赖组件的环境 xff1a jdk mysql tomcat 3 将项目需要用到的数据库sql导入到数据库里 4 把项目包传到t
  • 使用Ansible部署一次BIND节点

    如何使用Asible提高工作效率 工作场景描述实现方式实现思想playbook内容 结语 工作场景描述 大部分的运维小哥在实际的应用场景中经常会有一些重复的动作是需要耗时费力的去完成 xff0c 比如今天交付一个环境 xff0c 明天一个需
  • Appium: Windows系统桌面应用自动化测试(一)

    一 方案调研 1 windows桌面应用自动化测试方案 xff08 1 xff09 WinAppDriver是微软开发的自动化测试工具 xff0c 而windows是微软开发的 xff0c 兼容性应该极好 xff08 2 xff09 Win
  • Linux网络拷贝

    需求场景 xff1a Linux突然故障 xff0c 导致无法进入图形化界面 但是文件又太大将近20GB xff0c 不管是smb xff0c 还是U盘都无法传输 xff0c 这时候我突然想到了Linux网络拷贝 xff0c 哈哈哈 Lin
  • DFS搜索算法详解

    深度优先搜索 一条道走到黑 DFS其实叫深度优先搜索算法 xff0c 起始它只是一种搜索的方法思路 xff0c 并没有固定的算法格式 让我们通过一个社交图的例子来看 我们拿到一个社交关系无向图 xff1a 通过无向图可以得到邻接矩阵 用1表