《演算法筆記》廣度優先搜尋 BFS 初步學習

2021-10-13 07:29:21 字數 2956 閱讀 7582

bfs一般由佇列實現,且總是按層次的順序進行遍歷,其基本寫法如下:

void

bfs(

int s)

}

下面是對每乙個步驟的說明:

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

2.寫乙個while迴圈,迴圈條件是佇列q非空

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

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

5.返回2.繼續迴圈

接下來看兩個迷宮類問題:

.

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

0111001

0010000

0000100

0001110

1110100

1111000

例如上面的6x7矩陣中,塊的個數是4

需要乙個函式在遍歷到有1存在時,能找到這個1身邊的所有1。這個演算法這裡採用bfs。

#include

#include

using

namespace std;

const

int maxn 100

;struct node

node;

int n, m;

//矩陣大小

int matrix[maxn]

[maxn]

;//矩陣

bool inq[maxn]

[maxn]

;//判斷某個點是否已經入隊過

bool

judge

(int x,

int y)

//邊界判斷函式

void

bfs(

int x,

int y)

;//方便未來迴圈使用

int y[4]

=;q.

push

(node)

; inq[x]

[y]=

true

;while

(!q.empty)}}

}int

main()

}int ans =0;

//1塊初始化為0

for(

int x =

0; x < n;x++)}

}printf

("%d"

, ans)

;return0;

}

可以看到bfs每次遍歷值為1的點的周圍四個點,找到為1的點再以該點為中心重新遍歷周圍四個點,迴圈往復

這一題也可以使用dfs的演算法來解,留待以後再寫吧。

.

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

. . . . . 

. * . * .

. * s * .

. * * * .

. . . t *

在這個樣例中,s的座標為(2,2),t的座標為(4,3)。

和上一例類似,需要的函式也類似。有哪些邊界條件呢?這個邊界是指不能正常通過的

1.x,y超出範圍

2.遇到障礙物

3.已經碰到過

而bfs的功能還是和之前一樣,只是多了乙個step的特徵值。

#include

#include

#include

using

namespace std;

const in maxn 100

;struct node

s,t,node;

int m, n;

//迷宮矩陣行列數

char matrix[maxn]

[maxn]

;//迷宮矩陣

bool inq[maxn]

[maxn]=;

int x[4]

=;int y[4]

=;bool

judge

(int x,

int y)

//邊界判斷

intbfs

(int x,

int y,

int step)

//其功用就是找到下一層的可以通行的點

for(

int i =

0; i <

4;i++

)//第一件事,遍歷四周的點}}

return0;

}

感覺比dfs好理解啊。。還是太菜了

再強調一點,再bfs中設定的inq(in queue)陣列的含義是判斷節點是否已入過隊,而不是節點是否已被訪問。區別在於:

如果設定成是否已被訪問,有可能在某個節點正在佇列中(但還未訪問時)由於其他節點可以到達它而將這個節點再次入隊,導致很多節點反覆入隊,計算量大大增加。因此bfs中讓每個節點只入隊一次,故需要設定inq陣列的含義為:節點是否已入過隊而非節點是否已被訪問。

最後指出,當使用stl的queue時,元素入隊的push操作只是製造了該元素的乙個副本入隊,因此在入隊後對原元素的修改不會影響佇列中的副本,而對佇列在副本的修改也不會改變原元素,需要注意由此可能引入的bug(一般由結構體產生)。

演算法 廣度優先搜尋 BFS

廣度優先搜尋主要解決兩類問題 1 從a節點出發,有到b節點的路徑麼?2 從a節點出發,到b節點的最短路徑是什麼?演算法複雜度為o v e 其中v為頂點,e為邊數。例 假設你要在朋友中找乙個芒果銷售商,如果朋友中沒有,則找朋友的朋友,即人際關係網。實現的是第一類問題,在你的人際關係王忠,能找到芒果銷售...

演算法筆記 8 2 廣度優先搜尋BFS

三 相關例題 這次我們改變尋路策略,不知要找出路線,而且想知道從起點到終點的最短步數是多少 兩個相鄰節點間看作相隔一步 我們可以按如下的圖示進行寬度優先搜尋 起點a是第一層,發現從a出發能訪問到b和c,於是b c是第二層 按順序訪問第二層,先看b。從b出發能訪問到d和e,於是d e是第三層,等第二層...

BFS廣度優先搜尋

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