【廣度優先搜索BFS】廣度優先搜索基本思想

搜索是常見的解決問題的方法,常見的搜索方式有深度優先搜搜和廣度優先搜索,一般來說都是搜索只不過方式略有不同,所以我之前在學習搜索的時候一直都是練習的深度優先搜索,也很少有哪些問題就必須用深度優先或者廣度優先,否則就解不出來的,基本上會一種我感覺也差不多,但是呢,有的問題他還是最好用相應的解法效率更高一些,所以就來補補廣度優先搜索。

【廣度優先搜索(BFS)】

廣度優先搜索BFS(Breadth First Search)也稱爲寬度優先搜索,它是一種先生成的結點先擴展的策略。
BFS的思想有點像樹的遍歷當中的層序遍歷,一層一層的搜索,搜索完一層後再搜下一層,直到最後得到想要的結果。

在廣度優先搜索算法中,解答樹上結點的擴展是按它們在樹中的層次進行的。首先生成第一層結點,同時檢查目標結點是否在所生成的結點中,如果不在,則將所有的第一層結點逐一擴展,得到第二層結點,並檢查第二層結點是否包含目標結點,……,對層次爲n+1的任一結點進行擴展之前,必須先考慮層次完層次爲n的結點的每種可能的狀態。因此,對於同一層結點來說,求解問題的價值是相同的,可以按任意順序來擴展它們。通常採用的原則是先生成的結點先擴展。
參考

【什麼時候用BFS比較好?】

簡單點來說是廣度優先搜索適用於只需要求出最優解的問題。至於爲什麼呢?
我覺得深度優先搜索特別適用於統計路徑的條數,比如說走迷宮的問題,一共有多少條路徑能夠到達出口這種問題,很適合用dfs來解決,如果要找最佳路徑,也只能找出所有的路徑之後來比較得出最優解。
那麼如果是用BFS呢?

【BFS的實現】

首先要一個表來存儲所有的節點,因爲BFS是先生成的節點先擴展,類似於數據結構中的隊列(先進先出),所以一般是用一個數組模擬隊列的結構,front和rear分別表示頭和尾指針,初始狀態是rear=front,rear++表示入隊,front++表示出隊。

廣度優先搜索算法的搜索步驟一般是:
(1)從隊列頭取出一個結點,檢查它按照擴展規則是否能夠擴展,如果能則產生一個新結點。
(2)檢查新生成的結點,看它是否已在隊列中存在,如果新結點已經在隊列中出現過,就放棄這個結點,然後回到第(1)步。否則,如果新結點未曾在隊列中出現過,則將它加入到隊列尾。
(3)檢查新結點是否目標結點。如果新結點是目標結點,則搜索成功,程序結束;若新結點不是目標結點,則回到第(1)步,再從隊列頭取出結點進行擴展。

廣度優先搜索中問題不同具體的策略是不同的但是,答題的框架的類似的,但看下面這個實在是看不太懂,做幾道題來深入理解一下就好了。

void BFS(){
    隊列初始化;
    初始結點入隊;
    while (隊列非空) {  
          隊頭元素出隊,賦給current;
          while  (current 還可以擴展){
              由結點current擴展出新結點newifnew 重複於已有的結點狀態) continue;
              new結點入隊;
              if  (new結點是目標狀態){
                    置flag= true;    
                    break; 
               }
          }
      }
}

例題:參考上一篇

馬的遍歷

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章