廣度優先搜尋
(bfs)
的原理和應用
二叉樹中的層序遍歷就屬於一種
bfs(board first search)
層序遍歷會得到
abcdefg
的層序優先序列
(bfs序列)
。在層序遍歷過程中,可以注意到先訪問的節點的孩子節點必然先被訪問
(如訪問了a後訪問b和c,那麼b的孩子結點一定在c的孩子結點前被訪問――僅針對下一層的孩子而言
)。據這個特性,可以用佇列來實現這個遍歷。
void layer(bitree *p)
}bfs
比它更進一步,可以針對圖的結構進行
bfs遍歷
bfs(
從v1開始
)路徑是
廣搜的一般結構如下:
定義乙個佇列
;起始點入隊;
while(
佇列不空
)若迴圈中找到目標
,輸出結果
;否則輸出無解
;它的主要特點是:
n每次隊頭元素出隊時,擴充套件其全部的子結點,並用佇列記錄下來。
n搜尋過程沒有回溯,是一種犧牲空間換取時間的方法。
來看個bfs
的經典例子吧
knight moves zoj(1091)
!題目:西洋棋棋盤上有個馬,要跳到指定座標,求最少的跳的步數!
輸入:a1 h8
輸出:to get from a1 to h8 takes 6 knight moves.
先來看看跳馬的規則,馬只能往自己在的座標的
2*3或
3*2範圍內跳動!
例如:要從a1到
e4:
第1次所有能跳到的點
第2次所有能跳到的點
第3次所有能跳到的點
當第3次時達到了
e4,說明已經達到目的。
以下是我完全可執行的源程式:
#include
#include
#include
using namespace std;
int dir[8][2]=
,,,,,,,
}; //八個可能方向
int flag[8][8]; //標記棋盤中乙個點是否已經被踏過
struct node;
int main()}}
cout<
寬度優先搜尋演算法(又稱廣度優先搜尋)是最簡便的圖的搜尋演算法之一,這一演算法也是很多重要的圖的演算法的原型。dijkstra單源最短路徑演算法和prim最小生成樹演算法都採用了和寬度優先搜尋類似的思想。
已知圖g=(v,e)和乙個源頂點s,寬度優先搜尋以一種系統的方式探尋g的邊,從而「發現」s所能到達的所有頂點,並計算s到所有這些頂點的距離(最少邊數),該演算法同時能生成一棵根為s且包括所有可達頂點的寬度優先樹。對從s可達的任意頂點v,寬度優先樹中從s到v的路徑對應於圖g中從s到v的最短路徑,即包含最小邊數的路徑。該演算法對有向圖和無向圖同樣適用。
之所以稱之為寬度優先演算法,是因為演算法自始至終一直通過已找到和末找到頂點之間的邊界向外擴充套件,就是說,演算法首先搜尋和s距離為k的所有頂點,然後再去搜尋和s距離為k+l的其他頂點。
為了保持搜尋的軌跡,寬度優先搜尋為每個頂點著色:白色、灰色或黑色。演算法開始前所有頂點都是白色,隨著搜尋的進行,各頂點會逐漸變成灰色,然後成為黑色。在搜尋中第一次碰到一頂點時,我們說該頂點被發現,此時該頂點變為非白色頂點。因此,灰色和黑色頂點都已被發現,但是,寬度優先搜尋演算法對它們加以區分以保證搜尋以寬度優先的方式執行。若(u,v)∈e且頂點u為黑色,那麼頂點v要麼是灰色,要麼是黑色,就是說,所有和黑色頂點鄰接的頂點都已被發現。灰色頂點可以與一些白色頂點相鄰接,它們代表著已找到和未找到頂點之間的邊界。
在寬度優先搜尋過程中建立了一棵寬度優先樹,起始時只包含根節點,即源頂點s.在掃瞄已發現頂點u的鄰接表的過程中每發現乙個白色頂點v,該頂點v及邊(u,v)就被新增到樹中。在寬度優先樹中,我們稱結點u是結點v的先輩或父母結點。因為乙個結點至多只能被發現一次,因此它最多只能有--個父母結點。相對根結點來說祖先和後裔關係的定義和通常一樣:如果u處於樹中從根s到結點v的路徑中,那麼u稱為v的祖先,v是u的後裔。
下面的寬度優先搜尋過程bfs假定輸入圖g=(v,e)採用鄰接表表示,對於圖中的每個頂點還採用了幾種附加的資料結構,對每個頂點u∈v,其色彩儲存於變數color[u]中,結點u的父母存於變數π[u]中。如果u沒有父母(例如u=s或u還沒有被檢索到),則 π[u]=nil,由演算法算出的源點s和頂點u之間的距離存於變數d[u]中,演算法中使用了乙個先進先出佇列q來存放灰色節點集合。其中head[q]表示佇列q的隊頭元素,enqueue(q,v)表示將元素v入隊, dequeue(q)表示對頭元素出隊;adj[u]表示圖中和u相鄰的節點集合。
procedure bfs(g,s);
begin
1. for 每個節點u∈v[g]- do
begin
2. color[u]←white;
3. d[u]←∞;
4. π[u]←nil;
end;
5. color[s]←gray;
6. d[s]←0;
7. π[s]←nil;
8. q←
9. while q≠φ do
begin
10. u←head[q];
11. for 每個節點v∈adj[u] do
12. if color[v]=white then
begin
13. color[v]←gray;
14. d[v]←d[v]+1;
15. π[v]←u;
16. enqueue(q,v);
end;
17. dequeue(q);
18. color[u]←black;
end;
end;
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節點出發,搜尋周圍所有的圍繞節...