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搜索算法详解 的相关文章

  • Acwing 1414.牛异或

    输入样例 5 1 0 5 4 2 输出样例 6 4 5 刚开始看到这个题 我是毫无思绪 看了一下题解 https www acwing com video 2339 老师说这个是最大异或对的变形 于是我去找了一下最大异或对 看完之后我只能想
  • D - 整数变换问题

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

    思路 1 DFS算法可以求解图中从一点到另一点的全部路径 2 通过枚举所有顶点的邻接点 然后通过DFS寻找枚举点到的所有路径来寻找环路 3 思路很简单 但是算法复杂度确实是太高了 下面上代码 include
  • 剑指Offer - 面试题12:矩阵中的路径

    题目 请设计一个函数 用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径 路径可以从矩阵中的任意一格开始 每一步可以在矩阵总向左 右 上 下移动一格 如果一条路径经过了矩阵的某一格 那么该路径不能再次进入该格子 如 在下面的3 4的
  • 2023最新一文学会fastdfs单节点部署(含安装包镜像包)

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

    UVA1613 K GraphOddity 题目传送门 刚看第一眼一点思路都没有 后面看了大佬的题解发现这道题其实是一道水题 用到的方法就是DFS遍历图 我是废物 题目意思很简单 就不分析了 下面直接说方法 首先求出k 然后dfs遍历一遍图
  • Kamil and Making a Stream【Codeforces Round #588 (Div. 2) E】【dfs + map】

    Codeforces 1230 E 也没怎么读题 就看了下样例的note就知道了是对树上的直系祖先对子结点的链上gcd求和 然后就可以直接这样去跑一遍 个人比较的喜欢踩坑 有正着走的不走 偏偏选择了从根节点返回回来的答案 这样的做法虽然上是
  • 欧拉回路路径求解

    基本概念 今天讨论的主题是一类问题 就是欧拉路问题 有两种欧拉路 第一种叫做 Eulerian path trail 沿着这条路径走能够走遍图中每一条边 第二种叫做 Eularian cycle 沿着这条路径走 不仅能走遍图中每一条边 而且
  • 洛谷题单 算法1-7 搜索

    USACO08FEB Meteor Shower S 题目描述 Bessie hears that an extraordinary meteor shower is coming reports say that these meteor
  • 基础算法题——德邦国王(dfs、剪枝)

    德邦国王 题目还算中规中矩 就是剪枝比较麻烦 解题思路 dfs 剪枝 移动次数不超过设定值 M 若有解 则后面的步骤不可大于该解的值 不断查询完美矩阵与当前矩阵不同的个数 t t 1 为最快可将当前矩阵移动成完美矩阵的步数 若 t 1 已经
  • 剪格子 蓝桥杯 211

    题目描述 如下图所示 3 x 3 的格子中填写了一些整数 我们沿着图中的红色线剪开 得到两个部分 每个部分的数字和都是 60 本题的要求就是请你编程判定 对给定的 m n 的格子中的整数 是否可以分割为两个部分 使得这两个区域的数字和相等
  • 关于multipartFile.transferTo方法报错java.nio.file.FileAlreadyExistsException

    之前老项目用的spring4版本 现在升级成spring5版本 重新把文件中心搬过来 发现原先有一段 MultipartFile multiFile XXX File file File createTempFile System curr
  • LeetCode-116.填充每个节点的下一个右侧节点指针、深度优先搜索

    题目分析 广度优先搜索 题目要求把二叉树中每一层的的节点连起来 最简单的方法即 BFS 按层的顺序的对树进行遍历 但需要使用 queue 数据结构 空间复杂度为 O N 不符合题目要求 深度优先搜索 由于 next 指针的存在 可以实现对二
  • 蓝桥杯2019年c++b组国赛题目及题解

    填空题目来源来自于 https blog csdn net l503301397 article details 90697079 大题来源于 ACwing https www acwing com problem search 2 csr
  • [Codeforces 1286B] Numbers on Tree

    Evlampiy was gifted a rooted tree The vertices of the tree are numbered from 1 to n Each of its vertices also has an int
  • CentOS 7.9 64位 SCC版安装FastDfs和配置Nginx

    最近练习的项目中需要用到FastDfs 和Nginx 这里记录一下安装和配置过程 个人使用部署过程遇到了很多的坑 准备把过程记下来不然忘了 首先 购买 试用阿里云 CentOS 7 9 64位Scc版系统 进入远程桌面 由于项目较老 所以我
  • 递归、加法原理,如何分解问题(独立且完备的划分)

    加法原理适用于做一件事有n种独立不相交且完备的方向 每个方向上有ai种方案 则总的方案数就是 a1 a2 an 例题 把n个数分为k个非空子集 有多少种分法 分解问题 第一个集合里放多少个数把原问题的解分成了独立且完备的若干方向 分别解每个
  • 链式前向星存树图和遍历它的两种方法【dfs、bfs】

    目录 一 链式前向星存图 二 两种遍历方法 一 链式前向星存图 n个点 n 1条边 链式前向星把上面的树图存下来 输入 9 代表要存进去n个点 1 2 下面是n 1条边 每条边连接两个点 1 3 1 7 2 4 4 5 4 6 3 8 3
  • 仙岛求药 —— dfs 与 bfs求解

    样例输入1 8 8 样例输出1 10 样例输入2 9 6 样例输出2 1 dfs ps 使用dfs会运行超时 30组测试数据只能通过部分 其实这种最短路径 最少操作的问题最好还是靠bfs解决 import java util Scanner
  • DFS的个人理解和测试例题

    深度优先搜索 DFS 是一种搜索手段 可以理解为 它从某个位置 起点 开始 沿着一条路不断地向前走直到尽头 然后退后一步 去走其它没走过的路 没有的话 再退后一步 再去选择 直到找到目的地 终点 例如下图 从A 起点 开始走 先走ABD 在

随机推荐

  • 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表