C++深度优先和广度优先的实现

article/2025/9/17 3:49:11

C++深度优先和广度优先的实现

  • 前言
  • 源码如下:
  • 测试结果
  • 深度优先(栈实现)和广度优先(队列实现)图解


前言

本篇文章为笔者的读书笔记,未经允许请勿转载。如果对你有帮助记得点个赞(●’◡’●)
本文主要讲的深度优先算法和广度优先算法的区别,其中深度优先有两种实现方式,一种是递归法,另一种是非递归(栈实现),而广度优先就是队列的实现;
后面还会以图形表述栈实现和队列实现;且用到了图形库easyx;


源码如下:

main

#include <iostream>
#include<vector>
#include<windows.h>
#include"Draw.h"
#include"DFS.h"
#include"BFS.h"
#include"Search.h"
using namespace std;
vector<vector<int>> map =
{{0,0,1,0,1,0,1},{1,0,0,0,0,0,1},{1,0,1,1,1,0,0},{1,0,0,0,1,1,1},{0,0,1,0,0,0,1},{1,0,1,0,1,0,0},{1,0,1,1,1,0,1},
};
//检查数据的合法性
bool check(int x, int y)
{//所走的路径不能越界,也不能走到地图为1的地方。if ((y < 0 ||  x<0) || y >= map.size() ||x>=map[y].size() || map[y][x] == 1){return false;}return true;
}
//测试图形库是否能正常运行
void test()
{Draw draw(600, map);draw.updata();
}
//深度优先算法
void test1()
{DFS dfs(check);Draw draw(600, map);Pos start{ 0,0 };Pos end{ 1,6 };draw.level[end.y][end.x] = Draw::end;//设置终点位置draw.updata();const auto& path = dfs.recursive(start,end);//开始寻路,路径找完后用vector保存了for (const auto& e : path){draw.level[e.y][e.x] = Draw::visit;//路径设置为visit。注意x,y不要写反了draw.updata();Sleep(500);}
}
//广度优先算法
void test2()
{BFS bfs(check);Draw draw(600, map);Pos start{ 1,1 };Pos end{ 3,0 };draw.level[end.y][end.x] = Draw::end;draw.updata();const auto& path = bfs.queue(start, end);for (const auto& e : path){draw.level[e.y][e.x] = Draw::visit;draw.updata();Sleep(500);}}
int main()
{//test();//test1();//test2();system("pause");return 0;
}

Draw.h

