1. 程式人生 > >BFS(廣搜)和DFS(深搜)演算法原理(通俗易懂版)

BFS(廣搜)和DFS(深搜)演算法原理(通俗易懂版)

DFS 演算法思想:一直往深處走,直到找到解或者走不下去為止BFS演算法DFS:使用儲存未被檢測的結點,結點按照深度優先的次序被訪問並依次被壓入棧中,並以相反的次序出棧進行新的檢測。BFS:使用佇列儲存未被檢測的結點。結點按照寬度優先的次序被訪問和進出佇列。框架:

BFS

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn = 100;
bool vst[maxn][maxn]; // 訪問標記
int dir[4][2] = {0,1,0,-1,1,0,-1,0}; // 方向向量
struct State { // BFS 佇列中的狀態資料結構
	int x, y; // 座標位置
	int Step_Counter; // 搜尋步數統計器
};
State a[maxn];
bool CheckState(State s) { // 約束條件檢驗
	if(!vst[s.x][s.y] && ...) // 滿足條件
		return 1;
	else // 約束條件衝突
		return 0;
}
void bfs(State st) {
	queue <State> q; // BFS 佇列
	State now, next; // 定義2 個狀態,當前和下一個
	st.Step_Counter = 0; // 計數器清零
	q.push(st); // 入隊
	vst[st.x][st.y] = 1; // 訪問標記
	while(!q.empty()) {
		now = q.front(); // 取隊首元素進行擴充套件
		if(now == G) { // 出現目標態,此時為Step_Counter 的最小值,可以退出即可
			...... // 做相關處理
			return;
		}
		for(int i = 0; i < 4; i++) {
			next.x = now.x + dir[i][0]; // 按照規則生成下一個狀態
			next.y = now.y + dir[i][1];
			next.Step_Counter = now.Step_Counter+1; // 計數器加1
			if(CheckState(next)) { // 如果狀態滿足約束條件則入隊
				q.push(next);
				vst[next.x][next.y] = 1; //訪問標記
			}
		}
		q.pop(); // 隊首元素出隊
	}
	return;
}
int main() {
	......
	return 0;
}

DFS:

