BFS 和 DFS(深度優先搜索、廣度優先搜索)

深度優先搜索(DFS)和廣度優先搜索(BFS)是兩種常用的圖遍歷算法,用于解決圖相關的問題。它們在搜索問題中具有廣泛的應用,如路徑搜索、連通性檢測等。
以下是具體區別:

(圖片引自:https://www.cnblogs.com/xuxinstyle/p/13261651.html)

深度優先搜索(DFS)

深度優先搜索是一種先探索到盡可能深的節點,再回溯到之前的節點的搜索策略。在實現上,DFS通常使用遞歸或棧來實現。

模板:

def dfs(node, visited):if node in visited:returnvisited.add(node)# Process current node# Explore neighborsfor neighbor in node.neighbors:dfs(neighbor, visited)

講解:

1. 從起始節點開始,訪問當前節點并標記為已訪問。
2. 對當前節點的鄰居節點進行遍歷,若鄰居節點未被訪問過,則以該鄰居節點為新的當前節點,繼續進行深度優先搜索。
3. 遞歸地進行上述步驟,直到所有可達節點都被訪問。

例題:

問題:給定一個無向圖,判斷是否存在從節點A到節點B的路徑。

def hasPath(graph, start, end):"""判斷是否存在從start到end的路徑Args:graph: 圖的鄰接表表示start: 起始節點end: 目標節點Returns:bool: 如果存在路徑返回True,否則返回False"""visited = set()return dfs(start, end, visited, graph)def dfs(node, end, visited, graph):"""深度優先搜索的輔助函數Args:node: 當前節點end: 目標節點visited: 已訪問過的節點集合graph: 圖的鄰接表表示Returns:bool: 如果存在路徑返回True,否則返回False"""if node == end:return Truevisited.add(node)for neighbor in graph[node]:if neighbor not in visited:if dfs(neighbor, end, visited, graph):return Truereturn False


廣度優先搜索(BFS)

廣度優先搜索是一種先探索到當前節點的所有鄰居節點,再逐層向外搜索的策略。通常使用隊列來實現。把每個還沒有搜索到的點依次放入隊列,然后再彈出隊列的頭部元素當做當前遍歷點。模板:
?

from collections import dequedef bfs(start):"""廣度優先搜索Args:start: 起始節點Returns:None"""queue = deque([start])visited = set()while queue:node = queue.popleft()if node not in visited:visited.add(node)# Process current node# 處理當前節點# Explore neighbors# 探索當前節點的鄰居節點for neighbor in node.neighbors:queue.append(neighbor)


要點

1. 將起始節點加入隊列,并標記為已訪問。
2. 當隊列不為空時,彈出隊首節點,對其未被訪問的鄰居節點進行遍歷。
3. 將未被訪問的鄰居節點加入隊列,并標記為已訪問。
4. 重復上述步驟,直到隊列為空。
分類模板:如果不需要確定當前遍歷到了哪一層,模板如下(這里參考:https://www.cnblogs.com/xuxinstyle/p/13261651.html)
?

while queue 不空:cur = queue.pop()for 節點 in cur的所有相鄰節點:if 該節點有效且未訪問過:queue.push(該節點)

如果要確定當前遍歷到了哪一層,BFS模板如下
這里增加了level表示當前遍歷到二叉樹中的哪一層了,也可以理解為在一個圖中,現在已經走了多少步了。size表示在當前遍歷層有多少個元素,也就是隊列中的元素數,我們把這些元素一次性遍歷完,即把當前層的所有元素都向外走了一步。

level = 0
while queue 不空:size = queue.size()while (size --) {cur = queue.pop()for 節點 in cur的所有相鄰節點:if 該節點有效且未被訪問過:queue.push(該節點)}level ++;

例題:

問題:給定一個無向圖,從節點A開始,找到到節點B的最短路徑的長度。

from collections import dequedef shortestPath(graph, start, end):"""尋找從start到end的最短路徑長度Args:graph: 圖的鄰接表表示start: 起始節點end: 目標節點Returns:int: 最短路徑長度,如果不存在路徑則返回-1"""queue = deque([(start, 0)])visited = set()while queue:node, distance = queue.popleft()if node == end:return distancevisited.add(node)for neighbor in graph[node]:if neighbor not in visited:queue.append((neighbor, distance + 1))return -1 ?# If no path found# Example graph representation: {node: [neighbors]}
graph = {'A': ['B', 'C'],'B': ['A', 'D', 'E'],'C': ['A', 'F'],'D': ['B'],'E': ['B', 'F'],'F': ['C', 'E']
}print(shortestPath(graph, 'A', 'F')) ?# Output: 2

這里使用了BFS算法來搜索從節點A到節點B的最短路徑的長度。

下面是代碼的一些區別:這里使用字典來存圖

BFS實現

#BFS實現
graph = {"A":["B","C"],"B":["A","C","D"],"C":["A","B","D","F"],"D":["B","C","E","F"],"E":["C","D"],"F":["D"]}
def BFS(graph,s):queue = []queue.append(s)#將元素 s 加入到隊列的尾部(隊尾)seen = set()#儲存出現過的量seen.add(s)while(len(queue)>0):vertex ?= queue.pop(0)#從隊列的頭部(隊首)彈出元素nodes = graph[vertex]#vertex的所有臨接點for w in nodes:if w not in seen:queue.append(w)seen.add(w)print(vertex)
BFS(graph,"A")

DFS實現 ?隊列—>棧

graph = {"A":["B","C"],"B":["A","C","D"],"C":["A","B","D","F"],"D":["B","C","E","F"],"E":["C","D"],"F":["D"]}
def BFS(graph,s):queue = []queue.append(s)seen = set()#儲存出現過的量seen.add(s)while(len(queue)>0):vertex ?= queue.pop()#pop(0)->pop() 先彈出最后一個元素 這里體現出棧nodes = graph[vertex]#vertex的所有臨接點for w in nodes:if w not in seen:queue.append(w)seen.add(w)print(vertex)BFS(graph,"A")

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

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

相關文章

推薦幾款較好的開源成熟框架

一. 若依: 1. 官方網站:https://doc.ruoyi.vip/ruoyi/ 2. 若依SpringBootVueElement 的后臺管理系統:https://gitee.com/y_project/RuoYi-Vue 3. 若依SpringBootVueElement 的后臺管理系統:https://gitee.com/y_project/RuoYi-Cl…

根據音頻中的不同講述人聲音進行分離音頻 | 基于ai的說話人聲音分離項目

0.研究背景 在實際的開發中可能會遇到這樣的問題,老板讓你把音頻中的每個講話人的聲音分離成不同的音頻片段。你可以使用au等專業的音頻處理軟件手動分離。但是這樣效率太慢了,現在ai這么發達,我們能否借助ai之力來分離一條音頻中的不同的說…

本地化部署 DeepSeek:從零到一的完整指南

本地化部署 DeepSeek:從零到一的完整指南 個人主頁:顧漂亮 文章專欄:AI學習 目錄 引言什么是 DeepSeek?為什么選擇本地化部署?DeepSeek 本地化部署的前期準備 硬件需求軟件需求環境配置 DeepSeek 本地化部署步驟 步驟…

使用ArcGIS Pro自動矢量化水系

在地理信息系統(GIS)領域,自動矢量化是一項至關重要的技術,它能夠將柵格圖像中的要素轉換為矢量數據,從而方便后續的分析和處理。本文將詳細介紹如何使用ArcGIS Pro自動矢量化水系,適用于那些顏色相對統一、…

C++類和對象進階:初始化列表和static成員深度詳解

C類和對象:初始化列表和static成員深度詳解 1. 前言2. 構造函數初始化成員變量的方式2.1 構造函數體內賦值2.2 初始化列表2.2.1 初始化列表的注意事項 2.3 初始化列表的初始化順序 3. 類的靜態成員3.1 引入3.2 靜態成員變量3.3 靜態成員函數3.4 靜態成員的注意事項3…

ubuntu ffmpeg 安裝踩坑

ffmpeg 安裝踩坑 安裝命令: sudo apt update sudo apt install ffmpeg如果以上命令沒有報錯,那么恭喜你很幸運,可以關閉這篇文章了! 如果跟我一樣,遇到如下報錯,可以接著往下看: 報錯信息: …

第13章 int指令

目錄 13.1 int 指令13.2 編寫供應用程序調用的中斷例程13.3 對int、iret和棧的深入理解13.4 BIOS和DOS所提供的中斷例程13.5 BIOS和DOS中斷例程的安裝過程13.6 BIOS中斷例程應用13.7 DOS中斷例程應用實驗13 編寫、應用中斷例程 中斷信息可以來自CPU的內部和外部,當C…

最新扣子(Coze)案例教程:全自動DeepSeek 寫影評+批量生成 + 發布飛書,提效10 倍!手把手教學,完全免費教程

👨?💻群里有同學是做影視賽道的博主,聽說最近DeepSeek這么火,咨詢能不能用DeepSeek寫影評,并整理電影數據資料,自動發布到飛書文檔,把每天的工作做成一個自動化的流程。 那今天斜杠君就為大家…

DeepSeek 提示詞:定義、作用、分類與設計原則

🧑 博主簡介:CSDN博客專家,歷代文學網(PC端可以訪問:https://literature.sinhy.com/#/?__c1000,移動端可微信小程序搜索“歷代文學”)總架構師,15年工作經驗,精通Java編…

鳥語林-論壇系統自動化測試

文章目錄 一、自動化實施步驟1.1編寫Web測試用例1.2 編寫自動化代碼1.2.1 LoginPageTest1) 能否正確打開登錄頁面2) 點擊去注冊能否跳轉注冊頁面3) 模擬用戶登錄,輸入多組登錄測試用例 1.2.2 RegisterPageTest1) 能否成功打開注冊頁面2) 注冊測試用例3) 點擊去登錄按…

