日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

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

發(fā)布時(shí)間:2023/12/31 c/c++ 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++深度优先和广度优先的实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

C++深度優(yōu)先和廣度優(yōu)先的實(shí)現(xiàn)

  • 前言
  • 源碼如下:
  • 測(cè)試結(jié)果
  • 深度優(yōu)先(棧實(shí)現(xiàn))和廣度優(yōu)先(隊(duì)列實(shí)現(xiàn))圖解


前言

本篇文章為筆者的讀書筆記,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載。如果對(duì)你有幫助記得點(diǎn)個(gè)贊(●’?’●)
本文主要講的深度優(yōu)先算法和廣度優(yōu)先算法的區(qū)別,其中深度優(yōu)先有兩種實(shí)現(xiàn)方式,一種是遞歸法,另一種是非遞歸(棧實(shí)現(xiàn)),而廣度優(yōu)先就是隊(duì)列的實(shí)現(xiàn);
后面還會(huì)以圖形表述棧實(shí)現(xiàn)和隊(duì)列實(shí)現(xiàn);且用到了圖形庫(kù)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}, }; //檢查數(shù)據(jù)的合法性 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; } //測(cè)試圖形庫(kù)是否能正常運(yùn)行 void test() {Draw draw(600, map);draw.updata(); } //深度優(yōu)先算法 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;//設(shè)置終點(diǎn)位置draw.updata();const auto& path = dfs.recursive(start,end);//開始尋路,路徑找完后用vector保存了for (const auto& e : path){draw.level[e.y][e.x] = Draw::visit;//路徑設(shè)置為visit。注意x,y不要寫反了draw.updata();Sleep(500);} } //廣度優(yōu)先算法 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>//區(qū)別名 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,//終點(diǎn)};//繪制的地圖。vec2 level;//游戲更新void updata() {draw();test(); } private:int length; //寬度和高度int size; //每個(gè)瓦片的大小//繪制地圖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));//設(shè)置路的顏色}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的正方向圖形庫(kù)窗口的坐標(biāo)*/} } 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 += " ";//設(shè)置路的標(biāo)識(shí)符}else if (level[i][j] == wall){str += "+ ";//墻}else if (level[i][j] == visit){str += ". ";//走過的路}else if (level[i][j] == end){str += "= ";//終點(diǎn)}}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://通過函數(shù)適配器調(diào)用外部規(guī)則,對(duì)數(shù)據(jù)進(jìn)行判斷;Function fn;//創(chuàng)建一個(gè)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;}//判斷下次移動(dòng)是否合法bool isValid(Pos pos){return fn(pos.x, pos.y) && !isVisited(pos);//fn調(diào)用外部規(guī)則check} };

DFS.h

#pragma once #include "Search.h" //深度優(yōu)先算法 class DFS : public Search { public:DFS(std::function<bool(int, int)> fn):Search(fn)//構(gòu)造子類的時(shí)候,需要初始化父類。 {}/*start 起點(diǎn)坐標(biāo)end 終點(diǎn)坐標(biāo)*///遞歸法std::vector<Pos> recursive(Pos start, Pos end) {this->end = end;path.push_back(start);_recursive(start);return path; }//非遞歸法(棧實(shí)現(xiàn))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++){//準(zhǔn)備移動(dòng)的路徑Pos move(now.x + dir[i].x, now.y + dir[i].y);//判斷是否能移動(dòng)if (isValid(move)){st.push(move);path.push_back(move);//判斷是否到達(dá)終點(diǎn)if (move.x == end.x && move.y == end.y){return path;}}}}return path; } private:bool is_end=false;//遞歸需要的標(biāo)志位,默認(rèn)位falsePos end; //保存終點(diǎn)坐標(biāo) void _recursive(Pos now) {static Pos dir[4] = {{0,1},//y+1向下{1,0},//x+1向右{-1,0},//x-1向左{0,-1},//y-1向上};//判斷是否到達(dá)終點(diǎn)if (now.x == end.x && now.y == end.y){is_end = true;//找到終點(diǎn)標(biāo)志位置1return;}//循環(huán)遍歷下右左上4個(gè)方向for (int i = 0; i < 4; i++){//準(zhǔn)備移動(dòng)的路徑Pos move(now.x + dir[i].x, now.y + dir[i].y);//判斷能否移動(dòng)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è)試結(jié)果

遞歸實(shí)現(xiàn):

深度優(yōu)先(棧實(shí)現(xiàn)):

廣度優(yōu)先(隊(duì)列實(shí)現(xiàn))

深度優(yōu)先(棧實(shí)現(xiàn))和廣度優(yōu)先(隊(duì)列實(shí)現(xiàn))圖解

深度優(yōu)先:

廣度優(yōu)先:

總結(jié)

以上是生活随笔為你收集整理的C++深度优先和广度优先的实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。