c++算法學習4——廣度搜索bfs

一、引言:探索迷宮的智能方法

在解決迷宮最短路徑問題時,廣度優先搜索(BFS)是一種高效而優雅的算法。與深度優先搜索(DFS)不同,BFS采用"由近及遠"的搜索策略,逐層探索所有可能的路徑,從而保證首次到達終點時的路徑就是最短路徑。(對深搜沒有了解的同學,可以先看下我寫的關于深搜的學習文章)

二、問題描述:迷宮尋路

給定一個R行C列的迷宮,迷宮由'.'(空地)和'#'(障礙物)組成。我們需要計算從左上角(入口)到右下角(出口)的最短步數(包括起點和終點)。移動規則:每次只能向上、下、左、右四個方向移動到相鄰的空地格子。

輸入示例

5 5
..###
#....
#.#.#
#.#.#
#.#..

輸出示例

9

三、BFS算法核心思想

BFS采用隊列(Queue)?這一數據結構實現"先進先出"的訪問策略:

  1. 從起點開始,將其加入隊列

  2. 取出隊首元素,探索其所有相鄰位置

  3. 將未訪問的有效位置加入隊列

  4. 重復直到找到終點或隊列為空

這種策略確保算法優先訪問距離起點更近的位置,因此首次到達終點時的路徑必然是最短路徑。

四、完整代碼實現

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;int R, C; // 迷宮的行數和列數
char maze[40][40]; // 存儲迷宮
bool visited[40][40]; // 標記訪問狀態// 方向數組:右(0,1), 下(1,0), 上(0,-1), 左(-1,0)
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};// 位置結構體:存儲坐標和步數
struct Position {int x, y; // 當前坐標int steps; // 從起點到當前位置的步數
};int bfs() {queue<Position> q;// 起點入隊:位置(0,0),步數為1(包括起點)q.push({0, 0, 1});visited[0][0] = true; // 標記起點已訪問while (!q.empty()) {Position current = q.front();q.pop();// 到達終點:右下角(R-1, C-1)if (current.x == R - 1 && current.y == C - 1) {return current.steps;}// 探索四個方向for (int i = 0; i < 4; i++) {int nx = current.x + dx[i]; // 新位置的行坐標int ny = current.y + dy[i]; // 新位置的列坐標// 檢查新位置是否有效if (nx < 0 || nx >= R || ny < 0 || ny >= C) continue; // 超出邊界if (maze[nx][ny] == '#') continue; // 遇到障礙物if (visited[nx][ny]) continue; // 已訪問過// 有效位置:標記并加入隊列visited[nx][ny] = true;q.push({nx, ny, current.steps + 1});}}// 如果沒有找到路徑(題目保證有解,此返回值不會執行)return -1;
}int main() {// 讀入迷宮大小cin >> R >> C;// 讀入迷宮數據for (int i = 0; i < R; i++) {for (int j = 0; j < C; j++) {cin >> maze[i][j];}}// 初始化訪問標記數組memset(visited, false, sizeof(visited));// 執行BFS并輸出結果cout << bfs() << endl;return 0;
}

五、關鍵代碼解析

1. 方向數組:簡潔的方向控制

int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};

這兩個數組定義了四個基本移動方向:

  • 右:(x+0, y+1)

  • 下:(x+1, y+0)

  • 左:(x+0, y-1)

  • 上:(x-1, y+0)

使用方向數組避免了重復的方向判斷代碼,使程序更簡潔。

2. 位置結構體:信息封裝

struct Position {int x, y; // 當前位置坐標int steps; // 從起點到當前位置的步數
};

結構體封裝了位置信息和步數,便于在隊列中存儲和傳遞狀態。

3. BFS核心邏輯:逐層探索

while (!q.empty()) {Position current = q.front();q.pop();// 檢查是否到達終點// 探索四個方向for (int i = 0; i < 4; i++) {// 計算新位置// 檢查新位置有效性(邊界、障礙、訪問狀態)// 有效位置入隊}
}

這是BFS的核心循環,每次從隊列中取出最早加入的位置(距離起點最近),探索其所有相鄰位置。

4. 訪問標記:避免重復訪問

visited[nx][ny] = true;

每個位置在首次訪問時被標記,確保每個位置只被訪問一次,避免無限循環和不必要的重復計算。

六、BFS與DFS的對比