DeepSeek模型量化

技術背景 大語言模型(Large Language Model,LLM),可以通過量化(Quantization)操作來節約內存/顯存的使用,并且降低了通訊開銷,進而達到加速模型推理的效果。常見的就是把Float16的浮…

本周行情——250222

本周A股行情展望與策略 結合近期盤面特征及市場主線演化,本周A股預計延續結構性分化行情,科技成長與政策催化板塊仍是資金主戰場,但需警惕高標股分歧帶來的波動。以下是具體分析與策略建議: 1. 行情核心驅動因素 主線延續性&…

【JT/T 808協議】808 協議開發筆記 ② ( 終端注冊 | 終端注冊應答 | 字符編碼轉換網站 )

文章目錄 一、消息頭 數據1、消息頭拼接2、消息 ID 字段3、消息體屬性 字段4、終端手機號 字段5、終端流水號 字段 二、消息體 數據三、校驗碼計算四、最終計算結果五、終端注冊應答1、分解終端應答數據2、終端應答 消息體 數據 六、字符編碼轉換網站 一、消息頭 數據 1、消息頭…

使用ezuikit-js封裝一個對接攝像頭的組件

ezuikit-js 是一個基于 JavaScript 的視頻播放庫,主要用于在網頁中嵌入實時視頻流播放功能。它通常用于與支持 RTSP、RTMP、HLS 等協議的攝像頭或視頻流服務器進行交互,提供流暢的視頻播放體驗。 主要功能 多協議支持:支持 RTSP、RTMP、HLS …

