廣度優先搜尋 BFS

2021-10-16 18:50:07 字數 3503 閱讀 8909

廣度優先搜尋:當碰到岔道口時,總是先依次訪問從該岔道口能直接到達的所有結點,然後再按這些結點被訪問的順序去依次訪問它們能直接到達的所有結點,以此類推,直到所有結點都被訪問為止。

廣度優先搜尋(bfs)一般由佇列實現,且總是按層次的順序進行遍歷。

定義佇列q,並將起點s入隊

寫乙個while迴圈,迴圈條件時佇列q非空

在while迴圈中,先取出隊首元素top,然後訪問它(訪問可以時任何事情,例如將其輸出)。訪問完後將其出隊

將top的下一層結點中所有未曾入隊的結點入隊,並標記它們的層號為now的層號加1,同時設定這些入隊的結點已入過隊

返回2繼續迴圈

void

bfs(

int s)

}

給出乙個 mxn 的矩陣,矩陣中的元素為0或1。稱位置(x, y)與其上下左右四個位置(x, y+1)、(x, y-1)、(x+1, y)、(x-1, y)是相鄰的。如果矩陣中有若干個1是相鄰的(不必兩兩相鄰),那麼稱這些 1 構成了一塊「塊」。求給定的矩陣中「塊」的個數。

0 1 1 1 0 0 1

0 0 1 0 0 0 0

0 0 0 0 1 0 0

0 0 0 1 1 1 0

1 1 1 0 1 0 0

1 1 1 1 0 0 0

例如上面 6x7 的矩陣中,「塊」的個數為4。

列舉每乙個位置的元素

如果為0,則跳過

如果為1,則使用bfs查詢與該位置相鄰的4個位置

判斷它們是否為1(如果某個相鄰的位置為1,則同樣去查詢與該位置相鄰的4個位置,直到整個「1」塊訪問完畢)。

為了防止走回頭路,設定乙個bool型陣列 inq 來記錄每個位置是否在bfs中已入過隊

小技巧:對當前位置(x, y)來說,由於與其相鄰的四個位置分別為(x, y+1)、(x, y-1)、(x+1, y)、(x-1, y),那麼不妨設定下面兩個增量陣列,來表示四個方向(0, 1)、(0, -1)、(1, 0)、(-1, 0)

int x=

;int y=

;

使用for迴圈來列舉4個方向,以確定當前座標(nowx, nowy)相鄰的4個位置。

for

(int i =

0; i <

4; i++

)

bfs

#include

#include

using

namespace std;

const

int maxn =

100;

struct node

node;

int n, m;

//矩陣大小為n*m

int matrix[maxn]

[maxn]

;//01矩陣

bool inq[maxn]

[maxn]=;

//記錄位置(x, y)是否已入過隊

int x[4]

=;//增量陣列

int y[4]

=;//判斷座標(x, y)是否需要訪問

bool

judge

(int x,

int y)

//bfs函式訪問位置(x, y)所在的塊,將該塊中所有「1」的inq都設定為true

void

bfs(

int x,

int y)}}

}int

main()

}int ans =0;

//存放塊數

for(

int x =

0; x < n; x++

)//列舉每乙個位置}}

printf

("%d\n"

, ans)

;return0;

}

給定乙個n*m大小的迷宮,其中 * 代表不可通過的牆壁,而 . 代表平地,s表示起點,t代表終點。移動過程中,如果當前位置是(x, y)(下標從0開始),且每次只能前往上下左右(x, y+1)、(x, y-1)、(x-1, y)、(x+1, y)四個位置的平地,求從起點s到達終點t的最少步數。

在上面的樣例中,s的座標為(2, 2),t的座標為(4, 3)

由於求最少步數,而bfs是通過層次的順序來遍歷的,因此可以從起點s開始計數遍歷的層數,那麼在到達終點t時的層數就是需要求解的起點s到達終點t的最少步數。

#include

#include

#include

using

namespace std;

const

int maxn =

100;

struct node

s, t, node;

//s為起點,t為終點,node為臨時結點

int n, m;

//n為行,m為列

char maze[maxn]

[maxn]

;//迷宮資訊

bool inq[maxn]

[maxn]=;

//記錄位置(x, y)是否已入過隊

int x[4]

=;//增量陣列

int y[4]

=;//檢測位置(x, y)是否有效

bool

test

(int x,

int y)

intbfs()

for(

int i =

0; i <

4; i++

)//迴圈4次,得到4個相鄰位置}}

return-1

;//無法到達終點t返回-1

}int

main()

maze[i]

[m +1]

='\0';}

scanf

("%d%d%d%d"

,&s.x,

&s.y,

&t.x,

&t.y)

;//起點和終點的座標

s.step =0;

//初始化起點的層數為0,即s到s的最少步數為0

printf

("%d\n"

,bfs()

);return0;

}

//輸入資料55

//5行5列..

...//迷宮資訊.*

.*..

*s*..*

**..

..t*22

43//起點s的座標與終點t的座標

11

//輸出資料

在bfs中設定的inq陣列的含義是判斷結點是否已入過隊,而不是結點是否已被訪問。

區別:如果設定成是否被訪問,有可能在某個結點正在佇列中(但還未訪問)時由於其他結點可以到達它而將這個結點再次入隊,導致很多結點反覆入隊,計算量增加。

因此bfs中讓每個結點只入隊一次,則需要設定inq陣列的含義為結點是否已入隊。

BFS廣度優先搜尋

廣度優先搜尋,利用佇列實現,結束標誌是隊列為空的時候 承接dfs的演算法實現的講例,對於迷宮問題我們也可以採取廣度優先搜尋實現 include iostream include cstdio include cstdlib using namespace std int map 55 55 int ...

bfs廣度優先搜尋

這一課我們來學習圖的另一種遍歷方法 廣度優先搜尋 breadth first search,簡稱 bfs 這是一種連通圖的常用遍歷策略,通常用於求起點到各點的最短路徑,以及求兩點之間的最優路徑等問題。首先我們先來看看廣度優先搜尋的具體方法吧 對於乙個連通圖,我們假設一開始所有頂點均未被訪問,廣度優先...

廣度優先搜尋bfs

bfs即廣度優先搜尋演算法,其是搜尋演算法中的一種。1.dfs常用於尋找是否存在解 其從a節點出發,選取乙個臨近點b,然後不斷深入,在搜尋完b的下屬節點 ehif 後,回到a再搜尋臨近a的c節點,以此類推。2.bfs則用於在最短的時間或最少的移動距離內找到解 其往往從a節點出發,搜尋周圍所有的圍繞節...