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;
}
};

测试结果

递归实现:

深度优先(栈实现):

广度优先(队列实现)

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

深度优先:

广度优先:

C++深度优先和广度优先的实现相关推荐

  1. 第三百三十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—深度优先与广度优先原理...

    第三百三十八节,Python分布式爬虫打造搜索引擎Scrapy精讲-深度优先与广度优先原理 网站树形结构 深度优先 是从左到右深度进行爬取的,以深度为准则从左到右的执行(递归方式实现)Scrapy默认 ...

  2. python爬虫算法深度优先_爬虫课程(四)|深度优先和广度优先算法

    深度优先和广度优先算法在爬取一个整站上经常用到,本课程主要讲解这两个算法的原理以及使用过程. 一.网站的树结构 1.1.一个网站的url结构图 以知乎为例,知乎目前有发现.话题.Live.书店.圆桌. ...

  3. 继承:深度优先和广度优先

    面向对象 封装: 其实就是使用构造方法将内容封装到对象中,然后通过对象直接或者self间接获取被继承的内容 继承: 对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不 ...

  4. 〖Python〗-- 性能相关及深度优先与广度优先

    [性能相关及深度优先与广度优先] 性能相关 在编写爬虫时,性能的消耗主要在IO请求中,当单进程单线程模式下请求URL时必然会引起等待,从而使得请求整体变慢. import requestsdef fe ...

  5. 图的理解:深度优先和广度优先遍历及其 Java 实现

    遍历 图的遍历,所谓遍历,即是对结点的访问.一个图有那么多个结点,如何遍历这些结点,需要特定策略,一般有两种访问策略: 深度优先遍历 广度优先遍历 深度优先 深度优先遍历,从初始访问结点出发,我们知道 ...

  6. 图的深度优先和广度优先算法(DFS递归与非递归)

    无向图--邻接矩阵的深度优先和广度优先算法实现 测试环境:VS2008(C) [cpp:showcolumns] view plaincopyprint? ·········10········20· ...

  7. 白话Elasticsearch53-深入聚合数据分析之Collect Model_bucket优化机制:深度优先、广度优先

    文章目录 概述 官网 示例 概述 继续跟中华石杉老师学习ES,第53篇 课程地址: https://www.roncoo.com/view/55 官网 Collect Model:戳这里 示例 当bu ...

  8. 6.1 图的深度优先和广度优先搜索

    图的广度优先搜索 图的的搜索算法主要分为广度优先搜索(breadth-first search或BFS)和深度优先搜索(depth-first search或DFS).首先讨论广度优先搜索算法. 称之 ...

  9. 深度搜索和广度搜索领接表实现_数据结构与算法--图的搜索(深度优先和广度优先)...

    数据结构与算法--图的搜索(深度优先和广度优先) 有时候我们需要系统地检查每一个顶点或者每一条边来获取图的各种性质,为此需要从图的某个顶点出发,访遍图中其余顶点,且使得每一个顶点只被访问一次,这个过程 ...

  10. python深度优先_python数据结构之图深度优先和广度优先实例详解

    本文实例讲述了python数据结构之图深度优先和广度优先用法.分享给大家供大家参考.具体如下: 首先有一个概念:回溯 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到 ...

最新文章

  1. savexml php,PHP DOMDocument saveXML()用法及代码示例
  2. EXC_BAD_ACCESS调试
  3. Windows XP 专业版与家庭版的区别
  4. tensorflow2.0 GPU 版本安装测试教程及新特性初探
  5. 分布式与人工智能课程(part4)--第四课
  6. 编写jmeter测试用例_JMeter 编写接口测试用例遇到的问题及解决
  7. rest api如何创建_REST:创建资源
  8. 【Spring中使用MongoTemplate查询数据】
  9. UVA10579 Fibonacci Numbers【大数】
  10. java 重复流_Java Logger控制台流重复输出 - java
  11. oracle数据库:约束
  12. beetl模板使用场景_BeetlSQL3性能
  13. Echarts3柱状图切换折线图时发生位移
  14. Ubuntu20.04代理设置
  15. 什么叫泛域名ssl证书
  16. 浅析C/S、B/S与P2P架构
  17. 内存的基础知识(常用数量单位、进程运行原理、存储单元、内存地址、绝对装入、静态重定位、动态重定位、静态链接、动态链接等)
  18. 计算机组成原理测试题——第5章 输入输出系统(上)(2)
  19. 今日错题(10.6)
  20. uni-app实现联系人右侧索引字母表点击滚动到相应的位置(uni.pageScrollTo(OBJECT))

热门文章

  1. QueryList采集
  2. 【项目实战-MATLAB】:基于BP神经网络的三相逆变器故障诊断研究
  3. Chrome Apps將是Google送給微軟的特洛伊木馬?
  4. 如何进入UI设计行业 什么学习路线适合新手
  5. 2022-2028全球与中国长租公寓市场现状及未来发展趋势
  6. unittest用例前后置(testFixture测试夹具)
  7. html5 video audio currentTime 设定失效、重头开始播放
  8. 2008服务器做微信退款,Net微信退款开发流程
  9. 【GraphMaker】Unity3D图表插件——柱状图、折线图、饼图、环图、雷达图表、层次树
  10. java 分卷压缩_Apache Commons Compress介绍-Zip压缩解压