寬度優先搜尋(bfs)也是搜尋的手段之一。它與深度優先搜尋類似,從某個狀態出發搜尋所有可達的狀態。
與dfs不同的是搜尋的順序,寬度優先搜尋總是先搜尋離初始狀態近的狀態。也就是說,它是按照開始狀態--->只需1次轉移就可以到達的所有狀態--->只需2次轉移就可以到達的所有狀態--->......,以這樣的順序開始搜尋,對於同乙個狀態,寬度優先搜尋只經過一次,因此時間複雜度:o(狀態數 * 轉移的方式)。
深度優先搜尋隱式利用了棧進行計算(遞迴的基礎便是棧),而寬度優先搜尋則利用了佇列。搜尋時首先將初始狀態新增到佇列裡,此後從佇列的最前端不斷取出狀態,把從該狀態可以轉移到的狀態中尚未訪問過的部分加入佇列,如此往復知道隊列為空或找到問題的解。
佇列的特性為先進先出,那麼我們就可以知道所有的狀態都是按照初始狀態由近及遠的順序被遍歷的。
迷宮問題:
給定乙個大小為n×m的迷宮。迷宮由通道和牆壁組成,每一步可以向鄰接的上下左右四格
的通道移動。請求出從起點到終點所需的最小步數。請注意,本題假定從起點一定可以移動
到終點。
輸入n=10, m=10(迷宮如下圖所示。'#','.','s','g'分別表示牆壁、通道、起點和終點)
#s######.#
......#..#
.#.##.##.#
.#........
##.##.####
....#....#
.#######.#
....#.....
.####.###.
....#...g#
輸出22
分析:起點狀態其實就對應初始狀態,起點可走周圍四個方向(過程中需對是否越界,是否撞牆做出判斷,不滿足條件都為不可到達的狀態),一旦遍歷的點為終點這時經歷的路徑必為最短,因為寬度優先搜尋是由近到遠的,所以第乙個來到終點的路徑必為最短。過程中用二維陣列d將到達每個點的最短路徑儲存下來。
由於要向四個方向移動,用dx和dy兩個陣列來表示四個方向向量。
#include#include#include
using
namespace
std;
#define inf 0x3f3f3f3ftypedef pair
p;const
int max = 100
;char maze[max][max+1
];int
m,n;
int sx,sy;//
起點座標
int gx,gy;//
終點座標
int dx[4]=,dy[4]=;
int d[max][max+1
];int
bfs()
if(maze[i][j]=='g'
) }
} memset(d,inf,
sizeof
(d));
//將初始狀態(起點)加入佇列
que.push(p(sx,sy));
d[sx][sy]=0
;
while
(que.size())
for(int i=0;i<4;i++)}}
return
d[gx][gy];
}int
main()
cout
//coutcout}
寬度優先搜尋BFS
寬度優先搜尋 bfs,breadth first search 也是搜尋的手段之一。它與深度優先搜尋類似,從某個狀態出發探索所有可以到達的狀態。與深度優先搜尋的不同之處在於搜尋的順序,寬度優先搜尋總是先搜尋距離初始狀態近的狀態。也就是說,它是按照開始狀態 只需1次轉移就可以到達的所有狀態 只需2次轉...
寬度優先搜尋(BFS)
bfs,其英文全稱是breadth first search。0 1 4 2 3思路 從圖中某個節點出發,將該結點入隊,標記為已訪問。然後輸出佇列的隊首 第一次為起點 將隊首從佇列中刪除,訪問該結點的鄰接表,將未標記的相鄰結點入隊,並且標記為已訪問。接下來迴圈操作第二句話。按照上邊的圖,假設出發點為...
寬度優先搜尋bfs
好吧,今天看了bfs,其實發現基本思想也是不過如此。只是,應用還是不太會。bfs是寬度優先,從根節點開始,依次訪問它的所有鄰接點,然後再按順序訪問鄰接點的鄰接點,先被訪問的點的鄰接點先被訪問。由於要按這樣的順序訪問,所以需要用到佇列。求最短路徑和迷宮型別的題目都可以利用bfs.下面是基本步驟 1 從...