廣度優先搜索(BFS) vs 深度優先搜索(DFS):算法對比與 C++ 實現

目錄

一、BFS 和 DFS 的核心思想

1.?BFS(廣度優先搜索)

2.?DFS(深度優先搜索)

二、BFS 和 DFS 的對比

三、C++ 代碼實現

1. BFS 實現(鄰接表表示的無向圖)

2. DFS 實現(遞歸與迭代兩種方式)

四、關鍵細節說明

1. BFS 的關鍵點

2. DFS 的關鍵點

五、應用場景對比

六、總結


一、BFS 和 DFS 的核心思想

1.?BFS(廣度優先搜索)

  • 核心思想:按“層級”逐層遍歷,先訪問離起點最近的節點,再逐步向外擴散。

  • 類比:類似水波擴散,一層一層向外推進。

  • 數據結構:隊列(FIFO)。

  • 適用場景:最短路徑(未加權圖)、社交網絡層級關系、迷宮最短路徑。

2.?DFS(深度優先搜索)

  • 核心思想:沿著一條路徑盡可能深入,直到無法繼續時回溯,嘗試其他分支。

  • 類比:走迷宮時,遇到岔路選擇一條路走到頭,再返回選擇其他路。

  • 數據結構:棧(LIFO)或遞歸調用棧。

  • 適用場景:拓撲排序、連通性檢測、回溯問題(如八皇后)、圖的環路檢測。


二、BFS 和 DFS 的對比

特性BFSDFS
遍歷順序層級遍歷(近到遠)深度優先(一條路走到黑)
數據結構隊列(先進先出)棧(后進先出)或遞歸
空間復雜度O(N)(最壞情況,如完全二叉樹)O(H)(H為樹的高度,平衡樹時為 O(logN))
時間復雜度O(N + E)(N為節點數,E為邊數)同左
最短路徑天然支持(未加權圖)需額外處理(如記錄路徑長度)
內存消耗較高(存儲每一層節點)較低(僅存儲當前路徑)
實現復雜度簡單(固定隊列操作)遞歸簡單,迭代需顯式棧

三、C++ 代碼實現

1. BFS 實現(鄰接表表示的無向圖)