#pragma once
#include<vector>
#include<easyx.h>
#include<string>
#include<iostream>//区别名
using vec2 = std::vector<std::vector<int>>;
//绘制地图的类
class Draw
{
public:Draw(int&& length, vec2& map) :length(length)
{this->level = map;this->size = length / level.size();initgraph(length, length, EW_SHOWCONSOLE);
}~Draw()
{closegraph();
}enum {road=0,//空地wall,//墙visit,//走过的路end,//终点};//绘制的地图。vec2 level;//游戏更新void updata()
{draw();test();
}
private:int length;				//宽度和高度int size;				//每个瓦片的大小//绘制地图void draw()
{BeginBatchDraw();//开始批量画图cleardevice();//把之前的先清除for (size_t i = 0; i < level.size(); i++){for (size_t j = 0; j < level[i].size(); j++){if (level[i][j] == road){setfillcolor(RGB(0xdd, 0xdd, 0xdd));//设置路的颜色}else if (level[i][j] == wall){setfillcolor(RGB(0x33, 0x33, 0xcc));}else if (level[i][j] == visit){setfillcolor(RGB(0x33, 0xcc, 0x33));}else if (level[i][j] == end){setfillcolor(RGB(0xff, 0x33, 0x33));}rect(j, i);//绘制瓦片,j代表x,i代表y。/*(0,0)----------▷ x的正方向||||▽ y的正方向图形库窗口的坐标*/}		  }		EndBatchDraw();
}				 			//绘制文本void test()
{system("cls");//清屏std::string str="";for (size_t i = 0; i < level.size(); i++){for (size_t j = 0; j < level[i].size(); j++){if (level[i][j] == road){str += "  ";//设置路的标识符}else if (level[i][j] == wall){str += "+ ";//墙}else if (level[i][j] == visit){str += ". ";//走过的路}else if (level[i][j] == end){str += "= ";//终点}}str += '\n';}std::cout << str << std::endl;
}	//绘制瓦片		void rect(int x, int y)
{fillrectangle(x * size, y * size, (x + 1) * size, (y + 1) * size);/* void fillrectangle(int left,int top,int right,int bottom); */}
};

Search.h

#pragma once
#include<functional>
#include<vector>
struct Pos
{int x;int y;Pos(int x=0, int y=0) :x(x), y(y) {}
};
class Search
{	
protected:using Function = std::function<bool(int, int)>;
public:Search(Function fn) :fn(fn) {}
protected://通过函数适配器调用外部规则,对数据进行判断;Function fn;//创建一个vector保存路径std::vector<Pos> path;//判断这条路是否走过bool isVisited(Pos pos){for (const auto& e : path){if (pos.x == e.x && pos.y == e.y){return true;}}return false;}//判断下次移动是否合法bool isValid(Pos pos){return fn(pos.x, pos.y) && !isVisited(pos);//fn调用外部规则check}
};

DFS.h

#pragma once
#include "Search.h"
//深度优先算法
class DFS : public Search
{
public:DFS(std::function<bool(int, int)> fn):Search(fn)//构造子类的时候,需要初始化父类。
{}/*start 起点坐标end   终点坐标*///递归法std::vector<Pos> recursive(Pos start, Pos end)
{this->end = end;path.push_back(start);_recursive(start);return path;
}//非递归法(栈实现)std::vector<Pos> stack(Pos start, Pos end)
{static Pos dir[4] = {{0,1},//y+1向下{1,0},//x+1向右{-1,0},//x-1向左{0,-1},//y-1向上};std::stack<Pos> st;st.push(start);while (!st.empty()){auto now = st.top();st.pop();for (size_t i = 0; i < 4; i++){//准备移动的路径Pos move(now.x + dir[i].x, now.y + dir[i].y);//判断是否能移动if (isValid(move)){st.push(move);path.push_back(move);//判断是否到达终点if (move.x == end.x && move.y == end.y){return path;}}}}return path;
}
private:bool is_end=false;//递归需要的标志位,默认位falsePos end;		  //保存终点坐标	void _recursive(Pos now)
{static Pos dir[4] = {{0,1},//y+1向下{1,0},//x+1向右{-1,0},//x-1向左{0,-1},//y-1向上};//判断是否到达终点if (now.x == end.x && now.y == end.y){is_end = true;//找到终点标志位置1return;}//循环遍历下右左上4个方向for (int i = 0; i < 4; i++){//准备移动的路径Pos move(now.x + dir[i].x, now.y + dir[i].y);//判断能否移动if (!is_end && isValid(move)){path.push_back(move);//保存走过的路径_recursive(move);}}
}
};

BFS.h

#pragma once
#include "Search.h"
class BFS :public Search
{
public:BFS(Function fn):Search(fn)
{
}std::vector<Pos> queue(Pos start, Pos end)
{static Pos dir[4] = {{0,1},//y+1向下{1,0},//x+1向右{-1,0},//x-1向左{0,-1},//y-1向上};std::queue<Pos> qu;qu.push(start);while (!qu.empty()){auto now = qu.front();qu.pop();for (size_t i = 0; i < 4; i++){Pos move(now.x + dir[i].x, now.y + dir[i].y);if (isValid(move)){qu.push(move);path.push_back(move);if (move.x == end.x && move.y == end.y){return path;}}}}return path;
}
};

测试结果

递归实现:
在这里插入图片描述

深度优先(栈实现):
在这里插入图片描述

广度优先(队列实现)
在这里插入图片描述

深度优先(栈实现)和广度优先(队列实现)图解

深度优先:
在这里插入图片描述
广度优先:
在这里插入图片描述


http://chatgpt.dhexx.cn/article/9QIIk7Ar.shtml

相关文章

迷宫问题(maze problem)—— 深度优先与广度优先搜索求解

文章目录 1.问题简介2.求解方法3.深度优先搜索加回溯法3.1 求解第一条可行路径3.2 求解最短路径 4.广度优先搜索小结参考文献 1.问题简介 给定一个迷宫&#xff0c;指明起点和终点&#xff0c;找出从起点出发到终点的有效可行路径&#xff0c;就是迷宫问题&#xff08;maze pr…

图深度优先、广度优先遍历(java)

一、图的遍历 图的遍历&#xff0c;即是对结点的访问。一个图有那么多个结点&#xff0c;如何遍历这些结点,需要特定策略&#xff0c;一般有两种访问策略:(1)深度优先遍历(2)广度优先遍历深度优先遍历基本思想。 二、深度优先遍历 图的深度优先搜索(Depth First Search)。 深…

总结深度优先与广度优先的区别

3 总结深度优先与广度优先的区别 1、区别 1&#xff09; 二叉树的深度优先遍历的非递归的通用做法是采用栈&#xff0c;广度优先遍历的非递归的通用做法是采用队列。 2&#xff09; 深度优先遍历&#xff1a;对每一个可能的分支路径深入到不能再深入为止&#xff0c;而且每个结…

连通图里的深度优先和广度优先遍历

从图中的某个顶点出发&#xff0c;按照某种搜索方法沿着图的边访问图中的所有顶点&#xff0c;使得每个顶点仅被访问一次&#xff0c;这个过程称为图的遍历。图的遍历有两种&#xff1a;深度优先遍历和广度优先遍历。   图分为连通图和非连通图&#xff0c;这里主要讨论连通图…

广度优先算法

广度优先算法 本文主要以介绍算法思想为主这里并没有进行源码实现&#xff0c;但是给出推荐使用的数据结构和主要思想。 首先介绍一下广度优先算法&#xff0c;假设要查找AB两点之间的最短距离&#xff0c;以A为起点B为终点。可以先遍历A的相邻节点&#xff0c;这些节点称之为…

C语言基于邻接表的图的深度优先、广度优先遍历

目录 1 深度优先&#xff08;Depth_First Search&#xff09; 2 广度优先&#xff08;Broadth_First Search&#xff09; 3 基于邻接表的深度优先、广度优先遍历 4 源代码示例 4.1 深度优先 4.2广度优先 假设有无向图G &#xff08;V&#xff0c;E&#xff09;&#xff…

数据结构之深度优先和广度优先遍历

文章目录 图为什么要有图图的常用概念邻接矩阵邻接表图的深度优先遍历深度优先遍历基本思想深度优先遍历算法步骤深度优先算法的代码实现 图的广度优先遍历广度优先遍历基本思想广度优先遍历算法步骤广度优先算法的代码实现图结构完整代码 图 为什么要有图 1)前面我们学了线性…

图的深度优先和广度优先遍历算法

编写一个程序&#xff0c;输出下面带权有向图的邻接表&#xff0c;并根据该邻接表&#xff0c;实现图的遍历运算&#xff0c;具体要求如下&#xff1a; (1)从顶点0开始的深度优先遍历序列(递归算法) (2)从顶点0开始的深度优先遍历序列(非递归算法) (3)从顶点0开始的广度优先遍历…

算法之深度优先、广度优先算法

目录 前言&#xff1a; 搜索算法&#xff1a; 广度优先搜索算法 深度优先搜索算法 问题&#xff1a;如何找出社交网络中某个用户的三度好友关系&#xff1f; 总结&#xff1a; 参考资料&#xff1a; 前言&#xff1a; 图这种数据结构经常用于表示一个社交网络&#x…

广度优先搜索与深度优先搜索

广度优先搜索&#xff08;宽度优先搜索&#xff0c;BFS&#xff09;和深度优先搜索&#xff08;DFS&#xff09;算法的应用非常广泛&#xff0c;本篇文章主要介绍BFS与DFS的原理、实现和应用。 深度优先搜索 图的深度优先搜索(Depth First Search)&#xff0c;和树的先序遍历…

深度优先遍历与广度优先遍历

1、深度优先遍历(Depth First Search, 简称 DFS) 1.1、主要思路 从图中一个未访问的顶点 V 开始&#xff0c;沿着一条路一直走到底&#xff0c;然后从这条路尽头的节点回退到上一个节点&#xff0c;再从另一条路开始走到底…&#xff0c;不断递归重复此过程&#xff0c;直到所…

深度优先与广度优先

深度优先遍历简称DFS&#xff08;Depth First Search&#xff09;&#xff0c;广度优先遍历简称BFS&#xff08;Breadth First Search&#xff09;&#xff0c;它们是遍历图当中所有顶点的两种方式。 深度优先遍历&#xff1a; 选取一个节点开始&#xff0c;沿着一条路一直走…

深度优先遍历(DFS)和广度优先遍历(BFS)

深度优先遍历&#xff08;DFS&#xff09;和广度优先遍历&#xff08;BFS&#xff09; 图的遍历&#xff1a;所谓遍历&#xff0c;即是对结点的访问。一个图有多个结点&#xff0c;如何遍历这些结点&#xff0c;有两种访问策略&#xff1a; 深度优先遍历(Depth First Search, …

深度优先与广度优先的区别!

从深度优先和广度优先两个角度解决同一个问题 题目 从一号顶点开始遍历这个图&#xff0c;使用深度优先搜索和广度优先搜索的2种遍历结果 深度优先遍历的主要思想就是&#xff0c;首先以一个未被访问过的顶点作为起始顶点&#xff0c;沿着当前顶点的边走到未访问过的顶点&…

数据结构:图的遍历--深度优先、广度优先

图的遍历&#xff1a;深度优先、广度优先 遍历 图的遍历是指从图中的某一顶点出发&#xff0c;按照一定的策略访问图中的每一个顶点。当然&#xff0c;每个顶点有且只能被访问一次。 在图的遍历中&#xff0c;深度优先和广度优先是最常使用的两种遍历方式。这两种遍历方式对无…

深度优先搜索与广度优先搜索

算法是作用于具体数据结构之上的&#xff0c;深度优先搜索算法和广度优先搜索算法都是基于“图”这种数据结构的。这是因为&#xff0c;图这种数据结构的表达能力很强&#xff0c;大部分涉及搜索的场景都可以抽象成“图”。 图上的搜索算法&#xff0c;最直接的理解就是&#…

广度优先搜索和深度优先搜索

文章目录 1. 前言2. 广度优先搜索和深度优先搜索1&#xff09;深度优先搜索2&#xff09;广度优先搜索 3. 深度优先搜索算法框架1&#xff09;二叉树深度优先搜索模板2&#xff09;图深度优先搜索模板3&#xff09;二维矩阵深度优先搜索模板 4. 广度优先搜索算法框架1&#xff…

深度优先和广度优先算法

1、深度优先算法 遍历规则&#xff1a;不断地沿着顶点的深度方向遍历。顶点的深度方向是指它的邻接点方向。 最后得出的结果为&#xff1a;ABDECFHG。 Python代码实现的伪代码如下&#xff1a; 2、广度优先算法&#xff1a; 遍历规则&#xff1a; 1&#xff09;先访问完当…

深度优先搜索(DFS)和广度优先搜索(BFS)

代码随想录 深度优先搜索和广度优先搜索&#xff0c;都是图形搜索算法&#xff0c;它两相似&#xff0c;又却不同&#xff0c;在应用上也被用到不同的地方。这里拿一起讨论&#xff0c;方便比较。 先给大家说一下两者大概的区别&#xff1a; 如果搜索是以接近起始状态的程序依次…

算法:深度优先和广度优先(DFS,BFS)

一丶深度优先&#xff08;DFS&#xff09; 深度优先顾名思义: 就是往深的地方优先查找或遍历。 如图二叉树&#xff0c;想遍历树中所有结点可以用中序遍历&#xff0c;前序或后序。如果某一结点还有子结点就会往深处就是往下一结点&#xff0c;一直遍历直到最后一个结点没有子…