一周學會Flask3 Python Web開發-flask3模塊化blueprint配置

鋒哥原創的Flask3 Python Web開發 Flask3視頻教程: 2025版 Flask3 Python web開發 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili 我們在項目開發的時候,多多少少會劃分幾個或者幾十個業務模塊,如果把這些模塊的視圖方法都寫在app.py…

DSC數字選擇性呼叫

GMDSS Digital Selective Calling WAVECOM Decoder Online Help 12.0.0 VHF Marine GMDSS/DSC Decode & Scicos Simulation Black Cat Systems (一)DSC調制方式 DSC(Digital Selective Calling,數字選擇性呼叫&#xff0…

科普:你的筆記本電腦中有三個IP:127.0.0.1、無線網 IP 和局域網 IP;兩個域名:localhost和host.docker.internal

三個IP 你的筆記本電腦中有三個IP:127.0.0.1、無線網 IP 和局域網 IP。 在不同的場景下,需要選用不同的 IP 地址,如下為各自的特點及適用場景: 127.0.0.1(回環地址) 特點 127.0.0.1 是一個特殊的 IP 地…

《AI與NLP:開啟元宇宙社交互動新紀元》

在科技飛速發展的當下,元宇宙正從概念逐步走向現實,成為人們關注的焦點。而在元宇宙諸多令人矚目的特性中,社交互動體驗是其核心魅力之一。人工智能(AI)與自然語言處理(NLP)技術的迅猛發展&…

量化方法bitsandbytes hqq eetq區別

量化方法bitsandbytes、HQQ(Half-Quadratic Quantization)和EETQ(Efficient and Effective Ternary Quantization)在深度學習模型壓縮和加速中各有特點,以下是它們的區別: 1. bitsandbytes 概述: bitsand…

Hutool - Log:自動識別日志實現的日志門面

一、簡介 在 Java 開發中,日志記錄是一項非常重要的功能,它可以幫助開發者在開發和生產環境中監控程序的運行狀態、排查問題。然而,Java 生態系統中有多種日志實現框架,如 Log4j、Logback、JDK 自帶的日志框架等。為了在不同的項…