特性BFSDFS
數據結構隊列(Queue)棧(Stack)
搜索策略廣度優先,逐層擴展深度優先,沿路徑到底
空間復雜度O(最寬層的節點數)O(最大深度)
最短路徑首次到達即是最短路徑需要遍歷所有路徑找最短
適用場景無權圖最短路徑問題所有路徑遍歷,連通性檢查

在迷宮最短路徑問題中,BFS具有明顯優勢,因為它無需遍歷所有路徑就能找到最短路徑。

七、總結

廣度優先搜索是解決迷宮最短路徑問題的經典算法,其核心在于:

  • 使用隊列管理待訪問位置

  • 逐層探索保證首次到達終點即是最短路徑

  • 通過訪問標記避免重復計算

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/83792.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/83792.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/83792.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

4.RV1126-OPENCV 圖像輪廓識別

一.圖像識別API 1.圖像識別作用 它常用于視覺任務、目標檢測、圖像分割等等。在 OPENCV 中通常使用 Canny 函數、findContours 函數、drawContours 函數結合在一起去做輪廓的形檢測。 2.常用的API findContours 函數&#xff1a;用于尋找圖片的輪廓&#xff0c;并把所有的數…

Qt多線程訪問同一個數據庫源碼分享(基于Sqlite實現)

Qt多線程訪問同一個數據庫源碼分享&#xff08;基于Sqlite實現&#xff09; 一、實現難點線程安全問題死鎖風險連接管理問題數據一致性性能瓶頸跨線程信號槽最佳實踐建議 二、源碼分享三、測試1、新建一個多線程類2、開啟多線程插入數據 一、實現難點 多線程環境下多個線程同時…

雙空間知識蒸餾用于大語言模型

Dual-Space Knowledge Distillation for Large Language Models 發表&#xff1a;EMNLP 2024 機構&#xff1a;Beijing Key Lab of Traffic Data Analysis and Mining 連接&#xff1a;https://aclanthology.org/2024.emnlp-main.1010.pdf 代碼&#xff1a;GitHub - songmz…

貪心算法應用:多重背包啟發式問題詳解

貪心算法應用&#xff1a;多重背包啟發式問題詳解 多重背包問題是經典的組合優化問題&#xff0c;也是貪心算法的重要應用場景。本文將全面深入地探討Java中如何利用貪心算法解決多重背包問題。 多重背包問題定義 **多重背包問題(Multiple Knapsack Problem)**是背包問題的變…

ES6 Promise 狀態機

狀態機&#xff1a;抽象的計算模型&#xff0c;根據特定的條件或者信號切換不同的狀態 一、Promise 是什么&#xff1f; 簡單來說&#xff0c;Promise 就是一個“承諾對象”。在ES6 里&#xff0c;有些代碼執行起來需要點時間&#xff0c;比如加載文件、等待網絡請求或者設置…

【Docker管理工具】部署Docker可視化管理面板Dpanel

【Docker管理工具】部署Docker可視化管理面板Dpanel 一、Dpanel介紹1.1 DPanel 簡介1.2 主要特點 二、本次實踐規劃2.1 本地環境規劃2.2 本次實踐介紹 三、本地環境檢查3.1 檢查Docker服務狀態3.2 檢查Docker版本3.3 檢查docker compose 版本 四、下載Dpanel鏡像五、部署Dpanel…

最新研究揭示云端大語言模型防護機制的成效與缺陷

一項全面新研究揭露了主流云端大語言模型&#xff08;LLM&#xff09;平臺安全機制存在重大漏洞與不一致性&#xff0c;對當前人工智能安全基礎設施現狀敲響警鐘。該研究評估了三大領先生成式AI平臺的內容過濾和提示注入防御效果&#xff0c;揭示了安全措施在阻止有害內容生成與…

docker中,容器時間和宿機主機時間不一致問題

win11下的docker中有個mysql。今天發現插入數據的時間不正確。后來發現原來是docker容器中的時間不正確。于是嘗試了各種修改&#xff0c;什么run -e TZ"${tzutil /g}"&#xff0c;TZ"Asia/Shanghai"&#xff0c;還有初始化時帶--mysqld一類的&#xff0c;…

uniapp實現的簡約美觀的星級評分組件

采用 uniapp 實現的一款簡約美觀的星級評分模板&#xff0c;提供絲滑動畫效果&#xff0c;用戶可根據自身需求進行自定義修改、擴展&#xff0c;純CSS、HTML實現&#xff0c;支持web、H5、微信小程序&#xff08;其他小程序請自行測試&#xff09; 可到插件市場下載嘗試&#x…