#include <iostream>
#include <queue>
#include <vector>
using namespace std;void bfs(const vector<vector<int>>& graph, int start) {vector<bool> visited(graph.size(), false);queue<int> q;q.push(start);visited[start] = true;while (!q.empty()) {int node = q.front();q.pop();cout << node << " "; // 訪問節點// 遍歷當前節點的所有鄰居for (int neighbor : graph[node]) {if (!visited[neighbor]) {visited[neighbor] = true;q.push(neighbor);}}}
}// 示例圖結構
vector<vector<int>> graph = {{1, 2},     // 節點0的鄰居{0, 3, 4},  // 節點1的鄰居{0, 5, 6},  // 節點2的鄰居{1},        // 節點3的鄰居{1},        // 節點4的鄰居{2},        // 節點5的鄰居{2}         // 節點6的鄰居
};int main() {cout << "BFS遍歷結果: ";bfs(graph, 0); // 輸出: 0 1 2 3 4 5 6return 0;
}

2. DFS 實現(遞歸與迭代兩種方式)

// 遞歸實現
void dfsRecursive(const vector<vector<int>>& graph, int node, vector<bool>& visited) {visited[node] = true;cout << node << " "; // 訪問節點for (int neighbor : graph[node]) {if (!visited[neighbor]) {dfsRecursive(graph, neighbor, visited);}}
}// 迭代實現(顯式棧)
void dfsIterative(const vector<vector<int>>& graph, int start) {vector<bool> visited(graph.size(), false);stack<int> s;s.push(start);visited[start] = true;while (!s.empty()) {int node = s.top();s.pop();cout << node << " ";// 反向遍歷鄰居以保證與遞歸順序一致for (auto it = graph[node].rbegin(); it != graph[node].rend(); ++it) {if (!visited[*it]) {visited[*it] = true;s.push(*it);}}}
}int main() {cout << "DFS遞歸遍歷結果: ";vector<bool> visited(graph.size(), false);dfsRecursive(graph, 0, visited); // 輸出: 0 1 3 4 2 5 6cout << "\nDFS迭代遍歷結果: ";dfsIterative(graph, 0);          // 輸出: 0 1 3 4 2 5 6return 0;
}

四、關鍵細節說明

1. BFS 的關鍵點

  • 隊列操作:每次從隊頭取出節點,并將未訪問的鄰居加入隊尾。

  • 最短路徑:BFS 首次訪問到目標節點時,路徑一定是最短的(適用于未加權圖)。

  • 空間復雜度:最壞情況下需存儲所有節點(如完全二叉樹最后一層)。

2. DFS 的關鍵點

  • 遞歸與棧:遞歸隱式使用系統棧,迭代顯式使用棧。

  • 遍歷順序:迭代實現中,若按正序訪問鄰居,結果可能與遞歸順序不同(需反向遍歷鄰居)。

  • 應用場景:適合探索所有可能性(如回溯問題),但可能陷入深層分支無法及時返回。


五、應用場景對比

問題類型推薦算法原因
未加權圖最短路徑BFS天然支持最短路徑
圖的連通性檢測DFS/BFS二者均可快速遍歷所有連通節點
拓撲排序DFS天然支持后序遍歷的逆序
迷宮所有路徑DFS回溯特性適合探索所有可能路徑
社交網絡層級關系分析BFS按層遍歷符合實際場景
檢測環路DFS通過回溯標記路徑,容易檢測重復訪問

六、總結

  • BFS?適合“廣度優先”問題,如最短路徑;DFS?適合“深度優先”問題,如回溯和連通性。

  • 代碼實現:BFS 用隊列,DFS 用棧或遞歸,注意遍歷順序和空間消耗。

  • 選擇依據:根據問題特性(如是否需要最短路徑、內存限制)選擇算法。

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

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

相關文章

vulhub靶機----基于docker的初探索,環境搭建

環境搭建 首先就是搭建docker環境&#xff0c;這里暫且寫一下 #在kali apt update apt install docker.io配置docker源&#xff0c;位置在/etc/docker/daemon.json {"registry-mirrors": ["https://5tqw56kt.mirror.aliyuncs.com","https://docker…

第7章 類與面向對象

6-1 二維平面上的點操作&#xff08;Python3&#xff09; 題目描述 設計一個表示二維平面上點的類 Point。該類應該包含以下功能&#xff1a; 兩個私有屬性 _x 和 _y&#xff0c;分別表示點的橫坐標和縱坐標。 一個構造函數 __init__&#xff0c;用于初始化點的坐標。 一個…

算法訓練篇06--力扣611.有效三角形的個數

目錄 1.題目鏈接&#xff1a;611.有效三角形的個數 2.題目描述&#xff1a; 3.解法一&#xff1a;(暴力解法)(會超時)&#xff1a; 4.解法二(排序雙指針) 1.題目鏈接&#xff1a;611.有效三角形的個數 2.題目描述&#xff1a; 給定一個包含非負整數的數組 nums &#xf…

網絡編程之解除udp判斷客戶端是否斷開

思路&#xff1a;每幾秒發送一條不顯示的信息&#xff0c;客戶端斷開則不再發送信息&#xff0c;超時則表示客戶端斷開連接。&#xff08;心跳包&#xff09; 服務器 #include <head.h>#define MAX_CLIENTS 100 // 最大支持100個客戶端 #define TIMEOUT 5 // 5秒…

Python Cookbook-4.8 二維陣列變換

任務 需要變換一個列表的列表&#xff0c;將行換成列&#xff0c;列換成行。 解決方案 需要一個列表&#xff0c;其中的每一項都是同樣長度的列表&#xff0c;像這樣 arr [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]列表推導提供了簡單方便的方法以完成二維陣列的轉換: print …

B樹與B+樹在MySQL中的應用:索引

數據結構演示網站&#xff1a;Data Structure Visualization 先來了解兩個數據結構B樹與B樹 B樹&#xff1a; N階B樹每個節點最多存儲N-1個Key&#xff0c;N個指針 例如&#xff1a;一個5階B樹&#xff0c;當前節點存儲到5個Key時&#xff0c;中間的數會向上分離&#xff0c;…

【重構小程序】基于Tika和Langchain4J進行文件解析和文本切片(二)

為了將大語言模型植入到小程序中&#xff0c;來支持用戶的問答。那我們首先需要做的是什么呢&#xff0c;不是引入大語言模型&#xff0c;而且為大語言模型搭建一個私有化知識庫&#xff0c;但是這是這節呢&#xff0c;我們先不搭建私有化知識庫&#xff0c;在這之前&#xff0…

python|exm6-1try-except結構|raise關鍵字|異常類型

目錄 一、try-expect 1. 多個try-expect結構的使用 1.1 捕捉特定異常 1.2 捕捉全部異常 1.3 所有異常合并處理 2. try-except-else-finally 結構 二、raise 關鍵字 一、try-expect try-expect 結構是 Python 中用于異常處理的關鍵機制。它允許你捕獲并處理代碼中可能發生…

小藍的括號串1(棧,藍橋云課)

問題描述 小藍有一個長度為 nn 的括號串&#xff0c;括號串僅由字符 ( 、 ) 構成&#xff0c;請你幫他判斷一下該括號串是否合法&#xff0c;合法請輸出 Yes &#xff0c;反之輸出 No 。 合法括號序列&#xff1a; 空串是合法括號序列。 若 ss 是合法括號序列&#xff0c;則 (…

Centos7配置本地yum源

Centos7配置本地yum源 1、基于iso鏡像的centos源 1.1 準備iso <span style"color:#000000"><span style"background-color:#ffffff"><code class"language-bash"><span style"color:#008000"># 首先看自己使用…

VNA操作使用學習-14 再測晶振特性

再測一下4Mhz晶振&#xff0c;看看特性曲線&#xff0c;熟悉一下vna使用。 s11模式&#xff0c;找遍了各種format都無法顯示&#xff0c;只有這一種&#xff08;s11&#xff0c;Resistance&#xff09;稍微顯示出一個諧振&#xff0c;但是只有一個點。 s21模式 這是201p&#…

Tr0ll2靶機詳解

一、主機發現 arp-scan -l靶機ip&#xff1a;192.168.55.164 二、端口掃描、漏洞掃描、目錄枚舉、指紋識別 2.1端口掃描 nmap --min-rate 10000 -p- 192.168.55.164發現21端口的ftp服務開啟 以UDP協議進行掃描 使用參數-sU進行UDP掃描 nmap -sU --min-rate 10000 -p- 19…

基于開源模型的微調訓練及瘦身打造隨身掃描儀方案__用AI把手機變成文字識別小能手

基于開源模型的微調訓練及瘦身打造隨身掃描儀方案__用AI把手機變成文字識別小能手 一、準備工作&#xff1a;組裝你的"數碼工具箱" 1. 安裝基礎工具&#xff08;Python環境&#xff09; 操作步驟&#xff1a; 訪問Python官網下載安裝包安裝時務必勾選Add Python to…

GitHub 超火的開源終端工具——Warp

Warp 作為近年來 GitHub 上備受矚目的開源終端工具&#xff0c;以其智能化、高性能和協作能力重新定義了命令行操作體驗。以下從多個維度深入解析其核心特性、技術架構、用戶評價及生態影響力&#xff1a; 一、背景與核心團隊 Warp 由前 GitHub CTO Jason Warner 和 Google 前…

使用C#創建安裝Windows服務程序

在實際工作中&#xff0c;如果我們需要開發一個運行在后臺&#xff0c;無需用戶交互&#xff0c;不需要界面的應用程序&#xff0c;我們可以通過Windows服務來實現。 本文主要介紹如何基于C#創建一個Windows服務&#xff0c;來實現西門子PLC的定時讀取保存。 一、Windows服務…

docker、docker-compose常用命令

初學者使用的docker、docker-compose常用命令&#xff0c;日常練習&#xff0c;環境簡單搭建。 一、docker 1.1、安裝docker 1.1.1、yum安裝 #安裝docker的數據存儲驅動包 yum install -y yum-utils device-mapper-persistent-data lvm2 #設置新的安裝源、下載配置文件到…

阿里的MNN源碼如何編譯成so文件,供Android調用

在Ubtuntu下面的編譯&#xff0c;先整理編譯環境 1、安裝環境依賴 # 安裝必要工具 sudo apt update sudo apt install -y cmake ninja-build git wget # 安裝Android NDK&#xff08;建議使用r21版本或更高&#xff09; wget https://dl.google.com/android/repository/a…

吳恩達機器學習筆記復盤(六)梯度下降算法

簡介 梯度下降&#xff08;Gradient Descent&#xff09;是一種常用的優化算法&#xff0c;廣泛應用于機器學習、深度學習等領域&#xff0c;在這里是用于求J&#xff08;w,b&#xff09;局部最小值。 我自己覺得這樣說有點過于抽象。換個直觀點的說法就是&#xff0c;一個人…

使用JAVA-進行維吉尼亞密碼的解密與加密

維吉尼亞密碼 來源于百度百科 維吉尼亞密碼_百度百科 具體代碼 import java.util.*;public class WJMYmm {//常量 26public static final int N 26;//密碼public static void main(String[] args) {//字母String ZM"abcdefghijklmnopqrstuvwxyz";char[] zm ZM.…

Java DelayQueue 延遲隊列

Java DelayQueue 延遲隊列 1. DelayQueue 概述 DelayQueue 是 Java 并發包&#xff08;java.util.concurrent&#xff09;中的一個 無界 阻塞隊列&#xff0c;用于存儲實現了 Delayed 接口的元素。隊列中的元素只有在達到指定的延遲時間后才能被獲取。 2. DelayQueue 的底層…