/*
該DFS 框架以2D 座標範圍為例,來體現DFS 演算法的實現思想。
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
const int maxn=100;
bool vst[maxn][maxn]; // 訪問標記
int map[maxn][maxn]; // 座標範圍
int dir[4][2]= {0,1,0,-1,1,0,-1,0}; // 方向向量,(x,y)周圍的四個方向
bool CheckEdge(int x,int y) { // 邊界條件和約束條件的判斷
	if(!vst[x][y] && ...) // 滿足條件
		return 1;
	else // 與約束條件衝突
		return 0;
}
void dfs(int x,int y) {
	vst[x][y]=1; // 標記該節點被訪問過
	if(map[x][y]==G) { // 出現目標態G
		...... // 做相應處理
		return;
	}
	for(int i=0; i<4; i++) {
		if(CheckEdge(x+dir[i][0],y+dir[i][1])) // 按照規則生成下一個節點
			dfs(x+dir[i][0],y+dir[i][1]);
	}
	return; // 沒有下層搜尋節點,回溯
}
int main() {
	......
	return 0;
}

相關推薦

BFSDFS演算法原理通俗易懂

DFS 演算法思想:一直往深處走,直到找到解或者走不下去為止BFS演算法DFS:使用棧儲存未被檢測的結點,結點按照深度優先的次序被訪問並依次被壓入棧中,並以相反的次序出棧進行新的檢測。BFS:使用佇列儲存未被檢測的結點。結點按照寬度優先的次序被訪問和進出佇列。框架:BFS#i

BFSDFS演算法原理通俗易懂

#include<cstdio>#include<cstring> #include<queue> #include<algorithm> using namespace std; const int maxn=100; bool vst[maxn][maxn]

深度剖析八大經典排序演算法—C++實現通俗易懂

內容會持續更新,有錯誤的地方歡迎指正,謝謝! 引言 需握各種排序和常用的資料結構的核心思想,並知道是以什麼樣的方式解決了什麼樣的問題。 該部落格的示例程式碼均以遞增排序為目的~ 學習建議:切忌看示例程式碼去理解演算法,而是理解演算法原理寫出程式碼,否

[ZT]周易六十四卦詳解通俗易懂

周易六十四卦詳解(通俗易懂版) 圖1. 伏羲八卦次序方點陣圖 第1卦乾為天(乾卦)剛健中正 上上卦 象曰:困龍得水好運交,不由喜氣上眉梢,一切謀望皆如意,向後時運漸漸高。 這個卦是同卦(下乾上乾)相疊。象徵

圖 | 兩種遍歷方式:深度優先搜尋DFS廣度優先搜尋BFS

前邊介紹了有關圖的 4 種儲存方式,本節介紹如何對儲存的圖中的頂點進行遍歷。常用的遍歷方式有兩種:深度優先搜尋和廣度優先搜尋。 深度優先搜尋(簡稱“深搜”或DFS) 圖 1 無向圖 深度優先搜尋的過程類似於樹的先序遍歷,首先從例

DOM中BFS廣度優先遍歷DFS深度優先遍歷的方法

廣度優先遍歷,即父層遍歷結束,才開始遍歷子層,然後一直往下遍歷,如果是下面這樣一顆DOM樹 <div class="root"> <div class="container"> <section cla

Labyrinth 樹的直徑dfs

The northern part of the Pyramid contains a very large and complicated labyrinth. The labyrinth is divided into square blocks, each of the

【小家思想】通俗易懂講解JWTOAuth2,以及他倆的區別聯絡Token鑑權解決方案

相關閱讀 【小家java】java5新特性(簡述十大新特性) 重要一躍 【小家java】java6新特性(簡述十大新特性) 雞肋升級 【小家java】java7新特性(簡述八大新特性) 不溫不火 【小家java】java8新特性(簡述十大新特性) 飽受讚譽 【小家java】java9

三階幻方一維表二維進行列舉

三階幻方 時限:1000ms 記憶體限制:10000K 總時限:3000ms 描述: 三階幻方是最簡單的幻方,又叫九宮格,是由1,2,3,4,5,6,7,8,9九個數字組成的一個三行三列的矩陣,其對角線、橫行、縱向的的和都為15。 輸入: 無 輸出:

matlab中的中值濾波medfilt2opencv中的中值濾波medianblur是不同的

matlab中的中值濾波medfilt2()和opencv中的中值濾波medianblur()做出的結果不同,如圖所示: Opencv處理結果如下: Matlab處理結果如下: Opencv處理過程中的程式程式碼: float aa[] = { 1, 2, 3, 4, 5, 6, 7,

主成分分析PCA基於核函式的主成分分析KPCA入門

前言 主成分分析是在做特徵篩選時的重要手段,這個方法在大部分的書中都只是介紹了步驟方法,並沒有從頭到尾把這個事情給說清楚。本文的目的是把PCA和KPCA給說清楚。主要參考了YouTube上李政軒的Principal Component Analysis and

C++—randsrand的用法簡單易懂—產生隨機數

每天進步一點點,目標距離縮小點在C++中,可以使用rand()函式產生隨機數。(rand()函式的標頭檔案在<cstdlib>中)如果想產生在一定範圍內的數,可以用取餘的方法獲得。如想獲得0—100的數同樣的道理,如果想獲得100-200之間的數—————————

通過隧道實現虛擬伺服器VS/TUN通過網路地址轉換實現虛擬伺服器VS/NAT

一  通過隧道實現虛擬伺服器(VS/TUN):   排程器把請求報文通過IP隧道(相當於ipip或ipsec)轉發至真實伺服器,而真實伺服器將響應處理後直接返回給客戶,這種排程器只處理請求的入站報文,一般網路服務應答資料比請求報文大很多,採用VS/TUN技術後,集群系統的最

WSAEventselect模型中的一些注意事項尤其是event事件的關聯與重置;FD_WRITE事件的作用

  1. 需要包含winsock2.h,連結ws2_32.llib 2. 把#include <winsock2.h>放到最前面 至於原因,那是因為windows.h這個標頭檔案已經包含了winsock.h,winsock.h和winsock2.h貌似有衝突 

JWT一些雜談雖然譁眾取寵,但講的東西挺通俗易懂

摘要: 在Web應用中,使用JWT替代session並不是個好主意 適合JWT的使用場景 抱歉,當了回標題黨。我並不否認JWT的價值,只是它經常被誤用。 什麼是JWT 根據維基百科的定義,JSON WEB Token(JWT,讀作 [

RSA演算法原理——3RSA加解密過程及公式論證

個人分類: 演算法 上期(RSA簡介及基礎數論知識)為大家介紹了:互質、尤拉函式、尤拉定理、模反元素 這四個數論的知識點,而這四個知識點是理解RSA加密演算法的基石,忘了的同學可以快速的回顧一遍。 三、RSA加解密過程及公式論證 今天的內容主要分為三

今日頭條演算法原理全文

今天,演算法分發已經是資訊平臺、搜尋引擎、瀏覽器、社交軟體等幾乎所有軟體的標配,但同時,演算法也開始面臨質疑、挑戰和誤解。今日頭條的推薦演算法,從2012年9月第一版開發執行至今,已經經過四次大的調整和修改。 今日頭條委託資深演算法架構師曹歡歡博士,公開今日頭條的演算法原理,以期推動整

RSA演算法原理

(注意: 博文中部分公式圖片來自維基百科和 google , 需要翻牆檢視) 作者: 阮一峰 日期: 2013年6月27日 如果你問我,哪一種演算法最重 因為它是計算機通訊安全的基石,保證了加密資料不會被破解。你可以想象一下,信用卡交易被破解的後果。 進

快速排序基本思路通俗易懂+例子

快速排序 今天看到大神寫的一篇快速排序的部落格,肅然起敬,覺得原來快速排序這麼簡單 下面進行簡單的試試 快速排序的基本思想是 1、先從數列中取出一個數作為基準數 2、分割槽過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊 3、再對左

輸入日期判斷為該年第幾天 易懂

#include<stdio.h> int main() {   int i,j,k;   while(scanf("%d/%d/%d",&i,&j,&k) !=