go語言的鎖

本篇文章主要講鎖&#xff0c;主要會涉及go的sync.Mutex和sync.RWMutex。 一.鎖的概念和發展 1.1 鎖的概念 所謂的加鎖和解鎖其實就是指一個數據是否被占用了&#xff0c;通過Mutex內的一個狀態來表示。 例如&#xff0c;取 0 表示未加鎖&#xff0c;1 表示已加鎖&#xff…

Ubuntu 服務器軟件更新,以及常用軟件安裝 —— 一步一步配置 Ubuntu Server 的 NodeJS 服務器詳細實錄 3

前言 前面&#xff0c;我們已經 安裝好了 Ubuntu 服務器系統&#xff0c;并且 配置好了 ssh 免密登錄服務器 &#xff0c;現在&#xff0c;我們要來進一步的設置服務器。 那么&#xff0c;本文&#xff0c;就是進行服務器的系統更新&#xff0c;以及常用軟件的安裝 調整 Ubu…

如何從零開始建設一個網站?

當你沒有建站的基礎和建站的知識&#xff0c;那么應該如何開展網站建設和網站管理。而今天的教程是不管你是為自己建站還是為他人建站都適合的。本教程會指導你如何進入建站&#xff0c;將建站的步驟給大家分解&#xff1a; 首先我們了解一下&#xff0c;建站需要那些步驟和流程…

網絡可靠性的定義與核心要素

網絡可靠性&#xff08;Network Reliability&#xff09;是指網絡系統在特定時間范圍內持續提供穩定、無中斷、符合預期性能的服務能力。其核心目標是確保數據能夠準確、完整、及時地傳輸&#xff0c;即使在部分故障或異常情況下仍能維持基本功能。 1. 網絡可靠性的核心指標 衡…

GpuGeek如何成為AI基礎設施市場的中堅力量

AI時代&#xff0c;算力基礎設施已成為支撐技術創新和產業升級的關鍵要素。作為國內專注服務算法工程師群體的智算平臺&#xff0c;GpuGeek通過持續創新的服務模式、精準的市場定位和系統化的生態建設&#xff0c;正快速成長為AI基礎設施領域的中堅力量。本文將深入分析GpuGeek…

【Qt】Bug:findChildren找不到控件

使用正確的父對象調用 findChildren&#xff1a;不要在布局對象上調用 findChildren&#xff0c;而應該在布局所在的窗口或控件上調用。

【Linux網絡編程】傳輸層協議TCP,UDP

目錄 一&#xff0c;UDP協議 1&#xff0c;UDP協議的格式 2&#xff0c;UDP的特點 3&#xff0c;面向數據報 4&#xff0c;UDP的緩沖區 5&#xff0c;UDP使用注意事項 6&#xff0c;基于UDP的應用層協議 二&#xff0c;對于報文的理解 三&#xff0c;TCP協議 1&…

Neo4j 數據可視化與洞察獲取:原理、技術與實踐指南

在關系密集型數據的分析領域,Neo4j 憑借其強大的圖數據模型脫穎而出。然而,將復雜的連接關系轉化為直觀見解,需要專業的數據可視化技術和分析方法。本文將深入探討 Neo4j 數據可視化的核心原理、關鍵技術、實用技巧以及結合圖數據科學庫(GDS)獲取深度洞察的最佳實踐。 Ne…

樹莓派超全系列教程文檔--(55)如何使用網絡文件系統NFS

如何使用網絡文件系統NFS 網絡文件系統 (NFS)設置基本 NFS 服務器Portmap 鎖定&#xff08;可選&#xff09; 配置 NFS 客戶端端口映射鎖定&#xff08;可選&#xff09; 配置復雜的 NFS 服務器組權限DNS&#xff08;可選&#xff0c;僅在使用 DNS 時&#xff09;NIS&#xff0…

無法運用pytorch環境、改環境路徑、隔離環境

一.未建虛擬環境時 1.創建新項目后&#xff0c;直接運行是這樣的。 2.設置中Virtualenv找不到pytorch環境&#xff1f;因為此時沒有創建新虛擬環境。 3.選擇conda環境&#xff08;全局環境&#xff09;時&#xff0c;是可以下載環境的。 運行結果如下&#xff1a; 是全局環境…

HTML5+CSS3+JS小實例:具有粘性重力的磨砂玻璃導航欄

實例:具有粘性重力的磨砂玻璃導航欄 技術棧:HTML+CSS+JS 效果: 源碼: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width…